flatcontainer/impls/
option.rs1#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use crate::{IntoOwned, Push, Region, RegionPreference, ReserveItems};
7
8impl<T: RegionPreference> RegionPreference for Option<T> {
9 type Owned = Option<T::Owned>;
10 type Region = OptionRegion<T::Region>;
11}
12
13#[derive(Default, Debug)]
30#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31pub struct OptionRegion<R> {
32 inner: R,
33}
34
35impl<R: Clone> Clone for OptionRegion<R> {
36 fn clone(&self) -> Self {
37 Self {
38 inner: self.inner.clone(),
39 }
40 }
41
42 fn clone_from(&mut self, source: &Self) {
43 self.inner.clone_from(&source.inner);
44 }
45}
46
47impl<R: Region> Region for OptionRegion<R> {
48 type Owned = Option<R::Owned>;
49 type ReadItem<'a> = Option<<R as Region>::ReadItem<'a>> where Self: 'a;
50 type Index = Option<R::Index>;
51
52 #[inline]
53 fn merge_regions<'a>(regions: impl Iterator<Item = &'a Self> + Clone) -> Self
54 where
55 Self: 'a,
56 {
57 Self {
58 inner: R::merge_regions(regions.map(|r| &r.inner)),
59 }
60 }
61
62 #[inline]
63 fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
64 index.map(|t| self.inner.index(t))
65 }
66
67 #[inline]
68 fn reserve_regions<'a, I>(&mut self, regions: I)
69 where
70 Self: 'a,
71 I: Iterator<Item = &'a Self> + Clone,
72 {
73 self.inner.reserve_regions(regions.map(|r| &r.inner));
74 }
75
76 #[inline]
77 fn clear(&mut self) {
78 self.inner.clear();
79 }
80
81 #[inline]
82 fn heap_size<F: FnMut(usize, usize)>(&self, callback: F) {
83 self.inner.heap_size(callback);
84 }
85
86 #[inline]
87 fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b>
88 where
89 Self: 'a,
90 {
91 item.map(R::reborrow)
92 }
93}
94
95impl<'a, T> IntoOwned<'a> for Option<T>
96where
97 T: IntoOwned<'a>,
98{
99 type Owned = Option<T::Owned>;
100
101 #[inline]
102 fn into_owned(self) -> Self::Owned {
103 self.map(IntoOwned::into_owned)
104 }
105
106 #[inline]
107 fn clone_onto(self, other: &mut Self::Owned) {
108 match (self, other) {
109 (Some(item), Some(target)) => T::clone_onto(item, target),
110 (Some(item), target) => *target = Some(T::into_owned(item)),
111 (None, target) => *target = None,
112 }
113 }
114
115 #[inline]
116 fn borrow_as(owned: &'a Self::Owned) -> Self {
117 owned.as_ref().map(T::borrow_as)
118 }
119}
120
121impl<T, TR> Push<Option<T>> for OptionRegion<TR>
122where
123 TR: Region + Push<T>,
124{
125 #[inline]
126 fn push(&mut self, item: Option<T>) -> <OptionRegion<TR> as Region>::Index {
127 item.map(|t| self.inner.push(t))
128 }
129}
130
131impl<'a, T: 'a, TR> Push<&'a Option<T>> for OptionRegion<TR>
132where
133 TR: Region + Push<&'a T>,
134{
135 #[inline]
136 fn push(&mut self, item: &'a Option<T>) -> <OptionRegion<TR> as Region>::Index {
137 item.as_ref().map(|t| self.inner.push(t))
138 }
139}
140
141impl<T, TR> ReserveItems<Option<T>> for OptionRegion<TR>
142where
143 TR: Region + ReserveItems<T>,
144{
145 #[inline]
146 fn reserve_items<I>(&mut self, items: I)
147 where
148 I: Iterator<Item = Option<T>> + Clone,
149 {
150 #[allow(clippy::filter_map_identity)]
153 self.inner.reserve_items(items.filter_map(|r| r));
154 }
155}
156
157impl<'a, T: 'a, TR> ReserveItems<&'a Option<T>> for OptionRegion<TR>
158where
159 TR: Region + ReserveItems<&'a T>,
160{
161 #[inline]
162 fn reserve_items<I>(&mut self, items: I)
163 where
164 I: Iterator<Item = &'a Option<T>> + Clone,
165 {
166 self.inner.reserve_items(items.filter_map(|r| r.as_ref()));
167 }
168}
169
170#[cfg(test)]
171mod tests {
172 use crate::{MirrorRegion, OwnedRegion, Region, ReserveItems};
173
174 use super::*;
175
176 #[test]
177 fn test_reserve() {
178 let mut r = <OptionRegion<MirrorRegion<u8>>>::default();
179 ReserveItems::reserve_items(&mut r, [Some(0), None].iter());
180
181 ReserveItems::reserve_items(&mut r, [Some(0), None].into_iter());
182 }
183
184 #[test]
185 fn test_heap_size() {
186 let mut r = <OptionRegion<OwnedRegion<u8>>>::default();
187 ReserveItems::reserve_items(&mut r, [Some([1; 1]), None].iter());
188 let mut cap = 0;
189 r.heap_size(|_, ca| {
190 cap += ca;
191 });
192 assert!(cap > 0);
193 }
194}