efficient_enum/
option.rs

1use std::fmt;
2use std::hash::{Hash, Hasher};
3use std::mem::{replace,uninitialized};
4use std::ptr::{read,write};
5
6use tag::{One,Two};
7use tag::{TaggableValue,TagMSB,TagWrapper};
8use utils;
9
10
11/// An option type similar to `Option<(A, B)>`, but where no extra data is used. Instead, some of
12/// the space in `A` is used to "tag the union".
13///
14/// The one true downside is that it is impossible to get `&A` from `&EfficientOption`. The reason
15/// for this is that doing so would expose the private tag info.
16pub struct EfficientOption<A, B=(), TM=TagMSB>(TagWrapper<A, TM>, B)
17where A: TaggableValue<TM, One>;
18
19impl<TM, A: Clone, B: Clone> Clone for EfficientOption<A, B, TM>
20where A: TaggableValue<TM, One> {
21    fn clone(&self) -> Self {
22        EfficientOption(self.0.clone(), self.1.clone())
23    }
24
25    fn clone_from(&mut self, source: &Self) {
26        if source.is_some() {
27            if self.is_some() {
28                self.1.clone_from(&source.1);
29            } else {
30                let b = source.1.clone();
31                unsafe { write(&mut self.1 as *mut B, b); }
32            }
33            self.0.clone_from(&source.0);
34        } else {
35            unsafe { utils::change_tag(&mut self.0, One::Tagged); }
36        }
37    }
38}
39impl<TM, A: Copy, B: Copy> Copy for EfficientOption<A, B, TM>
40where A: TaggableValue<TM, One> {}
41
42impl<TM, A, B> Default for EfficientOption<A, B, TM>
43where A: TaggableValue<TM, One> {
44    fn default() -> Self {
45        EfficientOption::none()
46    }
47}
48
49impl<TM, A: fmt::Debug, B: fmt::Debug> fmt::Debug for EfficientOption<A, B, TM>
50where A: TaggableValue<TM, One> {
51    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52        if self.is_none() {
53            write!(f, "EfficientNone")
54        } else {
55            write!(f, "EfficientSome(")?;
56            utils::fmt_untagged(&self.0, f)?;
57            write!(f, ", {:?})", self.1)
58        }
59    }
60}
61
62impl<TM, A: PartialEq, B: PartialEq> PartialEq for EfficientOption<A, B, TM>
63where A: TaggableValue<TM, One> {
64    fn eq(&self, other: &Self) -> bool {
65        match (self.is_some(), other.is_some()) {
66            (true, true) => utils::eq(&self.0, &other.0) && self.1 == other.1,
67            (false, false) => true,
68            _ => false,
69        }
70    }
71
72    fn ne(&self, other: &Self) -> bool {
73        match (self.is_some(), other.is_some()) {
74            (true, true) => utils::ne(&self.0, &other.0) || self.1 != other.1,
75            (false, false) => false,
76            _ => true,
77        }
78    }
79}
80impl<TM, A: Eq, B: Eq> Eq for EfficientOption<A, B, TM>
81where A: TaggableValue<TM, One> {}
82
83impl<TM, A: Hash, B: Hash> Hash for EfficientOption<A, B, TM>
84where A: TaggableValue<TM, One> {
85    fn hash<H: Hasher>(&self, state: &mut H) {
86        if self.is_some() {
87            self.0.hash(state);
88            self.1.hash(state);
89        }
90    }
91}
92
93impl<TM, A> From<Option<A>> for EfficientOption<A, (), TM>
94where A: TaggableValue<TM, One> {
95    fn from(a: Option<A>) -> Self {
96        Self::new_0(a)
97    }
98}
99
100impl<TM, A, B> From<Option<(A, B)>> for EfficientOption<A, B, TM>
101where A: TaggableValue<TM, One> {
102    fn from(a: Option<(A, B)>) -> Self {
103        Self::new(a)
104    }
105}
106
107impl<TM, A, B> Into<Option<(A, B)>> for EfficientOption<A, B, TM>
108where A: TaggableValue<TM, One> {
109    fn into(self) -> Option<(A, B)> { self.destructure() }
110}
111
112impl<TM, A> Into<Option<A>> for EfficientOption<A, (), TM>
113where A: TaggableValue<TM, One> {
114    fn into(self) -> Option<A> { self.destructure().map(|(a, _)| a) }
115}
116
117impl<TM, A, B> EfficientOption<A, B, TM>
118where A: TaggableValue<TM, One> {
119    /// Constructs a new `EfficientOption`
120    #[inline]
121    pub fn new(a: Option<(A, B)>) -> Self {
122        a.map_or_else(Self::none, Self::some)
123    }
124
125    /// Constructs a new `EfficientOption`
126    #[inline]
127    pub fn new_0(a: Option<A>) -> Self
128    where B: Default {
129        a.map_or_else(Self::none, Self::some_0)
130    }
131
132    /// Constructs a new `EfficientOption`
133    #[inline]
134    pub fn new_1(b: Option<B>) -> Self
135    where A: Default {
136        b.map_or_else(Self::none, Self::some_1)
137    }
138
139    /// Constructs an empty `EfficientOption`
140    #[inline]
141    pub fn none() -> Self {
142        let a = unsafe { utils::uninitialized_from_tag(One::Tagged) };
143        let b = unsafe { uninitialized() };
144        EfficientOption(a, b)
145    }
146
147    /// Constructs an `EfficientOption` from an `A` value
148    #[inline]
149    pub fn some((a, b): (A, B)) -> Self {
150        let a = utils::tag(a, One::Untagged);
151        EfficientOption(a, b)
152    }
153
154    /// Constructs an `EfficientOption` from an `A` value
155    #[inline]
156    pub fn some_0(a: A) -> Self
157    where B: Default {
158        Self::some((a, Default::default()))
159    }
160
161    /// Constructs an `EfficientOption` from an `B` value
162    #[inline]
163    pub fn some_1(b: B) -> Self
164    where A: Default {
165        Self::some((Default::default(), b))
166    }
167
168    /// Clones the `A` value if one exists
169    pub fn clone_0(&self) -> Option<A>
170    where A: Clone {
171        self.ref_0().map(Clone::clone)
172    }
173
174    /// Clones the `B` value if one exists
175    pub fn clone_1(&self) -> Option<B>
176    where B: Clone {
177        self.ref_1().map(Clone::clone)
178    }
179
180    /// Gets references to both the `A` and `B` values if they exist
181    pub fn as_ref(&self) -> Option<(&A, &B)> {
182        if self.is_none() { None }
183        else { Some((&(self.0).1, &self.1)) }
184    }
185
186    /// Gets a reference to the `A` value if one exists
187    pub fn ref_0(&self) -> Option<&A> {
188        if self.is_none() { None }
189        else { Some(&(self.0).1) }
190    }
191
192    /// Gets a reference to the `B` value if one exists
193    pub fn ref_1(&self) -> Option<&B> {
194        if self.is_none() { None }
195        else { Some(&self.1) }
196    }
197
198    /// Gets references to both the `A` and `B` values by assuming they exist
199    pub unsafe fn unwrap_ref(&self) -> (&A, &B) {
200        debug_assert!(self.is_some());
201        (&(self.0).1, &self.1)
202    }
203
204    /// Gets a reference to the `A` value by assuming one exists
205    pub unsafe fn unwrap_ref_0(&self) -> &A {
206        debug_assert!(self.is_some());
207        &(self.0).1
208    }
209
210    /// Gets a reference to the `A` value by assuming one exists
211    pub unsafe fn unwrap_ref_1(&self) -> &B {
212        debug_assert!(self.is_some());
213        &self.1
214    }
215
216    /// Gets a reference to the `A` value and a mutable reference to the `B` value if they exist
217    pub fn as_mut(&mut self) -> Option<(&A, &mut B)> {
218        if self.is_none() { None }
219        else { Some((&(self.0).1, &mut self.1)) }
220    }
221
222    /// Gets mutable a reference to the `B` value if one exists
223    pub fn mut_1(&mut self) -> Option<&mut B> {
224        if self.is_none() { None }
225        else { Some(&mut self.1) }
226    }
227
228    /// Gets a reference to the `A` value and a mutable reference to the `B` value by assuming they exist
229    pub unsafe fn unwrap_as_mut(&mut self) -> (&A, &mut B) {
230        debug_assert!(self.is_some());
231        (&(self.0).1, &mut self.1)
232    }
233
234    /// Gets mutable a reference to the `B` value by assuming one exists
235    pub unsafe fn unwrap_mut_1(&mut self) -> &mut B {
236        debug_assert!(self.is_some());
237        &mut self.1
238    }
239
240    /// Returns an `EfficientOptionInnerSome` if the option is a `Some` value, returns an
241    /// `EfficientOptionInnerNone` otherwise.
242    #[inline]
243    pub fn inner(&mut self) -> EfficientOptionInner<A, B, TM> {
244        use self::EfficientOptionInner::{IsNone, IsSome};
245        if self.is_none() {
246            IsNone(EfficientOptionInnerNone(self))
247        } else {
248            IsSome(EfficientOptionInnerSome(self))
249        }
250    }
251
252    /// Returns an `EfficientOptionInnerSome`.
253    #[inline]
254    pub unsafe fn inner_some(&mut self) -> EfficientOptionInnerSome<A, B, TM> {
255        debug_assert!(self.is_some());
256        EfficientOptionInnerSome(self)
257    }
258
259    /// Returns an `EfficientOptionInnerSome`.
260    #[inline]
261    pub unsafe fn inner_none(&mut self) -> EfficientOptionInnerNone<A, B, TM> {
262        debug_assert!(self.is_none());
263        EfficientOptionInnerNone(self)
264    }
265
266    /// Destructures an `EfficientOption`
267    #[inline]
268    pub fn destructure(self) -> Option<(A, B)> {
269        if self.is_none() { None }
270        else { Some((utils::untag(self.0), self.1)) }
271    }
272
273    /// Destructures an `EfficientOption` into the `A` value if one exists
274    #[inline]
275    pub fn destructure_0(self) -> Option<A> {
276        if self.is_none() { None } else { Some(utils::untag(self.0)) }
277    }
278
279    /// Destructures an `EfficientOption` into the `B` value if one exists
280    #[inline]
281    pub fn destructure_1(self) -> Option<B> {
282        if self.is_none() { None } else { Some(self.1) }
283    }
284
285    /// Destructures an `EfficientOption`
286    #[inline]
287    pub unsafe fn unwrap_destructure(self) -> (A, B) {
288        debug_assert!(self.is_some());
289        (utils::untag(self.0), self.1)
290    }
291
292    /// Destructures an `EfficientOption` into the `A` value by assuming one exists
293    #[inline]
294    pub unsafe fn unwrap_destructure_0(self) -> A {
295        debug_assert!(self.is_some());
296        utils::untag(self.0)
297    }
298
299    /// Destructures an `EfficientOption` into the `B` value by assuming one exists
300    #[inline]
301    pub unsafe fn unwrap_destructure_1(self) -> B {
302        debug_assert!(self.is_some());
303        self.1
304    }
305
306    /// Takes the value out of the option, leaving a None in its place.
307    pub fn take(&mut self) -> Option<(A, B)> {
308        if self.is_none() { None } else {
309            let (a, b) = unsafe {
310                let a = read(&self.0 as *const TagWrapper<A, TM>);
311                utils::change_tag(&mut self.0, One::Tagged);
312                let b = read(&self.1 as *const B);
313                (a, b)
314            };
315
316            Some((utils::untag(a), b))
317        }
318    }
319
320    /// Takes both values out of the option, leaving a None in its place.
321    /// The version only returns the `A` value
322    pub fn take_0(&mut self) -> Option<A> {
323        if self.is_none() { None } else {
324            let a = unsafe {
325                let a = read(&self.0 as *const TagWrapper<A, TM>);
326                utils::change_tag(&mut self.0, One::Tagged);
327                a
328            };
329
330            Some(utils::untag(a))
331        }
332    }
333
334    /// Takes both values out of the option, leaving a None in its place.
335    /// The version only returns the `B` value
336    pub fn take_1(&mut self) -> Option<B> {
337        if self.is_none() { None } else {
338            let b = unsafe {
339                utils::change_tag(&mut self.0, One::Tagged);
340                read(&self.1 as *const B)
341            };
342
343            Some(b)
344        }
345    }
346
347    /// Returns `true` if the option is a `Some` value.
348    #[inline]
349    pub fn is_some(&self) -> bool { utils::get_tag(&self.0) == One::Untagged }
350
351    /// Returns `true` if the option is a `None` value.
352    #[inline]
353    pub fn is_none(&self) -> bool { !self.is_some() }
354
355    /// Maps the value to a result
356    #[inline]
357    pub fn map<R, F>(&mut self, f: F) -> R
358    where F: FnOnce(Option<(&mut A, &mut B)>) -> R {
359        let b = &mut self.1;
360        utils::borrow_untagged(&mut self.0, |tag, a|
361            match tag {
362                One::Tagged => f(None),
363                One::Untagged => f(Some((a, b))),
364            }
365        )
366    }
367}
368
369/// A helper type for `EfficientOption`, useful for adding data to `is_none` options.
370pub struct EfficientOptionInnerNone<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOption<A, B, TM>)
371where A: TaggableValue<TM, One>;
372
373/// A helper type for `EfficientOption`, useful for accessing 'is_some' data and removing it.
374pub struct EfficientOptionInnerSome<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOption<A, B, TM>)
375where A: TaggableValue<TM, One>;
376
377/// A helper type for `EfficientOption`, gives access to `EfficientOptionInnerNone` and
378/// `EfficientOptionInnerSome` variants.
379pub enum EfficientOptionInner<'a, A: 'a, B: 'a, TM: 'a = TagMSB>
380where A: TaggableValue<TM, One> {
381    IsNone(EfficientOptionInnerNone<'a, A, B, TM>),
382    IsSome(EfficientOptionInnerSome<'a, A, B, TM>),
383}
384
385impl<'a, TM, A, B> EfficientOptionInnerNone<'a, A, B, TM>
386where A: TaggableValue<TM, One> {
387    /// Adds a value
388    pub fn give(self, (a, b): (A, B)) -> EfficientOptionInnerSome<'a, A, B, TM> {
389        debug_assert!(self.0.is_none());
390        let a = utils::tag(a, One::Untagged);
391        unsafe {
392            write(&mut (self.0).0 as *mut TagWrapper<A, TM>, a);
393            write(&mut (self.0).1 as *mut B, b);
394        }
395        EfficientOptionInnerSome(self.0)
396    }
397}
398
399impl<'a, TM, A, B> EfficientOptionInnerSome<'a, A, B, TM>
400where A: TaggableValue<TM, One> {
401    /// Clones the `A` value
402    pub fn clone_0(&self) -> A
403    where A: Clone {
404        debug_assert!(self.0.is_some());
405        utils::untag((self.0).0.clone())
406    }
407
408    /// Clones the `B` value
409    pub fn clone_1(&self) -> B
410    where B: Clone {
411        debug_assert!(self.0.is_some());
412        self.ref_1().clone()
413    }
414
415    /// Gets a reference to the `A` value
416    pub fn ref_0(&self) -> &A {
417        debug_assert!(self.0.is_some());
418        &((self.0).0).1
419    }
420
421    /// Gets a reference to the `B` value
422    pub fn ref_1(&self) -> &B {
423        debug_assert!(self.0.is_some());
424        &(self.0).1
425    }
426
427    /// Gets a reference to both the `A` and `B` values
428    pub fn as_ref(&self) -> (&A, &B) {
429        debug_assert!(self.0.is_some());
430        (&((self.0).0).1, &(self.0).1)
431    }
432
433    /// Gets mutable a reference to the `B` value
434    pub fn mut_1(&mut self) -> &mut B {
435        debug_assert!(self.0.is_some());
436        &mut (self.0).1
437    }
438
439    /// Gets a reference to the `A` value and a mutable reference to the `B` value
440    pub fn as_mut(&mut self) -> (&A, &mut B) {
441        debug_assert!(self.0.is_some());
442        (&((self.0).0).1, &mut (self.0).1)
443    }
444
445    /// Destructures an `EfficientOptionInnerSome` into a reference to the `A` value
446    pub fn destructure_0(self) -> &'a A {
447        debug_assert!(self.0.is_some());
448        &((self.0).0).1
449    }
450
451    /// Destructures an `EfficientOptionInnerSome` into a mutable reference to the `B` value
452    pub fn destructure_1(self) -> &'a mut B {
453        debug_assert!(self.0.is_some());
454        &mut (self.0).1
455    }
456
457    /// Destructures an `EfficientOptionInnerSome`
458    pub fn destructure(self) -> (&'a A, &'a mut B) {
459        debug_assert!(self.0.is_some());
460        (&((self.0).0).1, &mut (self.0).1)
461    }
462
463    /// Replaces the `A` value
464    pub fn replace_0(&mut self, a: A) -> A {
465        let a = utils::tag(a, One::Untagged);
466        utils::untag(replace(&mut (self.0).0, a))
467    }
468
469    /// Replaces the `B` value
470    pub fn replace_1(&mut self, b: B) -> B {
471        replace(self.mut_1(), b)
472    }
473
474    /// Takes both values out of the option, leaving a None in its place.
475    pub fn take(self) -> (EfficientOptionInnerNone<'a, A, B, TM>, (A, B)) {
476        debug_assert!(self.0.is_some());
477        let (a, b) = unsafe {
478           let a = read(&(self.0).0 as *const TagWrapper<A, TM>);
479           utils::change_tag(&mut (self.0).0, One::Tagged);
480           let b = read(&(self.0).1 as *const B);
481           (a, b)
482        };
483        (EfficientOptionInnerNone(self.0), (utils::untag(a), b))
484    }
485
486    /// Takes both values out of the option, leaving a None in its place.
487    /// The version only returns the `A` value
488    pub fn take_0(self) -> (EfficientOptionInnerNone<'a, A, B, TM>, A) {
489        debug_assert!(self.0.is_some());
490        let a = unsafe {
491           let a = read(&(self.0).0 as *const TagWrapper<A, TM>);
492           utils::change_tag(&mut (self.0).0, One::Tagged);
493           a
494        };
495        (EfficientOptionInnerNone(self.0), utils::untag(a))
496    }
497
498    /// Takes both values out of the option, leaving a None in its place.
499    /// The version only returns the `B` value
500    pub fn take_1(self) -> (EfficientOptionInnerNone<'a, A, B, TM>, B) {
501        debug_assert!(self.0.is_some());
502        let b = unsafe {
503           utils::change_tag(&mut (self.0).0, One::Tagged);
504           read(&(self.0).1 as *const B)
505        };
506        (EfficientOptionInnerNone(self.0), b)
507    }
508
509    /// Maps the value to a result
510    pub fn map<R, F: FnOnce(&mut A)-> R>(&mut self, f: F) -> R {
511        debug_assert!(self.0.is_some());
512        utils::borrow_untagged(&mut (self.0).0, |_, a|
513            f(a)
514        )
515    }
516}
517
518impl<'a, TM, A, B> EfficientOptionInner<'a, A, B, TM>
519where A: TaggableValue<TM, One> {
520    /// Unwraps an option, yielding the content of a `IsSome`.
521    ///
522    /// # Panics
523    ///
524    /// Panics if the value is a `IsNone` with a custom panic message provided by
525    /// `msg`.
526    #[inline]
527    pub fn expect_some(self, msg: &str) -> EfficientOptionInnerSome<'a, A, B, TM> {
528        use self::EfficientOptionInner::{IsNone,IsSome};
529        match self {
530            IsNone(_) => utils::expect_failed(msg),
531            IsSome(x) => x,
532        }
533    }
534
535    /// Unwraps an option, yielding the content of a `IsNone`.
536    ///
537    /// # Panics
538    ///
539    /// Panics if the value is a `IsSome` with a custom panic message provided by
540    /// `msg`.
541    #[inline]
542    pub fn expect_none(self, msg: &str) -> EfficientOptionInnerNone<'a, A, B, TM> {
543        use self::EfficientOptionInner::{IsNone,IsSome};
544        match self {
545            IsNone(x) => x,
546            IsSome(_) => utils::expect_failed(msg),
547        }
548    }
549
550    /// Moves the value `v` out if it is `IsSome(v)`.
551    ///
552    /// In general, because this function may panic, its use is discouraged.
553    /// Instead, prefer to use pattern matching and handle the `IsNone`
554    /// case explicitly.
555    ///
556    /// # Panics
557    ///
558    /// Panics if the self value equals `IsNone`.
559    #[inline]
560    pub fn unwrap_some(self) -> EfficientOptionInnerSome<'a, A, B, TM> {
561        use self::EfficientOptionInner::{IsNone,IsSome};
562        match self {
563            IsNone(_) => panic!("called `EfficientOptionInner::unwrap_some()` on a `IsNone` value"),
564            IsSome(x) => x,
565        }
566    }
567
568    /// Moves the value `v` out if it is `IsNone(v)`.
569    ///
570    /// In general, because this function may panic, its use is discouraged.
571    /// Instead, prefer to use pattern matching and handle the `IsSome`
572    /// case explicitly.
573    ///
574    /// # Panics
575    ///
576    /// Panics if the self value equals `IsSome`.
577    #[inline]
578    pub fn unwrap_none(self) -> EfficientOptionInnerNone<'a, A, B, TM> {
579        use self::EfficientOptionInner::{IsNone,IsSome};
580        match self {
581            IsNone(x) => x,
582            IsSome(_) => panic!("called `EfficientOptionInner::unwrap_none()` on a `IsSome` value"),
583        }
584    }
585
586    /// Returns the contained `IsSome` value or a default.
587    #[inline]
588    pub fn unwrap_some_or(self, default: EfficientOptionInnerSome<'a, A, B, TM>) -> EfficientOptionInnerSome<'a, A, B, TM> {
589        self.map(|_| default, |x| x)
590    }
591
592    /// Returns the contained `IsNone` value or a default.
593    #[inline]
594    pub fn unwrap_none_or(self, default: EfficientOptionInnerNone<'a, A, B, TM>) -> EfficientOptionInnerNone<'a, A, B, TM> {
595        self.map(|x| x, |_| default)
596    }
597
598    /// Returns the contained `IsSome` value or computes it from a closure.
599    #[inline]
600    pub fn unwrap_some_or_else<F>(self, f: F) -> EfficientOptionInnerSome<'a, A, B, TM>
601    where F: FnOnce(EfficientOptionInnerNone<'a, A, B, TM>) -> EfficientOptionInnerSome<'a, A, B, TM> {
602        self.map(f, |x| x)
603    }
604
605    /// Returns the contained `IsNone` value or computes it from a closure.
606    #[inline]
607    pub fn unwrap_none_or_else<F>(self, f: F) -> EfficientOptionInnerNone<'a, A, B, TM>
608    where F: FnOnce(EfficientOptionInnerSome<'a, A, B, TM>) -> EfficientOptionInnerNone<'a, A, B, TM> {
609        self.map(|x| x, f)
610    }
611
612    /// Applies a function to the contained `IsSome` value or returns a `default`.
613    #[inline]
614    pub fn map_some_or<U, F>(self, default: U, f: F) -> U
615    where F: FnOnce(EfficientOptionInnerSome<'a, A, B, TM>) -> U {
616        self.map(|_| default, f)
617    }
618
619    /// Applies a function to the contained `IsNone` value or returns a `default`.
620    #[inline]
621    pub fn map_none_or<U, F>(self, default: U, f: F) -> U
622    where F: FnOnce(EfficientOptionInnerNone<'a, A, B, TM>) -> U {
623        self.map(f, |_| default)
624    }
625
626
627    /// Applies a function to the contained `IsSome` value or computes a `default` from the `IsNone`.
628    #[inline]
629    pub fn map<U, D, F>(self, default: D, f: F) -> U
630    where D: FnOnce(EfficientOptionInnerNone<'a, A, B, TM>) -> U,
631    F: FnOnce(EfficientOptionInnerSome<'a, A, B, TM>) -> U {
632        use self::EfficientOptionInner::{IsNone,IsSome};
633        match self {
634            IsNone(x) => default(x),
635            IsSome(x) => f(x),
636        }
637    }
638}
639
640/// An option type similar to `(A, Option<B>)`, but where no extra data is used. Instead, some of
641/// the space in `A` is used to "tag the union".
642///
643/// The one true downside is that it is impossible to get `&A` from `&EfficientOptionTuple`. The reason
644/// for this is that doing so would expose the private tag info.
645pub struct EfficientOptionTuple<A, B, TM=TagMSB>(TagWrapper<A, TM>, B)
646where A: TaggableValue<TM, Two>;
647
648impl<TM, A: Clone, B: Clone> Clone for EfficientOptionTuple<A, B, TM>
649where A: TaggableValue<TM, Two> {
650    fn clone(&self) -> Self {
651        let b = self.ref_1().map_or(unsafe { uninitialized() }, Clone::clone);
652        EfficientOptionTuple(self.0.clone(), b)
653    }
654
655    fn clone_from(&mut self, source: &Self) {
656        if let Some(b) = source.ref_1() {
657            if self.is_some() {
658                self.1.clone_from(b);
659            } else {
660                let b = b.clone();
661                unsafe { write(&mut self.1 as *mut B, b) }
662            }
663        }
664        self.0.clone_from(&source.0);
665    }
666}
667impl<TM, A: Copy, B: Copy> Copy for EfficientOptionTuple<A, B, TM>
668where A: TaggableValue<TM, Two> {}
669
670impl<TM, A: Default, B> Default for EfficientOptionTuple<A, B, TM>
671where A: TaggableValue<TM, Two> {
672    fn default() -> Self {
673        EfficientOptionTuple::none(Default::default())
674    }
675}
676
677impl<TM, A: fmt::Debug, B: fmt::Debug> fmt::Debug for EfficientOptionTuple<A, B, TM>
678where A: TaggableValue<TM, Two> {
679    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
680        write!(f, "EfficientOptionTuple(")?;
681        TaggableValue::fmt_untagged(&self.0, f)?;
682        if let Some(b) = self.ref_1() {
683            write!(f, ", Some({:?}))", b)
684        } else {
685            write!(f, ", None)")
686        }
687    }
688}
689
690impl<TM, A: PartialEq, B: PartialEq> PartialEq for EfficientOptionTuple<A, B, TM>
691where A: TaggableValue<TM, Two> {
692    fn eq(&self, other: &Self) -> bool {
693        TaggableValue::eq(&self.0, &other.0) && match (self.ref_1(), other.ref_1()) {
694            (Some(s), Some(o)) => *s == *o,
695            (None, None) => true,
696            _ => false,
697        }
698    }
699
700    fn ne(&self, other: &Self) -> bool {
701        TaggableValue::ne(&self.0, &other.0) || match (self.ref_1(), other.ref_1()) {
702            (Some(s), Some(o)) => *s != *o,
703            (None, None) => false,
704            _ => true,
705        }
706    }
707}
708impl<TM, A: Eq, B: Eq> Eq for EfficientOptionTuple<A, B, TM>
709where A: TaggableValue<TM, Two> {}
710
711impl<TM, A: Hash, B: Hash> Hash for EfficientOptionTuple<A, B, TM>
712where A: TaggableValue<TM, Two> {
713    fn hash<H: Hasher>(&self, state: &mut H) {
714        self.0.hash(state);
715        if let Some(b) = self.ref_1() { b.hash(state) }
716    }
717}
718
719impl<TM, A, B> From<(A, Option<B>)> for EfficientOptionTuple<A, B, TM>
720where A: TaggableValue<TM, Two> {
721    fn from((a, b): (A, Option<B>)) -> Self {
722        Self::new(a, b)
723    }
724}
725
726impl<TM, A, B> Into<(A, Option<B>)> for EfficientOptionTuple<A, B, TM>
727where A: TaggableValue<TM, Two> {
728    fn into(self) -> (A, Option<B>) { self.destructure() }
729}
730
731impl<TM, A, B> EfficientOptionTuple<A, B, TM>
732where A: TaggableValue<TM, Two> {
733    /// Constructs a new `EfficientOptionTuple`
734    #[inline]
735    pub fn new(a: A, b: Option<B>) -> Self {
736        if let Some(b) = b { Self::some(a, b) } else { Self::none(a) }
737    }
738
739    /// Constructs an `EfficientOptionTuple` with no `B` value
740    #[inline]
741    pub fn none(a: A) -> Self {
742        let a = utils::tag(a, Two::Option0);
743        let b = unsafe { uninitialized() };
744        EfficientOptionTuple(a, b)
745    }
746
747    /// Constructs an `EfficientOptionTuple` with a `B` value
748    #[inline]
749    pub fn some(a: A, b: B) -> Self {
750        let a = utils::tag(a, Two::Option1);
751        EfficientOptionTuple(a, b)
752    }
753
754    /// Destructures an `EfficientOptionTuple`
755    #[inline]
756    pub fn destructure(self) -> (A, Option<B>) {
757        let b = if self.is_none() { None } else { Some(self.1) };
758        (utils::untag(self.0), b)
759    }
760
761    /// Destructures an `EfficientOptionTuple` into the `A` value
762    #[inline]
763    pub fn destructure_0(self) -> A {
764        utils::untag(self.0)
765    }
766
767    /// Destructures an `EfficientOptionTuple` into the `B` value if one exists
768    #[inline]
769    pub fn destructure_1(self) -> Option<B> {
770        if self.is_none() { None } else { Some(self.1) }
771    }
772
773    /// Destructures an `EfficientOptionTuple` by assuming the `B` values exists
774    #[inline]
775    pub unsafe fn unwrap_destructure(self) -> (A, B) {
776        debug_assert!(self.is_some());
777        (utils::untag(self.0), self.1)
778    }
779
780    /// Destructures an `EfficientOptionTuple`into the `B` value by assuming one exists
781    #[inline]
782    pub unsafe fn unwrap_destructure_1(self) -> B {
783        debug_assert!(self.is_some());
784        self.1
785    }
786
787    /// Takes the `B` value out of the option, leaving a None in its place.
788    pub fn take_1(&mut self) -> Option<B> {
789        if self.is_none() { None }
790        else {
791            let b = unsafe {
792                utils::change_tag(&mut self.0, Two::Option0);
793                read(&self.1 as *const B)
794            };
795
796            Some(b)
797        }
798    }
799
800    /// Returns `true` if the option is a `Some` value.
801    #[inline]
802    pub fn is_some(&self) -> bool { utils::get_tag(&self.0) == Two::Option1 }
803
804    /// Returns `true` if the option is a `None` value.
805    #[inline]
806    pub fn is_none(&self) -> bool { !self.is_some() }
807
808    /// Returns an `EfficientOptionTupleInnerSome` if the option is a `Some` value, returns an
809    /// `EfficientOptionTupleInnerNone` otherwise.
810    #[inline]
811    pub fn inner(&mut self) -> EfficientOptionTupleInner<A, B, TM> {
812        use self::EfficientOptionTupleInner::{IsNone,IsSome};
813        if self.is_none() {
814            IsNone(EfficientOptionTupleInnerNone(self))
815        } else {
816            IsSome(EfficientOptionTupleInnerSome(self))
817        }
818    }
819
820    /// Returns an `EfficientOptionTupleInnerSome`.
821    #[inline]
822    pub unsafe fn inner_some(&mut self) -> EfficientOptionTupleInnerSome<A, B, TM> {
823        debug_assert!(self.is_some());
824        EfficientOptionTupleInnerSome(self)
825    }
826
827    /// Returns an `EfficientOptionTupleInnerSome`.
828    #[inline]
829    pub unsafe fn inner_none(&mut self) -> EfficientOptionTupleInnerNone<A, B, TM> {
830        debug_assert!(self.is_none());
831        EfficientOptionTupleInnerNone(self)
832    }
833
834    /// Clones the `A` value
835    pub fn clone_0(&self) -> A
836    where A: Clone { utils::untag(self.0.clone()) }
837
838    /// Clones the `B` value if one exists
839    pub fn clone_1(&self) -> Option<B>
840    where B: Clone {
841        self.ref_1().map(Clone::clone)
842    }
843
844    /// Gets a reference to the `B` value if one exists
845    pub fn ref_1(&self) -> Option<&B> {
846        if self.is_none() { None }
847        else { Some(&self.1) }
848    }
849
850    /// Gets a reference to the `B` value by assuming one exists
851    pub unsafe fn unwrap_ref_1(&self) -> &B {
852        debug_assert!(self.is_some());
853        &self.1
854    }
855
856    /// Gets mutable a reference to the `B` value if one exists
857    pub fn mut_1(&mut self) -> Option<&mut B> {
858        if self.is_none() { None }
859        else { Some(&mut self.1) }
860    }
861
862    /// Gets mutable a reference to the `B` value if one exists
863    pub unsafe fn unwrap_mut_1(&mut self) -> &mut B {
864        debug_assert!(self.is_some());
865        &mut self.1
866    }
867
868    /// Replaces the `A` value
869    pub fn replace_0(&mut self, a: A) -> A {
870        let a = utils::tag(a, utils::get_tag(&self.0));
871        utils::untag(replace(&mut self.0, a))
872    }
873
874    /// Replaces the `B` value
875    pub fn replace_1(&mut self, b: Option<B>) -> Option<B> {
876        match (utils::get_tag(&self.0), b) {
877            (Two::Option0, None) => None,
878            (Two::Option0, Some(b)) => { unsafe {
879                write(&mut self.1 as *mut B, b);
880                utils::change_tag(&mut self.0, Two::Option1);
881                None
882            }},
883            (Two::Option1, None) => { unsafe {
884                utils::change_tag(&mut self.0, Two::Option0);
885                Some(read(&self.1 as *const B))
886            }},
887            (Two::Option1, Some(b)) => Some(replace(&mut self.1, b)),
888        }
889    }
890
891    /// Maps the `A` and `B` values to a result
892    pub fn map<R, F: FnOnce(&mut A, Option<&mut B>)-> R>(&mut self, f: F) -> R {
893        let b = &mut self.1;
894        utils::borrow_untagged(&mut self.0, |tag, a|
895            match tag {
896                Two::Option0 => f(a, None),
897                Two::Option1 => f(a, Some(b)),
898            }
899        )
900    }
901}
902
903/// A helper type useful for accessing the lack of data or replacing it with nothing without having to
904/// use unwraps.
905pub struct EfficientOptionTupleInnerNone<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOptionTuple<A, B, TM>)
906where A: TaggableValue<TM, Two>;
907
908/// A helper type useful for accessing the optional data or removing it without having to
909/// use unwraps.
910pub struct EfficientOptionTupleInnerSome<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOptionTuple<A, B, TM>)
911where A: TaggableValue<TM, Two>;
912
913/// A helper type useful for accessing the lack of data or replacing it with nothing without having to
914/// use unwraps.
915pub enum EfficientOptionTupleInner<'a, A: 'a, B: 'a, TM: 'a = TagMSB>
916where A: TaggableValue<TM, Two> {
917    IsNone(EfficientOptionTupleInnerNone<'a, A, B, TM>),
918    IsSome(EfficientOptionTupleInnerSome<'a, A, B, TM>),
919}
920
921impl<'a, TM, A, B> EfficientOptionTupleInnerNone<'a, A, B, TM>
922where A: TaggableValue<TM, Two> {
923    /// Clones the `A` value
924    pub fn clone_0(&self) -> A
925    where A: Clone { self.0.clone_0() }
926
927    /// Adds a `B` value
928    pub fn add_1(self, b: B) -> EfficientOptionTupleInnerSome<'a, A, B, TM> {
929        debug_assert!(self.0.is_none());
930        unsafe {
931            write(&mut (self.0).1 as *mut B, b);
932            utils::change_tag(&mut (self.0).0, Two::Option1);
933        }
934        EfficientOptionTupleInnerSome(self.0)
935    }
936    /// Maps the `A` value to a result
937    pub fn map<R, F: FnOnce(&mut A)-> R>(&mut self, f: F) -> R {
938        debug_assert!(self.0.is_none());
939        utils::borrow_untagged(&mut (self.0).0, |_, a|
940            f(a)
941        )
942    }
943}
944
945impl<'a, TM, A, B> EfficientOptionTupleInnerSome<'a, A, B, TM>
946where A: TaggableValue<TM, Two> {
947    /// Clones the `A` value
948    pub fn clone_0(&self) -> A
949    where A: Clone { self.0.clone_0() }
950
951    /// Clones the `B` value
952    pub fn clone_1(&self) -> B
953    where B: Clone {
954        debug_assert!(self.0.is_some());
955        self.ref_1().clone()
956    }
957
958    /// Gets a reference to the `B` value
959    pub fn ref_1(&self) -> &B {
960        debug_assert!(self.0.is_some());
961        &(self.0).1
962    }
963
964    /// Gets mutable a reference to the `B` value
965    pub fn mut_1(&mut self) -> &mut B {
966        debug_assert!(self.0.is_some());
967        &mut (self.0).1
968    }
969
970    /// Destructures an `EfficientOptionTupleInnerSome` into a mutable reference to the `B` value
971    pub fn destructure_1(self) -> &'a mut B {
972        debug_assert!(self.0.is_some());
973        &mut (self.0).1
974    }
975
976    /// Replaces the `A` value
977    pub fn replace_0(&mut self, a: A) -> A {
978        debug_assert!(self.0.is_some());
979        self.0.replace_0(a)
980    }
981
982    /// Removes the `B` value
983    pub fn remove_1(self) -> (EfficientOptionTupleInnerNone<'a, A, B, TM>, B) {
984        debug_assert!(self.0.is_some());
985        let b = unsafe {
986           utils::change_tag(&mut (self.0).0, Two::Option0);
987           read(&(self.0).1 as *const B)
988        };
989        (EfficientOptionTupleInnerNone(self.0), b)
990    }
991
992    /// Maps the `A` and `B` values to a result
993    pub fn map<R, F: FnOnce(&mut A, &mut B)-> R>(&mut self, f: F) -> R {
994        debug_assert!(self.0.is_some());
995        let b = &mut (self.0).1;
996        utils::borrow_untagged(&mut (self.0).0, |_, a|
997            f(a, b)
998        )
999    }
1000}
1001
1002impl<'a, TM, A, B> EfficientOptionTupleInner<'a, A, B, TM>
1003where A: TaggableValue<TM, Two> {
1004    /// Unwraps an option, yielding the content of a `IsSome`.
1005    ///
1006    /// # Panics
1007    ///
1008    /// Panics if the value is a `IsNone` with a custom panic message provided by
1009    /// `msg`.
1010    #[inline]
1011    pub fn expect_some(self, msg: &str) -> EfficientOptionTupleInnerSome<'a, A, B, TM> {
1012        use self::EfficientOptionTupleInner::{IsNone,IsSome};
1013        match self {
1014            IsNone(_) => utils::expect_failed(msg),
1015            IsSome(x) => x,
1016        }
1017    }
1018
1019    /// Unwraps an option, yielding the content of a `IsNone`.
1020    ///
1021    /// # Panics
1022    ///
1023    /// Panics if the value is a `IsSome` with a custom panic message provided by
1024    /// `msg`.
1025    #[inline]
1026    pub fn expect_none(self, msg: &str) -> EfficientOptionTupleInnerNone<'a, A, B, TM> {
1027        use self::EfficientOptionTupleInner::{IsNone,IsSome};
1028        match self {
1029            IsNone(x) => x,
1030            IsSome(_) => utils::expect_failed(msg),
1031        }
1032    }
1033
1034    /// Moves the value `v` out if it is `IsSome(v)`.
1035    ///
1036    /// In general, because this function may panic, its use is discouraged.
1037    /// Instead, prefer to use pattern matching and handle the `IsNone`
1038    /// case explicitly.
1039    ///
1040    /// # Panics
1041    ///
1042    /// Panics if the self value equals `IsNone`.
1043    #[inline]
1044    pub fn unwrap_some(self) -> EfficientOptionTupleInnerSome<'a, A, B, TM> {
1045        use self::EfficientOptionTupleInner::{IsNone,IsSome};
1046        match self {
1047            IsNone(_) => panic!("called `EfficientOptionTupleInner::unwrap_some()` on a `IsNone` value"),
1048            IsSome(x) => x,
1049        }
1050    }
1051
1052    /// Moves the value `v` out if it is `IsNone(v)`.
1053    ///
1054    /// In general, because this function may panic, its use is discouraged.
1055    /// Instead, prefer to use pattern matching and handle the `IsSome`
1056    /// case explicitly.
1057    ///
1058    /// # Panics
1059    ///
1060    /// Panics if the self value equals `IsSome`.
1061    #[inline]
1062    pub fn unwrap_none(self) -> EfficientOptionTupleInnerNone<'a, A, B, TM> {
1063        use self::EfficientOptionTupleInner::{IsNone,IsSome};
1064        match self {
1065            IsNone(x) => x,
1066            IsSome(_) => panic!("called `EfficientOptionTupleInner::unwrap_none()` on a `IsSome` value"),
1067        }
1068    }
1069
1070    /// Returns the contained `IsSome` value or a default.
1071    #[inline]
1072    pub fn unwrap_some_or(self, default: EfficientOptionTupleInnerSome<'a, A, B, TM>) -> EfficientOptionTupleInnerSome<'a, A, B, TM> {
1073        self.map(|_| default, |x| x)
1074    }
1075
1076    /// Returns the contained `IsNone` value or a default.
1077    #[inline]
1078    pub fn unwrap_none_or(self, default: EfficientOptionTupleInnerNone<'a, A, B, TM>) -> EfficientOptionTupleInnerNone<'a, A, B, TM> {
1079        self.map(|x| x, |_| default)
1080    }
1081
1082    /// Returns the contained `IsSome` value or computes it from a closure.
1083    #[inline]
1084    pub fn unwrap_some_or_else<F>(self, f: F) -> EfficientOptionTupleInnerSome<'a, A, B, TM>
1085    where F: FnOnce(EfficientOptionTupleInnerNone<'a, A, B, TM>) -> EfficientOptionTupleInnerSome<'a, A, B, TM> {
1086        self.map(f, |x| x)
1087    }
1088
1089    /// Returns the contained `IsNone` value or computes it from a closure.
1090    #[inline]
1091    pub fn unwrap_none_or_else<F>(self, f: F) -> EfficientOptionTupleInnerNone<'a, A, B, TM>
1092    where F: FnOnce(EfficientOptionTupleInnerSome<'a, A, B, TM>) -> EfficientOptionTupleInnerNone<'a, A, B, TM> {
1093        self.map(|x| x, f)
1094    }
1095
1096    /// Applies a function to the contained `IsSome` value or returns a `default`.
1097    #[inline]
1098    pub fn map_some_or<U, F>(self, default: U, f: F) -> U
1099    where F: FnOnce(EfficientOptionTupleInnerSome<'a, A, B, TM>) -> U {
1100        self.map(|_| default, f)
1101    }
1102
1103    /// Applies a function to the contained `IsNone` value or returns a `default`.
1104    #[inline]
1105    pub fn map_none_or<U, F>(self, default: U, f: F) -> U
1106    where F: FnOnce(EfficientOptionTupleInnerNone<'a, A, B, TM>) -> U {
1107        self.map(f, |_| default)
1108    }
1109
1110
1111    /// Applies a function to the contained `IsSome` value or computes a `default` from the `IsNone`.
1112    #[inline]
1113    pub fn map<U, D, F>(self, default: D, f: F) -> U
1114    where D: FnOnce(EfficientOptionTupleInnerNone<'a, A, B, TM>) -> U,
1115    F: FnOnce(EfficientOptionTupleInnerSome<'a, A, B, TM>) -> U {
1116        use self::EfficientOptionTupleInner::{IsNone,IsSome};
1117        match self {
1118            IsNone(x) => default(x),
1119            IsSome(x) => f(x),
1120        }
1121    }
1122}
1123
1124/// A helper type for `Option`, useful for adding data to `is_none` options.
1125pub struct OptionNoneMut<'a, A: 'a>(&'a mut Option<A>);
1126
1127/// A helper type for `Option`, useful for accessing 'is_some' data and removing it.
1128pub struct OptionSomeMut<'a, A: 'a>(&'a mut Option<A>);
1129
1130/// A helper type for `Option`, gives access to `OptionNoneMut` and
1131/// `OptionSomeMut` variants.
1132pub enum OptionMut<'a, A: 'a> {
1133    IsNone(OptionNoneMut<'a, A>),
1134    IsSome(OptionSomeMut<'a, A>),
1135}
1136
1137impl<'a, A> OptionMut<'a, A> {
1138    pub fn new(a: &'a mut Option<A>) -> Self {
1139        use self::OptionMut::{IsNone,IsSome};
1140        if a.is_none() { IsNone(OptionNoneMut(a))}
1141        else { IsSome(OptionSomeMut(a))}
1142    }
1143}
1144
1145impl<'a, A> OptionNoneMut<'a, A> {
1146    /// Adds a value
1147    pub fn add(self, a: A) -> OptionSomeMut<'a, A> {
1148        debug_assert!(self.0.is_none());
1149        *self.0 = Some(a);
1150        OptionSomeMut(self.0)
1151    }
1152}
1153
1154impl<'a, A> OptionSomeMut<'a, A> {
1155    /// Gets a reference to the value
1156    pub fn as_ref(&self) -> &A {
1157        debug_assert!(self.0.is_some());
1158        self.0.as_ref().unwrap()
1159    }
1160
1161    /// Gets mutable a reference to the value
1162    pub fn as_mut(&mut self) -> &mut A {
1163        debug_assert!(self.0.is_some());
1164        self.0.as_mut().unwrap()
1165    }
1166
1167    /// Removes the value
1168    pub fn remove(self) -> (OptionNoneMut<'a, A>, A) {
1169        debug_assert!(self.0.is_some());
1170        let a = replace(self.0, None).unwrap();
1171        (OptionNoneMut(self.0), a)
1172    }
1173}
1174
1175impl<'a, A> OptionMut<'a, A> {
1176    /// Unwraps an option, yielding the content of a `IsSome`.
1177    ///
1178    /// # Panics
1179    ///
1180    /// Panics if the value is a `IsNone` with a custom panic message provided by
1181    /// `msg`.
1182    #[inline]
1183    pub fn expect_some(self, msg: &str) -> OptionSomeMut<'a, A> {
1184        use self::OptionMut::{IsNone,IsSome};
1185        match self {
1186            IsNone(_) => utils::expect_failed(msg),
1187            IsSome(x) => x,
1188        }
1189    }
1190
1191    /// Unwraps an option, yielding the content of a `IsNone`.
1192    ///
1193    /// # Panics
1194    ///
1195    /// Panics if the value is a `IsSome` with a custom panic message provided by
1196    /// `msg`.
1197    #[inline]
1198    pub fn expect_none(self, msg: &str) -> OptionNoneMut<'a, A> {
1199        use self::OptionMut::{IsNone,IsSome};
1200        match self {
1201            IsNone(x) => x,
1202            IsSome(_) => utils::expect_failed(msg),
1203        }
1204    }
1205
1206    /// Moves the value `v` out if it is `IsSome(v)`.
1207    ///
1208    /// In general, because this function may panic, its use is discouraged.
1209    /// Instead, prefer to use pattern matching and handle the `IsNone`
1210    /// case explicitly.
1211    ///
1212    /// # Panics
1213    ///
1214    /// Panics if the self value equals `IsNone`.
1215    #[inline]
1216    pub fn unwrap_some(self) -> OptionSomeMut<'a, A> {
1217        use self::OptionMut::{IsNone,IsSome};
1218        match self {
1219            IsNone(_) => panic!("called `OptionMut::unwrap_some()` on a `IsNone` value"),
1220            IsSome(x) => x,
1221        }
1222    }
1223
1224    /// Moves the value `v` out if it is `IsNone(v)`.
1225    ///
1226    /// In general, because this function may panic, its use is discouraged.
1227    /// Instead, prefer to use pattern matching and handle the `IsSome`
1228    /// case explicitly.
1229    ///
1230    /// # Panics
1231    ///
1232    /// Panics if the self value equals `IsSome`.
1233    #[inline]
1234    pub fn unwrap_none(self) -> OptionNoneMut<'a, A> {
1235        use self::OptionMut::{IsNone,IsSome};
1236        match self {
1237            IsNone(x) => x,
1238            IsSome(_) => panic!("called `OptionMut::unwrap_none()` on a `IsSome` value"),
1239        }
1240    }
1241
1242    /// Returns the contained `IsSome` value or a default.
1243    #[inline]
1244    pub fn unwrap_some_or(self, default: OptionSomeMut<'a, A>) -> OptionSomeMut<'a, A> {
1245        self.map(|_| default, |x| x)
1246    }
1247
1248    /// Returns the contained `IsNone` value or a default.
1249    #[inline]
1250    pub fn unwrap_none_or(self, default: OptionNoneMut<'a, A>) -> OptionNoneMut<'a, A> {
1251        self.map(|x| x, |_| default)
1252    }
1253
1254    /// Returns the contained `IsSome` value or computes it from a closure.
1255    #[inline]
1256    pub fn unwrap_some_or_else<F>(self, f: F) -> OptionSomeMut<'a, A>
1257    where F: FnOnce(OptionNoneMut<'a, A>) -> OptionSomeMut<'a, A> {
1258        self.map(f, |x| x)
1259    }
1260
1261    /// Returns the contained `IsNone` value or computes it from a closure.
1262    #[inline]
1263    pub fn unwrap_none_or_else<F>(self, f: F) -> OptionNoneMut<'a, A>
1264    where F: FnOnce(OptionSomeMut<'a, A>) -> OptionNoneMut<'a, A> {
1265        self.map(|x| x, f)
1266    }
1267
1268    /// Applies a function to the contained `IsSome` value or returns a `default`.
1269    #[inline]
1270    pub fn map_some_or<U, F>(self, default: U, f: F) -> U
1271    where F: FnOnce(OptionSomeMut<'a, A>) -> U {
1272        self.map(|_| default, f)
1273    }
1274
1275    /// Applies a function to the contained `IsNone` value or returns a `default`.
1276    #[inline]
1277    pub fn map_none_or<U, F>(self, default: U, f: F) -> U
1278    where F: FnOnce(OptionNoneMut<'a, A>) -> U {
1279        self.map(f, |_| default)
1280    }
1281
1282
1283    /// Applies a function to the contained `IsSome` value or computes a `default` from the `IsNone`.
1284    #[inline]
1285    pub fn map<U, D, F>(self, default: D, f: F) -> U
1286    where D: FnOnce(OptionNoneMut<'a, A>) -> U,
1287    F: FnOnce(OptionSomeMut<'a, A>) -> U {
1288        use self::OptionMut::{IsNone,IsSome};
1289        match self {
1290            IsNone(x) => default(x),
1291            IsSome(x) => f(x),
1292        }
1293    }
1294}
1295
1296#[cfg(test)]
1297mod tests {
1298    use super::*;
1299
1300    #[test]
1301    fn test_option_new() {
1302        let a = EfficientOption::<usize>::some_0(10);
1303        let b = EfficientOption::<usize>::new_0(Some(10));
1304        assert_eq!(a.destructure_0(), Some(10));
1305        assert_eq!(b.destructure_0(), Some(10));
1306        assert_eq!(a, b);
1307
1308        let a = EfficientOption::<usize>::none();
1309        let b = EfficientOption::<usize>::new(None);
1310        assert_eq!(a.destructure(), None);
1311        assert_eq!(b.destructure(), None);
1312        assert_eq!(a, b);
1313    }
1314
1315    #[test]
1316    fn test_option_simple() {
1317        let v = EfficientOption::<usize>::some_0(10);
1318        assert!(!v.is_none());
1319        assert!(v.is_some());
1320
1321        let v = EfficientOption::<usize>::none();
1322        assert!(v.is_none());
1323        assert!(!v.is_some());
1324    }
1325
1326    #[test]
1327    fn test_option_mut() {
1328        let mut v = EfficientOption::<usize>::some_0(10);
1329        assert_eq!(v.destructure_0(), Some(10));
1330
1331        v.map(|a| *a.unwrap().0 = 11 );
1332        assert_eq!(v.destructure_0(), Some(11));
1333
1334        v = EfficientOption::<usize>::none();
1335        assert_eq!(v.destructure(), None);
1336
1337        v.map(|a| assert_eq!(a, None));
1338        assert_eq!(v.destructure(), None);
1339    }
1340
1341    #[test]
1342    fn test_option_tuple_new() {
1343        let a = EfficientOptionTuple::<usize, usize>::some(10, 15);
1344        let b = EfficientOptionTuple::<usize, usize>::new(10, Some(15));
1345        assert_eq!(a.destructure(), (10, Some(15)));
1346        assert_eq!(b.destructure(), (10, Some(15)));
1347        assert_eq!(a, b);
1348
1349        let a = EfficientOptionTuple::<usize, usize>::none(10);
1350        let b = EfficientOptionTuple::<usize, usize>::new(10, None);
1351        assert_eq!(a.destructure(), (10, None));
1352        assert_eq!(b.destructure(), (10, None));
1353        assert_eq!(a, b);
1354    }
1355
1356    #[test]
1357    fn test_option_tuple_simple() {
1358        let v = EfficientOptionTuple::<usize, usize>::some(10, 15);
1359        assert!(!v.is_none());
1360        assert!(v.is_some());
1361        assert_eq!(v.clone_0(), 10);
1362        assert_eq!(v.clone_1(), Some(15));
1363        assert_eq!(*v.ref_1().unwrap(), 15);
1364        assert_eq!(v.destructure(), (10, Some(15)));
1365
1366        let v = EfficientOptionTuple::<usize, usize>::none(10);
1367        assert!(v.is_none());
1368        assert!(!v.is_some());
1369        assert_eq!(v.clone_0(), 10);
1370        assert_eq!(v.clone_1(), None);
1371        assert_eq!(v.ref_1(), None);
1372        assert_eq!(v.destructure(), (10, None));
1373    }
1374
1375    #[test]
1376    fn test_option_tuple_mut() {
1377        let mut v = EfficientOptionTuple::<usize, usize>::some(10, 15);
1378        assert_eq!(v.destructure(), (10, Some(15)));
1379
1380        *v.mut_1().unwrap() = 16;
1381        assert_eq!(v.destructure(), (10, Some(16)));
1382
1383        v.replace_0(11);
1384        assert_eq!(v.destructure(), (11, Some(16)));
1385
1386        v.replace_1(Some(17));
1387        assert_eq!(v.destructure(), (11, Some(17)));
1388
1389        v.replace_1(None);
1390        assert_eq!(v.destructure(), (11, None));
1391        assert_eq!(v.mut_1(), None);
1392
1393        v.map(|a, b| {
1394            *a = 12;
1395            assert_eq!(b, None);
1396        });
1397        assert_eq!(v.destructure(), (12, None));
1398
1399        v.replace_0(13);
1400        assert_eq!(v.destructure(), (13, None));
1401
1402        v.replace_1(Some(18));
1403        assert_eq!(v.destructure(), (13, Some(18)));
1404
1405        v.map(|a, b| {
1406            *a = 14;
1407            *b.unwrap() = 19;
1408        });
1409        assert_eq!(v.destructure(), (14, Some(19)));
1410    }
1411
1412    #[test]
1413    fn test_option_tuple_as_mut() {
1414        let mut v = EfficientOptionTuple::<usize, usize>::some(10, 15);
1415        {
1416            let r = v.inner();
1417            assert_eq!(r.unwrap_some().clone_0(), 10);
1418        }
1419        {
1420            let r = v.inner();
1421            assert_eq!(r.unwrap_some().clone_1(), 15);
1422        }
1423        {
1424            let r = v.inner();
1425            assert_eq!(*r.unwrap_some().ref_1(), 15);
1426        }
1427
1428
1429        let mut v = EfficientOptionTuple::<usize, usize>::none(10);
1430        {
1431            let r = v.inner();
1432            assert_eq!(r.unwrap_none().clone_0(), 10);
1433        }
1434    }
1435}