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
11pub 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 #[inline]
121 pub fn new(a: Option<(A, B)>) -> Self {
122 a.map_or_else(Self::none, Self::some)
123 }
124
125 #[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 #[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 #[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 #[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 #[inline]
156 pub fn some_0(a: A) -> Self
157 where B: Default {
158 Self::some((a, Default::default()))
159 }
160
161 #[inline]
163 pub fn some_1(b: B) -> Self
164 where A: Default {
165 Self::some((Default::default(), b))
166 }
167
168 pub fn clone_0(&self) -> Option<A>
170 where A: Clone {
171 self.ref_0().map(Clone::clone)
172 }
173
174 pub fn clone_1(&self) -> Option<B>
176 where B: Clone {
177 self.ref_1().map(Clone::clone)
178 }
179
180 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 pub fn ref_0(&self) -> Option<&A> {
188 if self.is_none() { None }
189 else { Some(&(self.0).1) }
190 }
191
192 pub fn ref_1(&self) -> Option<&B> {
194 if self.is_none() { None }
195 else { Some(&self.1) }
196 }
197
198 pub unsafe fn unwrap_ref(&self) -> (&A, &B) {
200 debug_assert!(self.is_some());
201 (&(self.0).1, &self.1)
202 }
203
204 pub unsafe fn unwrap_ref_0(&self) -> &A {
206 debug_assert!(self.is_some());
207 &(self.0).1
208 }
209
210 pub unsafe fn unwrap_ref_1(&self) -> &B {
212 debug_assert!(self.is_some());
213 &self.1
214 }
215
216 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 pub fn mut_1(&mut self) -> Option<&mut B> {
224 if self.is_none() { None }
225 else { Some(&mut self.1) }
226 }
227
228 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 pub unsafe fn unwrap_mut_1(&mut self) -> &mut B {
236 debug_assert!(self.is_some());
237 &mut self.1
238 }
239
240 #[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 #[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 #[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 #[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 #[inline]
275 pub fn destructure_0(self) -> Option<A> {
276 if self.is_none() { None } else { Some(utils::untag(self.0)) }
277 }
278
279 #[inline]
281 pub fn destructure_1(self) -> Option<B> {
282 if self.is_none() { None } else { Some(self.1) }
283 }
284
285 #[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 #[inline]
294 pub unsafe fn unwrap_destructure_0(self) -> A {
295 debug_assert!(self.is_some());
296 utils::untag(self.0)
297 }
298
299 #[inline]
301 pub unsafe fn unwrap_destructure_1(self) -> B {
302 debug_assert!(self.is_some());
303 self.1
304 }
305
306 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 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 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 #[inline]
349 pub fn is_some(&self) -> bool { utils::get_tag(&self.0) == One::Untagged }
350
351 #[inline]
353 pub fn is_none(&self) -> bool { !self.is_some() }
354
355 #[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
369pub struct EfficientOptionInnerNone<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOption<A, B, TM>)
371where A: TaggableValue<TM, One>;
372
373pub struct EfficientOptionInnerSome<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOption<A, B, TM>)
375where A: TaggableValue<TM, One>;
376
377pub 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 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 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 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 pub fn ref_0(&self) -> &A {
417 debug_assert!(self.0.is_some());
418 &((self.0).0).1
419 }
420
421 pub fn ref_1(&self) -> &B {
423 debug_assert!(self.0.is_some());
424 &(self.0).1
425 }
426
427 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 pub fn mut_1(&mut self) -> &mut B {
435 debug_assert!(self.0.is_some());
436 &mut (self.0).1
437 }
438
439 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 pub fn destructure_0(self) -> &'a A {
447 debug_assert!(self.0.is_some());
448 &((self.0).0).1
449 }
450
451 pub fn destructure_1(self) -> &'a mut B {
453 debug_assert!(self.0.is_some());
454 &mut (self.0).1
455 }
456
457 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 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 pub fn replace_1(&mut self, b: B) -> B {
471 replace(self.mut_1(), b)
472 }
473
474 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 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 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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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
640pub 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 #[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 #[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 #[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 #[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 #[inline]
763 pub fn destructure_0(self) -> A {
764 utils::untag(self.0)
765 }
766
767 #[inline]
769 pub fn destructure_1(self) -> Option<B> {
770 if self.is_none() { None } else { Some(self.1) }
771 }
772
773 #[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 #[inline]
782 pub unsafe fn unwrap_destructure_1(self) -> B {
783 debug_assert!(self.is_some());
784 self.1
785 }
786
787 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 #[inline]
802 pub fn is_some(&self) -> bool { utils::get_tag(&self.0) == Two::Option1 }
803
804 #[inline]
806 pub fn is_none(&self) -> bool { !self.is_some() }
807
808 #[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 #[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 #[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 pub fn clone_0(&self) -> A
836 where A: Clone { utils::untag(self.0.clone()) }
837
838 pub fn clone_1(&self) -> Option<B>
840 where B: Clone {
841 self.ref_1().map(Clone::clone)
842 }
843
844 pub fn ref_1(&self) -> Option<&B> {
846 if self.is_none() { None }
847 else { Some(&self.1) }
848 }
849
850 pub unsafe fn unwrap_ref_1(&self) -> &B {
852 debug_assert!(self.is_some());
853 &self.1
854 }
855
856 pub fn mut_1(&mut self) -> Option<&mut B> {
858 if self.is_none() { None }
859 else { Some(&mut self.1) }
860 }
861
862 pub unsafe fn unwrap_mut_1(&mut self) -> &mut B {
864 debug_assert!(self.is_some());
865 &mut self.1
866 }
867
868 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 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 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
903pub struct EfficientOptionTupleInnerNone<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOptionTuple<A, B, TM>)
906where A: TaggableValue<TM, Two>;
907
908pub struct EfficientOptionTupleInnerSome<'a, A: 'a, B: 'a, TM: 'a = TagMSB>(&'a mut EfficientOptionTuple<A, B, TM>)
911where A: TaggableValue<TM, Two>;
912
913pub 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 pub fn clone_0(&self) -> A
925 where A: Clone { self.0.clone_0() }
926
927 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 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 pub fn clone_0(&self) -> A
949 where A: Clone { self.0.clone_0() }
950
951 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 pub fn ref_1(&self) -> &B {
960 debug_assert!(self.0.is_some());
961 &(self.0).1
962 }
963
964 pub fn mut_1(&mut self) -> &mut B {
966 debug_assert!(self.0.is_some());
967 &mut (self.0).1
968 }
969
970 pub fn destructure_1(self) -> &'a mut B {
972 debug_assert!(self.0.is_some());
973 &mut (self.0).1
974 }
975
976 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 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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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
1124pub struct OptionNoneMut<'a, A: 'a>(&'a mut Option<A>);
1126
1127pub struct OptionSomeMut<'a, A: 'a>(&'a mut Option<A>);
1129
1130pub 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 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 pub fn as_ref(&self) -> &A {
1157 debug_assert!(self.0.is_some());
1158 self.0.as_ref().unwrap()
1159 }
1160
1161 pub fn as_mut(&mut self) -> &mut A {
1163 debug_assert!(self.0.is_some());
1164 self.0.as_mut().unwrap()
1165 }
1166
1167 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 #[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 #[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 #[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 #[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 #[inline]
1244 pub fn unwrap_some_or(self, default: OptionSomeMut<'a, A>) -> OptionSomeMut<'a, A> {
1245 self.map(|_| default, |x| x)
1246 }
1247
1248 #[inline]
1250 pub fn unwrap_none_or(self, default: OptionNoneMut<'a, A>) -> OptionNoneMut<'a, A> {
1251 self.map(|x| x, |_| default)
1252 }
1253
1254 #[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 #[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 #[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 #[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 #[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}