Embedded Template Library 1.0
Loading...
Searching...
No Matches
optional.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2015 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_OPTIONAL_INCLUDED
32#define ETL_OPTIONAL_INCLUDED
33
34#include "platform.h"
35#include "alignment.h"
36#include "memory.h"
37#include "type_traits.h"
38#include "exception.h"
39#include "error_handler.h"
40#include "utility.h"
41#include "placement_new.h"
42
43namespace etl
44{
45 //*****************************************************************************
48 //*****************************************************************************
50 {
51 public:
52
53 // Convertible to any type of null non-member pointer.
54 template<class T>
55 operator T*() const
56 {
57 return 0;
58 }
59
60 private:
61
62 // Can't take address of nullopt.
63 void operator&() const ETL_DELETE;
64 };
65
66 //*****************************************************************************
69 //*****************************************************************************
70 const nullopt_t nullopt = {};
71
72 //***************************************************************************
75 //***************************************************************************
85
86 //***************************************************************************
89 //***************************************************************************
91 {
92 public:
93
95 : optional_exception("optional:invalid", file_name_, line_number_)
96 {
97 }
98 };
99
100 //*****************************************************************************
101 // Implementations for fundamental and non fundamental types.
102 //*****************************************************************************
103 namespace private_optional
104 {
107
108 //*****************************************************************************
109 // Implementation for non fundamental types.
110 //*****************************************************************************
111 template <typename T>
112 class optional_impl<T, false>
113 {
114 protected:
115
116 typedef T value_type;
117
118 //***************************************************************************
120 //***************************************************************************
121 ETL_CONSTEXPR20_STL
123 : storage()
124 {
125 }
126
127 //***************************************************************************
129 //***************************************************************************
130 ETL_CONSTEXPR20_STL
132 : storage()
133 {
134 }
135
137 //***************************************************************************
139 //***************************************************************************
140 ETL_CONSTEXPR20_STL
142 {
143 if (other.has_value())
144 {
145 storage.construct(other.value());
146 }
147 }
149
150#if ETL_USING_CPP11
151 //***************************************************************************
153 //***************************************************************************
154 ETL_CONSTEXPR20_STL
156 {
157 if (other.has_value())
158 {
159 storage.construct(etl::move(other.value()));
160 }
161 }
162#endif
163
164 //***************************************************************************
166 //***************************************************************************
167 ETL_CONSTEXPR20_STL
169 {
170 storage.construct(value_);
171 }
172
173#if ETL_USING_CPP11
174 //***************************************************************************
176 //***************************************************************************
177 ETL_CONSTEXPR20_STL
179 {
180 storage.construct(etl::move(value_));
181 }
182#endif
183
184 //***************************************************************************
186 //***************************************************************************
187 ETL_CONSTEXPR20_STL
189 {
190 storage.destroy();
191 }
192
193 //***************************************************************************
195 //***************************************************************************
196 ETL_CONSTEXPR20_STL
198 {
199 if (has_value())
200 {
201 storage.destroy();
202 }
203
204 return *this;
205 }
206
207 //***************************************************************************
209 //***************************************************************************
210 ETL_CONSTEXPR20_STL
212 {
213 if (this != &other)
214 {
215 if (other.has_value())
216 {
217 storage.construct(other.value());
218 }
219 else
220 {
221 storage.destroy();
222 }
223 }
224
225 return *this;
226 }
227
228#if ETL_USING_CPP11
229 //***************************************************************************
231 //***************************************************************************
232 ETL_CONSTEXPR20_STL
234 {
235 if (this != &other)
236 {
237 if (other.has_value())
238 {
239 storage.construct(etl::move(other.value()));
240 }
241 else
242 {
243 storage.destroy();
244 }
245 }
246
247 return *this;
248 }
249#endif
250
251 //***************************************************************************
253 //***************************************************************************
254 ETL_CONSTEXPR20_STL
256 {
257 storage.construct(value_);
258
259 return *this;
260 }
261
262#if ETL_USING_CPP11
263 //***************************************************************************
265 //***************************************************************************
266 ETL_CONSTEXPR20_STL
268 {
269 storage.construct(etl::move(value_));
270
271 return *this;
272 }
273#endif
274
275 public:
276
277 //***************************************************************************
279 //***************************************************************************
280 ETL_CONSTEXPR20_STL
282 {
283#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
284 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
285#endif
286
287 return &storage.u.value;
288 }
289
290 //***************************************************************************
292 //***************************************************************************
293 ETL_CONSTEXPR20_STL
294 const T* operator ->() const
295 {
296#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
297 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
298#endif
299
300 return &storage.u.value;
301 }
302
303 //***************************************************************************
305 //***************************************************************************
306 ETL_CONSTEXPR20_STL
307 T& operator *() ETL_LVALUE_REF_QUALIFIER
308 {
309#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
310 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
311#endif
312
313 return storage.u.value;
314 }
315
316 //***************************************************************************
318 //***************************************************************************
319 ETL_CONSTEXPR20_STL
320 const T& operator *() const ETL_LVALUE_REF_QUALIFIER
321 {
322#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
323 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
324#endif
325
326 return storage.u.value;
327 }
328
329#if ETL_USING_CPP11
330 //***************************************************************************
332 //***************************************************************************
333 ETL_CONSTEXPR20_STL
334 T&& operator *()&&
335 {
336#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
337 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
338#endif
339
340 return etl::move(storage.u.value);
341 }
342
343 //***************************************************************************
345 //***************************************************************************
346 ETL_CONSTEXPR20_STL
347 const T&& operator *() const&&
348 {
349#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
350 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
351#endif
352
353 return etl::move(storage.u.value);
354 }
355#endif
356
357 //***************************************************************************
358 // Check whether optional contains value
359 //***************************************************************************
360 ETL_CONSTEXPR20_STL
361 bool has_value() const ETL_NOEXCEPT
362 {
363 return storage.valid;
364 }
365
366 //***************************************************************************
368 //***************************************************************************
369 ETL_CONSTEXPR20_STL
370 ETL_EXPLICIT operator bool() const
371 {
372 return has_value();
373 }
374
375 //***************************************************************************
377 //***************************************************************************
378 ETL_CONSTEXPR20_STL
379 T& value() ETL_LVALUE_REF_QUALIFIER
380 {
381#if ETL_IS_DEBUG_BUILD
382 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
383#endif
384
385 return storage.u.value;
386 }
387
388 //***************************************************************************
390 //***************************************************************************
391 ETL_CONSTEXPR20_STL
392 const T& value() const ETL_LVALUE_REF_QUALIFIER
393 {
394#if ETL_IS_DEBUG_BUILD
395 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
396#endif
397
398 return storage.u.value;
399 }
400
401 //***************************************************************************
403 //***************************************************************************
404 ETL_CONSTEXPR20_STL
405 T value_or(const T& default_value) const ETL_LVALUE_REF_QUALIFIER
406 {
407 return has_value() ? value() : default_value;
408 }
409
410#if ETL_USING_CPP11
411 //***************************************************************************
413 //***************************************************************************
414 ETL_CONSTEXPR20_STL
415 T&& value()&&
416 {
417#if ETL_IS_DEBUG_BUILD
418 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
419#endif
420
421 return etl::move(storage.u.value);
422 }
423
424 //***************************************************************************
426 //***************************************************************************
427 ETL_CONSTEXPR20_STL
428 const T&& value() const&&
429 {
430#if ETL_IS_DEBUG_BUILD
431 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
432#endif
433
434 return etl::move(storage.u.value);
435 }
436
437 //***************************************************************************
439 //***************************************************************************
440 template <typename U>
441 ETL_CONSTEXPR20_STL
443 value_or(U&& default_value) const&
444 {
445 return has_value() ? value() : etl::forward<T>(default_value);
446 }
447
448 //***************************************************************************
450 //***************************************************************************
451 template <typename U>
452 ETL_CONSTEXPR20_STL
454 value_or(U&& default_value)&&
455 {
456 return has_value() ? etl::move(value()) : etl::forward<T>(default_value);
457 }
458#endif
459
460 //***************************************************************************
462 //***************************************************************************
463 ETL_CONSTEXPR20_STL
465 {
466 optional_impl temp(*this);
467 *this = other;
468 other = temp;
469 }
470
471 //***************************************************************************
473 //***************************************************************************
474 ETL_CONSTEXPR20_STL
475 void reset()
476 {
477 storage.destroy();
478 }
479
480#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
481 //*************************************************************************
484 //*************************************************************************
485 template <typename... TArgs>
486 ETL_CONSTEXPR20_STL
487 T& emplace(TArgs&& ... args)
488 {
489 storage.construct(etl::forward<TArgs>(args)...);
490
491 return storage.u.value;
492 }
493#else
494 //*************************************************************************
497 //*************************************************************************
499 {
500 if (has_value())
501 {
502 // Destroy the old one.
503 storage.destroy();
504 }
505
506 T* p = ::new (&storage.u.value) T();
507 storage.valid = true;
508
509 return *p;
510 }
511
512 //*************************************************************************
515 //*************************************************************************
516 template <typename T1>
517 T& emplace(const T1& value1)
518 {
519 if (has_value())
520 {
521 // Destroy the old one.
522 storage.destroy();
523 }
524
525 T* p = ::new (&storage.u.value) T(value1);
526 storage.valid = true;
527
528 return *p;
529 }
530
531 //*************************************************************************
534 //*************************************************************************
535 template <typename T1, typename T2>
536 T& emplace(const T1& value1, const T2& value2)
537 {
538 if (has_value())
539 {
540 // Destroy the old one.
541 storage.destroy();
542 }
543
544 T* p = ::new (&storage.u.value) T(value1, value2);
545 storage.valid = true;
546
547 return *p;
548 }
549
550 //*************************************************************************
553 //*************************************************************************
554 template <typename T1, typename T2, typename T3>
555 T& emplace(const T1& value1, const T2& value2, const T3& value3)
556 {
557 if (has_value())
558 {
559 // Destroy the old one.
560 storage.destroy();
561 }
562
563 T* p = ::new (&storage.u.value) T(value1, value2, value3);
564 storage.valid = true;
565
566 return *p;
567 }
568
569 //*************************************************************************
572 //*************************************************************************
573 template <typename T1, typename T2, typename T3, typename T4>
574 T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
575 {
576 if (has_value())
577 {
578 // Destroy the old one.
579 storage.destroy();
580 }
581
582 T* p = ::new (&storage.u.value) T(value1, value2, value3, value4);
583 storage.valid = true;
584
585 return *p;
586 }
587#endif
588
589 private:
590
591 struct dummy_t {};
592
593 //*************************************
594 // The storage for the optional value.
595 //*************************************
596 struct storage_type
597 {
598 //*******************************
599 ETL_CONSTEXPR20_STL
600 storage_type()
601 : u()
602 , valid(false)
603 {
604 }
605
606 //*******************************
607 ETL_CONSTEXPR20_STL
608 void construct(const T& value_)
609 {
610 if (valid)
611 {
612 etl::destroy_at(&u.value);
613 }
614
615 etl::construct_at(&u.value, value_);
616 valid = true;
617 }
618
619#if ETL_USING_CPP11
620 //*******************************
621 ETL_CONSTEXPR20_STL
622 void construct(T&& value_)
623 {
624 if (valid)
625 {
626 etl::destroy_at(&u.value);
627 }
628
629 etl::construct_at(&u.value, etl::move(value_));
630 valid = true;
631 }
632
633 //*******************************
634 template <typename... TArgs>
635 ETL_CONSTEXPR20_STL
636 void construct(TArgs&&... args)
637 {
638 if (valid)
639 {
640 etl::destroy_at(&u.value);
641 }
642
643 etl::construct_at(&u.value, etl::forward<TArgs>(args)...);
644 valid = true;
645 }
646#endif
647
648 //*******************************
649 ETL_CONSTEXPR20_STL
650 void destroy()
651 {
652 if (valid)
653 {
654 etl::destroy_at(&u.value);
655 valid = false;
656 }
657 }
658
659 //*******************************
660 union union_type
661 {
662 ETL_CONSTEXPR20_STL
663 union_type()
664 : dummy()
665 {
666 }
667
668 ETL_CONSTEXPR20_STL
669 ~union_type()
670 {
671 }
672
673 dummy_t dummy;
674 T value;
675 } u;
676
677 bool valid;
678 };
679
680 storage_type storage;
681 };
682
683 //*****************************************************************************
684 // Implementation for fundamental types.
685 //*****************************************************************************
686 template <typename T>
687 class optional_impl<T, true>
688 {
689 protected:
690
691 typedef T value_type;
692
693 //***************************************************************************
695 //***************************************************************************
696 ETL_CONSTEXPR14
698 : storage()
699 {
700 }
701
702 //***************************************************************************
704 //***************************************************************************
705 ETL_CONSTEXPR14
707 : storage()
708 {
709 }
710
712 //***************************************************************************
714 //***************************************************************************
715 ETL_CONSTEXPR14
717 {
718 if (other.has_value())
719 {
720 storage.construct(other.value());
721 }
722 }
724
725#if ETL_USING_CPP11
726 //***************************************************************************
728 //***************************************************************************
729 ETL_CONSTEXPR14
731 {
732 if (other.has_value())
733 {
734 storage.construct(etl::move(other.value()));
735 }
736 }
737#endif
738
739 //***************************************************************************
741 //***************************************************************************
742 ETL_CONSTEXPR14
744 {
745 storage.construct(value_);
746 }
747
748#if ETL_USING_CPP11
749 //***************************************************************************
751 //***************************************************************************
752 ETL_CONSTEXPR14
754 {
755 storage.construct(etl::move(value_));
756 }
757#endif
758
759 //***************************************************************************
761 //***************************************************************************
762 ETL_CONSTEXPR14
764 {
765 if (has_value())
766 {
767 storage.destroy();
768 }
769
770 return *this;
771 }
772
773 //***************************************************************************
775 //***************************************************************************
776 ETL_CONSTEXPR14
778 {
779 if (this != &other)
780 {
781 if (other.has_value())
782 {
783 storage.construct(other.value());
784 }
785 else
786 {
787 storage.destroy();
788 }
789 }
790
791 return *this;
792 }
793
794#if ETL_USING_CPP11
795 //***************************************************************************
797 //***************************************************************************
798 ETL_CONSTEXPR14
800 {
801 if (this != &other)
802 {
803 if (other.has_value())
804 {
805 storage.construct(etl::move(other.value()));
806 }
807 else
808 {
809 storage.destroy();
810 }
811 }
812
813 return *this;
814 }
815#endif
816
817 //***************************************************************************
819 //***************************************************************************
820 ETL_CONSTEXPR14
822 {
823 storage.construct(value_);
824
825 return *this;
826 }
827
828#if ETL_USING_CPP11
829 //***************************************************************************
831 //***************************************************************************
832 ETL_CONSTEXPR14
834 {
835 storage.construct(etl::move(value_));
836
837 return *this;
838 }
839#endif
840
841 public:
842
843 //***************************************************************************
845 //***************************************************************************
846 ETL_CONSTEXPR14
848 {
849#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
850 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
851#endif
852
853 return &storage.value;
854 }
855
856 //***************************************************************************
858 //***************************************************************************
859 ETL_CONSTEXPR14
860 const T* operator ->() const
861 {
862#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
863 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
864#endif
865
866 return &storage.value;
867 }
868
869 //***************************************************************************
871 //***************************************************************************
872 ETL_CONSTEXPR14
873 T& operator *() ETL_LVALUE_REF_QUALIFIER
874 {
875#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
876 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
877#endif
878
879 return storage.value;
880 }
881
882 //***************************************************************************
884 //***************************************************************************
885 ETL_CONSTEXPR14
886 const T& operator *() const ETL_LVALUE_REF_QUALIFIER
887 {
888#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
889 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
890#endif
891
892 return storage.value;
893 }
894
895#if ETL_USING_CPP11
896 //***************************************************************************
898 //***************************************************************************
899 ETL_CONSTEXPR14
900 T&& operator *()&&
901 {
902#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
903 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
904#endif
905
906 return etl::move(storage.value);
907 }
908
909 //***************************************************************************
911 //***************************************************************************
912 ETL_CONSTEXPR14
913 const T&& operator *() const&&
914 {
915#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
916 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
917#endif
918
919 return etl::move(storage.value);
920 }
921#endif
922
923 //***************************************************************************
924 // Check whether optional contains value
925 //***************************************************************************
926 ETL_CONSTEXPR14
927 bool has_value() const ETL_NOEXCEPT
928 {
929 return storage.valid;
930 }
931
932 //***************************************************************************
934 //***************************************************************************
935 ETL_CONSTEXPR14
936 ETL_EXPLICIT operator bool() const
937 {
938 return has_value();
939 }
940
941 //***************************************************************************
943 //***************************************************************************
944 ETL_CONSTEXPR14
945 T& value() ETL_LVALUE_REF_QUALIFIER
946 {
947#if ETL_IS_DEBUG_BUILD
948 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
949#endif
950
951 return storage.value;
952 }
953
954 //***************************************************************************
956 //***************************************************************************
957 ETL_CONSTEXPR14
958 const T& value() const ETL_LVALUE_REF_QUALIFIER
959 {
960#if ETL_IS_DEBUG_BUILD
961 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
962#endif
963
964 return storage.value;
965 }
966
967 //***************************************************************************
969 //***************************************************************************
970 ETL_CONSTEXPR14
971 T value_or(const T& default_value) const ETL_LVALUE_REF_QUALIFIER
972 {
973 return has_value() ? value() : default_value;
974 }
975
976#if ETL_USING_CPP11
977 //***************************************************************************
979 //***************************************************************************
980 ETL_CONSTEXPR14
981 T&& value()&&
982 {
983#if ETL_IS_DEBUG_BUILD
984 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
985#endif
986
987 return etl::move(storage.value);
988 }
989
990 //***************************************************************************
992 //***************************************************************************
993 ETL_CONSTEXPR14
994 const T&& value() const&&
995 {
996#if ETL_IS_DEBUG_BUILD
997 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
998#endif
999
1000 return etl::move(storage.value);
1001 }
1002
1003 //***************************************************************************
1005 //***************************************************************************
1006 template <typename U>
1007 ETL_CONSTEXPR14
1009 value_or(U&& default_value) const&
1010 {
1011 return has_value() ? value() : etl::forward<T>(default_value);
1012 }
1013
1014 //***************************************************************************
1016 //***************************************************************************
1017 template <typename U>
1018 ETL_CONSTEXPR14
1020 value_or(U&& default_value)&&
1021 {
1022 return has_value() ? etl::move(value()) : etl::forward<T>(default_value);
1023 }
1024#endif
1025
1026 //***************************************************************************
1028 //***************************************************************************
1029 ETL_CONSTEXPR14
1031 {
1032 optional_impl temp(*this);
1033 *this = other;
1034 other = temp;
1035 }
1036
1037 //***************************************************************************
1039 //***************************************************************************
1040 ETL_CONSTEXPR14
1041 void reset()
1042 {
1043 storage.destroy();
1044 }
1045
1046#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
1047 //*************************************************************************
1050 //*************************************************************************
1051 template <typename... TArgs>
1052 ETL_CONSTEXPR14
1053 T& emplace(TArgs&& ... args)
1054 {
1055 storage.construct(etl::forward<TArgs>(args)...);
1056
1057 return storage.value;
1058 }
1059#else
1060 //*************************************************************************
1063 //*************************************************************************
1065 {
1066 if (has_value())
1067 {
1068 // Destroy the old one.
1069 storage.destroy();
1070 }
1071
1072 T* p = ::new (&storage.value) T();
1073 storage.valid = true;
1074
1075 return *p;
1076 }
1077
1078 //*************************************************************************
1081 //*************************************************************************
1082 template <typename T1>
1083 T& emplace(const T1& value1)
1084 {
1085 if (has_value())
1086 {
1087 // Destroy the old one.
1088 storage.destroy();
1089 }
1090
1091 T* p = ::new (&storage.value) T(value1);
1092 storage.valid = true;
1093
1094 return *p;
1095 }
1096
1097 //*************************************************************************
1100 //*************************************************************************
1101 template <typename T1, typename T2>
1102 T& emplace(const T1& value1, const T2& value2)
1103 {
1104 if (has_value())
1105 {
1106 // Destroy the old one.
1107 storage.destroy();
1108 }
1109
1110 T* p = ::new (&storage.value) T(value1, value2);
1111 storage.valid = true;
1112
1113 return *p;
1114 }
1115
1116 //*************************************************************************
1119 //*************************************************************************
1120 template <typename T1, typename T2, typename T3>
1121 T& emplace(const T1& value1, const T2& value2, const T3& value3)
1122 {
1123 if (has_value())
1124 {
1125 // Destroy the old one.
1126 storage.destroy();
1127 }
1128
1129 T* p = ::new (&storage.value) T(value1, value2, value3);
1130 storage.valid = true;
1131
1132 return *p;
1133 }
1134
1135 //*************************************************************************
1138 //*************************************************************************
1139 template <typename T1, typename T2, typename T3, typename T4>
1140 T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1141 {
1142 if (has_value())
1143 {
1144 // Destroy the old one.
1145 storage.destroy();
1146 }
1147
1148 T* p = ::new (&storage.value) T(value1, value2, value3, value4);
1149 storage.valid = true;
1150
1151 return *p;
1152 }
1153#endif
1154
1155 private:
1156
1157 //*************************************
1158 // The storage for the optional value.
1159 //*************************************
1160 struct storage_type
1161 {
1162 //*******************************
1163 ETL_CONSTEXPR14
1164 storage_type()
1165 : value()
1166 , valid(false)
1167 {
1168 }
1169
1170 //*******************************
1171 ETL_CONSTEXPR14
1172 void construct(const T& value_)
1173 {
1174 value = value_;
1175 valid = true;
1176 }
1177
1178#if ETL_USING_CPP11
1179 //*******************************
1180 ETL_CONSTEXPR14
1181 void construct(T&& value_)
1182 {
1183 value = value_;
1184 valid = true;
1185 }
1186
1187 //*******************************
1188 template <typename... TArgs>
1189 ETL_CONSTEXPR14
1190 void construct(TArgs&&... args)
1191 {
1192 value = T(etl::forward<TArgs>(args)...);
1193 valid = true;
1194 }
1195#endif
1196
1197 //*******************************
1198 ETL_CONSTEXPR14
1199 void destroy()
1200 {
1201 valid = false;
1202 }
1203
1204 T value;
1205 bool valid;
1206 };
1207
1208 storage_type storage;
1209 };
1210 }
1211
1212#define ETL_OPTIONAL_ENABLE_CPP14 typename etl::enable_if< etl::is_pod<U>::value, int>::type = 0
1213#define ETL_OPTIONAL_ENABLE_CPP20_STL typename etl::enable_if<!etl::is_pod<U>::value, int>::type = 0
1214
1215#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 ETL_CONSTEXPR14 typename etl::enable_if< etl::is_pod<T>::value, bool>::type
1216#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL ETL_CONSTEXPR20_STL typename etl::enable_if<!etl::is_pod<T>::value, bool>::type
1217
1218 //*****************************************************************************
1224 //*****************************************************************************
1225 template <typename T>
1227 {
1228 private:
1229
1231
1232 public:
1233
1234 typedef T value_type;
1235
1236#if ETL_USING_CPP11
1237 //***************************************************************************
1239 //***************************************************************************
1240 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1241 ETL_CONSTEXPR14
1242 optional()
1243 : impl_t()
1244 {
1245 }
1246
1247 //***************************************************************************
1249 //***************************************************************************
1250 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1251 ETL_CONSTEXPR20_STL
1252 optional()
1253 : impl_t()
1254 {
1255 }
1256#else
1257 optional()
1258 : impl_t()
1259 {
1260 }
1261#endif
1262
1263#if ETL_USING_CPP11
1264 //***************************************************************************
1266 //***************************************************************************
1267 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1268 ETL_CONSTEXPR14
1271 {
1272 }
1273
1274 //***************************************************************************
1276 //***************************************************************************
1277 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1278 ETL_CONSTEXPR20_STL
1281 {
1282 }
1283#else
1284 //***************************************************************************
1286 //***************************************************************************
1288 : impl_t(etl::nullopt)
1289 {
1290 }
1291#endif
1292
1294#if ETL_USING_CPP11
1295 //***************************************************************************
1297 //***************************************************************************
1298 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1299 ETL_CONSTEXPR14
1300 optional(const optional& other)
1301 : impl_t(other)
1302 {
1303 }
1304
1305 //***************************************************************************
1307 //***************************************************************************
1308 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1309 ETL_CONSTEXPR20_STL
1310 optional(const optional& other)
1311 : impl_t(other)
1312 {
1313 }
1314#else
1315 //***************************************************************************
1317 //***************************************************************************
1319 : impl_t(other)
1320 {
1321 }
1322#endif
1323#include "private/diagnostic_pop.h"
1324
1325#if ETL_USING_CPP11
1326 //***************************************************************************
1328 //***************************************************************************
1329 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1330 ETL_CONSTEXPR14
1332 : impl_t(other)
1333 {
1334 }
1335
1336 //***************************************************************************
1338 //***************************************************************************
1339 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1340 ETL_CONSTEXPR20_STL
1341 optional(optional&& other)
1342 : impl_t(other)
1343 {
1344 }
1345#endif
1346
1347#if ETL_USING_CPP11
1348 //***************************************************************************
1350 //***************************************************************************
1351 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1352 ETL_CONSTEXPR14
1353 optional(const T& value_)
1354 : impl_t(value_)
1355 {
1356 }
1357
1358 //***************************************************************************
1360 //***************************************************************************
1361 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1362 ETL_CONSTEXPR20_STL
1363 optional(const T& value_)
1364 : impl_t(value_)
1365 {
1366 }
1367#else
1368 //***************************************************************************
1370 //***************************************************************************
1372 : impl_t(value_)
1373 {
1374 }
1375#endif
1376
1377
1378#if ETL_USING_CPP11
1379 //***************************************************************************
1381 //***************************************************************************
1382 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1383 ETL_CONSTEXPR14
1384 optional(T&& value_)
1385 : impl_t(etl::move(value_))
1386 {
1387 }
1388
1389 //***************************************************************************
1391 //***************************************************************************
1392 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1393 ETL_CONSTEXPR20_STL
1394 optional(T&& value_)
1395 : impl_t(etl::move(value_))
1396 {
1397 }
1398#endif
1399
1400#if ETL_USING_CPP11
1401 //***************************************************************************
1403 //***************************************************************************
1404 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1405 ETL_CONSTEXPR14
1406 optional& operator =(etl::nullopt_t)
1407 {
1408 impl_t::operator=(etl::nullopt);
1409
1410 return *this;
1411 }
1412
1413 //***************************************************************************
1415 //***************************************************************************
1416 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1417 ETL_CONSTEXPR20_STL
1418 optional& operator =(etl::nullopt_t)
1419 {
1420 impl_t::operator=(etl::nullopt);
1421
1422 return *this;
1423 }
1424#else
1425 //***************************************************************************
1427 //***************************************************************************
1429 {
1430 impl_t::operator=(etl::nullopt);
1431
1432 return *this;
1433 }
1434#endif
1435
1436#if ETL_USING_CPP11
1437 //***************************************************************************
1439 //***************************************************************************
1440 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1441 ETL_CONSTEXPR14
1443 {
1444 impl_t::operator=(other);
1445
1446 return *this;
1447 }
1448
1449 //***************************************************************************
1451 //***************************************************************************
1452 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1453 ETL_CONSTEXPR20_STL
1454 optional& operator =(const optional& other)
1455 {
1456 impl_t::operator=(other);
1457
1458 return *this;
1459 }
1460#else
1461 //***************************************************************************
1463 //***************************************************************************
1465 {
1466 impl_t::operator=(other);
1467
1468 return *this;
1469 }
1470#endif
1471
1472#if ETL_USING_CPP11
1473 //***************************************************************************
1475 //***************************************************************************
1476 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1477 ETL_CONSTEXPR14
1479 {
1480 impl_t::operator=(etl::move(other));
1481
1482 return *this;
1483 }
1484
1485 //***************************************************************************
1487 //***************************************************************************
1488 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1489 ETL_CONSTEXPR20_STL
1490 optional& operator =(optional&& other)
1491 {
1492 impl_t::operator=(etl::move(other));
1493
1494 return *this;
1495 }
1496#endif
1497
1498#if ETL_USING_CPP11
1499 //***************************************************************************
1501 //***************************************************************************
1502 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1503 ETL_CONSTEXPR14
1504 optional& operator =(const T& value_)
1505 {
1506 impl_t::operator=(value_);
1507
1508 return *this;
1509 }
1510
1511 //***************************************************************************
1513 //***************************************************************************
1514 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1515 ETL_CONSTEXPR20_STL
1516 optional& operator =(const T& value_)
1517 {
1518 impl_t::operator=(value_);
1519
1520 return *this;
1521 }
1522#else
1523 //***************************************************************************
1525 //***************************************************************************
1527 {
1528 impl_t::operator=(value_);
1529
1530 return *this;
1531 }
1532#endif
1533
1534#if ETL_USING_CPP11
1535 //***************************************************************************
1537 //***************************************************************************
1538 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1539 ETL_CONSTEXPR14
1541 {
1542 impl_t::operator=(etl::move(value_));
1543
1544 return *this;
1545 }
1546
1547 //***************************************************************************
1549 //***************************************************************************
1550 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1551 ETL_CONSTEXPR20_STL
1552 optional& operator =(T&& value_)
1553 {
1554 impl_t::operator=(etl::move(value_));
1555
1556 return *this;
1557 }
1558#endif
1559 };
1560
1562
1563 //***************************************************************************
1565 //***************************************************************************
1566 template <typename T>
1567 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1568 {
1569 if (lhs.has_value() != rhs.has_value())
1570 {
1571 return false;
1572 }
1573 else if (!lhs.has_value() && !rhs.has_value())
1574 {
1575 return true;
1576 }
1577 else
1578 {
1579 return lhs.value() == rhs.value();
1580 }
1581 }
1582
1583 //***************************************************************************
1585 //***************************************************************************
1586 template <typename T>
1587 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1588 {
1589 if (lhs.has_value() != rhs.has_value())
1590 {
1591 return false;
1592 }
1593 else if (!lhs.has_value() && !rhs.has_value())
1594 {
1595 return true;
1596 }
1597 else
1598 {
1599 return lhs.value() == rhs.value();
1600 }
1601 }
1602
1603 //***************************************************************************
1605 //***************************************************************************
1606 template <typename T>
1607 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1608 {
1609 return !(lhs == rhs);
1610 }
1611
1612 //***************************************************************************
1614 //***************************************************************************
1615 template <typename T>
1616 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1617 {
1618 return !(lhs == rhs);
1619 }
1620
1621 //***************************************************************************
1623 //***************************************************************************
1624 template <typename T>
1625 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1626 {
1627 if (!rhs.has_value())
1628 {
1629 return false;
1630 }
1631 else if (!lhs.has_value())
1632 {
1633 return true;
1634 }
1635 else
1636 {
1637 return lhs.value() < rhs.value();
1638 }
1639 }
1640
1641 //***************************************************************************
1643 //***************************************************************************
1644 template <typename T>
1645 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1646 {
1647 if (!rhs.has_value())
1648 {
1649 return false;
1650 }
1651 else if (!lhs.has_value())
1652 {
1653 return true;
1654 }
1655 else
1656 {
1657 return lhs.value() < rhs.value();
1658 }
1659 }
1660
1661 //***************************************************************************
1663 //***************************************************************************
1664 template <typename T>
1665 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1666 {
1667 return !(rhs < lhs);
1668 }
1669
1670 //***************************************************************************
1672 //***************************************************************************
1673 template <typename T>
1674 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1675 {
1676 return !(rhs < lhs);
1677 }
1678
1679 //***************************************************************************
1681 //***************************************************************************
1682 template <typename T>
1683 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1684 {
1685 return (rhs < lhs);
1686 }
1687
1688 //***************************************************************************
1690 //***************************************************************************
1691 template <typename T>
1692 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1693 {
1694 return (rhs < lhs);
1695 }
1696
1697 //***************************************************************************
1699 //***************************************************************************
1700 template <typename T>
1701 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1702 {
1703 return !(lhs < rhs);
1704 }
1705
1706 //***************************************************************************
1708 //***************************************************************************
1709 template <typename T>
1710 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1711 {
1712 return !(lhs < rhs);
1713 }
1714
1715 //***************************************************************************
1717 //***************************************************************************
1718 template <typename T>
1719 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
1720 {
1721 return !lhs.has_value();
1722 }
1723
1724 //***************************************************************************
1726 //***************************************************************************
1727 template <typename T>
1728 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
1729 {
1730 return !lhs.has_value();
1731 }
1732
1733 //***************************************************************************
1735 //***************************************************************************
1736 template <typename T>
1737 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
1738 {
1739 return !rhs.has_value();
1740 }
1741
1742 //***************************************************************************
1744 //***************************************************************************
1745 template <typename T>
1746 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
1747 {
1748 return !rhs.has_value();
1749 }
1750
1751 //***************************************************************************
1753 //***************************************************************************
1754 template <typename T>
1755 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
1756 {
1757 return !(lhs == etl::nullopt);
1758 }
1759
1760 //***************************************************************************
1762 //***************************************************************************
1763 template <typename T>
1764 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
1765 {
1766 return !(lhs == etl::nullopt);
1767 }
1768
1769 //***************************************************************************
1771 //***************************************************************************
1772 template <typename T>
1773 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(etl::nullopt_t , const etl::optional<T>& rhs)
1774 {
1775 return !(etl::nullopt == rhs);
1776 }
1777
1778 //***************************************************************************
1780 //***************************************************************************
1781 template <typename T>
1782 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(etl::nullopt_t, const etl::optional<T>& rhs)
1783 {
1784 return !(etl::nullopt == rhs);
1785 }
1786
1787 //***************************************************************************
1789 //***************************************************************************
1790 template <typename T>
1791 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>&, etl::nullopt_t)
1792 {
1793 return false;
1794 }
1795
1796 //***************************************************************************
1798 //***************************************************************************
1799 template <typename T>
1800 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>&, etl::nullopt_t)
1801 {
1802 return false;
1803 }
1804
1805 //***************************************************************************
1807 //***************************************************************************
1808 template <typename T>
1809 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(etl::nullopt_t, const etl::optional<T>& rhs)
1810 {
1811 return rhs.has_value();
1812 }
1813
1814 //***************************************************************************
1816 //***************************************************************************
1817 template <typename T>
1818 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(etl::nullopt_t, const etl::optional<T>& rhs)
1819 {
1820 return rhs.has_value();
1821 }
1822
1823 //***************************************************************************
1825 //***************************************************************************
1826 template <typename T>
1827 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
1828 {
1829 return !lhs.has_value();
1830 }
1831
1832 //***************************************************************************
1834 //***************************************************************************
1835 template <typename T>
1836 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
1837 {
1838 return !lhs.has_value();
1839 }
1840
1841 //***************************************************************************
1843 //***************************************************************************
1844 template <typename T>
1845 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(etl::nullopt_t, const etl::optional<T>&)
1846 {
1847 return true;
1848 }
1849
1850 //***************************************************************************
1852 //***************************************************************************
1853 template <typename T>
1854 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(etl::nullopt_t, const etl::optional<T>&)
1855 {
1856 return true;
1857 }
1858
1859 //***************************************************************************
1861 //***************************************************************************
1862 template <typename T>
1863 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, etl::nullopt_t)
1864 {
1865 return lhs.has_value();
1866 }
1867
1868 //***************************************************************************
1870 //***************************************************************************
1871 template <typename T>
1872 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, etl::nullopt_t)
1873 {
1874 return lhs.has_value();
1875 }
1876
1877 //***************************************************************************
1879 //***************************************************************************
1880 template <typename T>
1881 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(etl::nullopt_t, const etl::optional<T>&)
1882 {
1883 return false;
1884 }
1885
1886 //***************************************************************************
1888 //***************************************************************************
1889 template <typename T>
1890 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(etl::nullopt_t, const etl::optional<T>&)
1891 {
1892 return false;
1893 }
1894
1895 //***************************************************************************
1897 //***************************************************************************
1898 template <typename T>
1899 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>&, etl::nullopt_t)
1900 {
1901 return true;
1902 }
1903
1904 //***************************************************************************
1906 //***************************************************************************
1907 template <typename T>
1908 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>&, etl::nullopt_t)
1909 {
1910 return true;
1911 }
1912
1913 //***************************************************************************
1915 //***************************************************************************
1916 template <typename T>
1917 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
1918 {
1919 return !rhs.has_value();
1920 }
1921
1922 //***************************************************************************
1924 //***************************************************************************
1925 template <typename T>
1926 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
1927 {
1928 return !rhs.has_value();
1929 }
1930
1931 //***************************************************************************
1933 //**************************************************************************
1934 template <typename T, typename U>
1935 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const U& rhs)
1936 {
1937 return lhs.has_value() ? lhs.value() == rhs : false;
1938 }
1939
1940 //***************************************************************************
1942 //**************************************************************************
1943 template <typename T, typename U>
1944 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const U& rhs)
1945 {
1946 return lhs.has_value() ? lhs.value() == rhs : false;
1947 }
1948
1949 //***************************************************************************
1951 //**************************************************************************
1952 template <typename T, typename U>
1953 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const U& rhs)
1954 {
1955 return !(lhs == rhs);
1956 }
1957
1958 //***************************************************************************
1960 //**************************************************************************
1961 template <typename T, typename U>
1962 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const U& rhs)
1963 {
1964 return !(lhs == rhs);
1965 }
1966
1967 //***************************************************************************
1969 //**************************************************************************
1970 template <typename T, typename U>
1971 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const U& lhs, const etl::optional<T>& rhs)
1972 {
1973 return rhs.has_value() ? rhs.value() == lhs : false;
1974 }
1975
1976 //***************************************************************************
1978 //**************************************************************************
1979 template <typename T, typename U>
1980 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const U& lhs, const etl::optional<T>& rhs)
1981 {
1982 return rhs.has_value() ? rhs.value() == lhs : false;
1983 }
1984
1985 //***************************************************************************
1987 //**************************************************************************
1988 template <typename T, typename U>
1989 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const U& lhs, const etl::optional<T>& rhs)
1990 {
1991 return !(lhs == rhs);
1992 }
1993
1994 //***************************************************************************
1996 //**************************************************************************
1997 template <typename T, typename U>
1998 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const U& lhs, const etl::optional<T>& rhs)
1999 {
2000 return !(lhs == rhs);
2001 }
2002
2003 //***************************************************************************
2005 //***************************************************************************
2006 template <typename T, typename U>
2007 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const U& rhs)
2008 {
2009 return lhs.has_value() ? lhs.value() < rhs : true;
2010 }
2011
2012 //***************************************************************************
2014 //***************************************************************************
2015 template <typename T, typename U>
2016 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const U& rhs)
2017 {
2018 return lhs.has_value() ? lhs.value() < rhs : true;
2019 }
2020
2021 //***************************************************************************
2023 //***************************************************************************
2024 template <typename T, typename U>
2025 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const U& lhs, const etl::optional<T>& rhs)
2026 {
2027 return rhs.has_value() ? lhs < rhs.value() : false;
2028 }
2029
2030 //***************************************************************************
2032 //***************************************************************************
2033 template <typename T, typename U>
2034 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const U& lhs, const etl::optional<T>& rhs)
2035 {
2036 return rhs.has_value() ? lhs < rhs.value() : false;
2037 }
2038
2039 //***************************************************************************
2041 //***************************************************************************
2042 template <typename T, typename U>
2043 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const U& rhs)
2044 {
2045 return lhs.has_value() ? lhs.value() <= rhs : true;
2046 }
2047
2048 //***************************************************************************
2050 //***************************************************************************
2051 template <typename T, typename U>
2052 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const U& rhs)
2053 {
2054 return lhs.has_value() ? lhs.value() <= rhs : true;
2055 }
2056
2057 //***************************************************************************
2059 //***************************************************************************
2060 template <typename T, typename U>
2061 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const U& lhs, const etl::optional<T>& rhs)
2062 {
2063 return rhs.has_value() ? lhs <= rhs.value() : false;
2064 }
2065
2066 //***************************************************************************
2068 //***************************************************************************
2069 template <typename T, typename U>
2070 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const U& lhs, const etl::optional<T>& rhs)
2071 {
2072 return rhs.has_value() ? lhs <= rhs.value() : false;
2073 }
2074
2075 //***************************************************************************
2077 //***************************************************************************
2078 template <typename T, typename U>
2079 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const U& rhs)
2080 {
2081 return lhs.has_value() ? lhs.value() > rhs : false;
2082 }
2083
2084 //***************************************************************************
2086 //***************************************************************************
2087 template <typename T, typename U>
2088 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const U& rhs)
2089 {
2090 return lhs.has_value() ? lhs.value() > rhs : false;
2091 }
2092
2093 //***************************************************************************
2095 //***************************************************************************
2096 template <typename T, typename U>
2097 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const U& lhs, const etl::optional<T>& rhs)
2098 {
2099 return rhs.has_value() ? lhs > rhs.value() : true;
2100 }
2101
2102 //***************************************************************************
2104 //***************************************************************************
2105 template <typename T, typename U>
2106 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const U& lhs, const etl::optional<T>& rhs)
2107 {
2108 return rhs.has_value() ? lhs > rhs.value() : true;
2109 }
2110
2111 //***************************************************************************
2113 //***************************************************************************
2114 template <typename T, typename U>
2115 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const U& rhs)
2116 {
2117 return lhs.has_value() ? lhs.value() >= rhs : false;
2118 }
2119
2120 //***************************************************************************
2122 //***************************************************************************
2123 template <typename T, typename U>
2124 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const U& rhs)
2125 {
2126 return lhs.has_value() ? lhs.value() >= rhs : false;
2127 }
2128
2129 //***************************************************************************
2131 //***************************************************************************
2132 template <typename T, typename U>
2133 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const U& lhs, const etl::optional<T>& rhs)
2134 {
2135 return rhs.has_value() ? lhs >= rhs.value() : true;
2136 }
2137
2138 //***************************************************************************
2140 //***************************************************************************
2141 template <typename T, typename U>
2142 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const U& lhs, const etl::optional<T>& rhs)
2143 {
2144 return rhs.has_value() ? lhs >= rhs.value() : true;
2145 }
2146
2147#include "private/diagnostic_pop.h"
2148
2149 //***************************************************************************
2151 //***************************************************************************
2152 template <typename T>
2154 {
2156 }
2157
2158 //***************************************************************************
2160 //***************************************************************************
2161#if ETL_CPP17_SUPPORTED
2162 template <typename T>
2163 optional(T) -> optional<T>;
2164#endif
2165}
2166
2167//*************************************************************************
2169//*************************************************************************
2170template <typename T>
2171ETL_CONSTEXPR20_STL void swap(etl::optional<T>& lhs, etl::optional<T>& rhs)
2172{
2173 lhs.swap(rhs);
2174}
2175
2176#undef ETL_OPTIONAL_ENABLE_CPP14
2177#undef ETL_OPTIONAL_ENABLE_CPP20_STL
2178
2179#undef ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL
2180#undef ETL_OPTIONAL_ENABLE_COMSTEXPR_BOOL_RETURN_CPP20_STL
2181
2182#endif
Definition optional.h:50
Definition optional.h:1227
optional(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:1287
optional(const T &value_)
Construct from value type.
Definition optional.h:1371
optional(const optional &other)
Copy constructor.
Definition optional.h:1318
optional & operator=(etl::nullopt_t)
Assignment operator from nullopt.
Definition optional.h:1428
ETL_CONSTEXPR20_STL const T & value() const ETL_LVALUE_REF_QUALIFIER
Get a const reference to the value.
Definition optional.h:392
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition optional.h:555
ETL_CONSTEXPR20_STL optional_impl()
Constructor.
Definition optional.h:122
ETL_CONSTEXPR20_STL optional_impl(const T &value_)
Constructor from value type.
Definition optional.h:168
ETL_CONSTEXPR20_STL void swap(optional_impl &other)
Swaps this value with another.
Definition optional.h:464
ETL_CONSTEXPR20_STL optional_impl(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:131
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition optional.h:574
T & emplace(const T1 &value1)
Definition optional.h:517
ETL_CONSTEXPR20_STL T value_or(const T &default_value) const ETL_LVALUE_REF_QUALIFIER
Gets the value or a default if not valid.
Definition optional.h:405
ETL_CONSTEXPR20_STL ~optional_impl()
Destructor.
Definition optional.h:188
ETL_CONSTEXPR20_STL optional_impl(const optional_impl< T > &other)
Copy constructor.
Definition optional.h:141
ETL_CONSTEXPR20_STL void reset()
Reset back to invalid.
Definition optional.h:475
T & emplace(const T1 &value1, const T2 &value2)
Definition optional.h:536
T & emplace()
Definition optional.h:498
ETL_CONSTEXPR20_STL T & value() ETL_LVALUE_REF_QUALIFIER
Get a reference to the value.
Definition optional.h:379
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition optional.h:1121
T & emplace()
Definition optional.h:1064
ETL_CONSTEXPR14 T & value() ETL_LVALUE_REF_QUALIFIER
Get a reference to the value.
Definition optional.h:945
ETL_CONSTEXPR14 optional_impl(const T &value_)
Constructor from value type.
Definition optional.h:743
ETL_CONSTEXPR14 T value_or(const T &default_value) const ETL_LVALUE_REF_QUALIFIER
Gets the value or a default if not valid.
Definition optional.h:971
ETL_CONSTEXPR14 optional_impl(const optional_impl< T > &other)
Copy constructor.
Definition optional.h:716
ETL_CONSTEXPR14 const T & value() const ETL_LVALUE_REF_QUALIFIER
Get a const reference to the value.
Definition optional.h:958
T & emplace(const T1 &value1, const T2 &value2)
Definition optional.h:1102
ETL_CONSTEXPR14 void reset()
Reset back to invalid.
Definition optional.h:1041
ETL_CONSTEXPR14 void swap(optional_impl &other)
Swaps this value with another.
Definition optional.h:1030
ETL_CONSTEXPR14 optional_impl(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:706
ETL_CONSTEXPR14 optional_impl()
Constructor.
Definition optional.h:697
T & emplace(const T1 &value1)
Definition optional.h:1083
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition optional.h:1140
Definition optional.h:106
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
Definition exception.h:47
Definition optional.h:77
Definition optional.h:91
T * construct_at(T *p)
Definition memory.h:977
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition memory.h:1027
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR20_STL etl::optional< typename etl::decay< T >::type > make_optional(T &value)
Make an optional.
Definition optional.h:2153
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:693
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:705
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:654
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:642
void destroy(const T *const p)
Destroys the object.
Definition variant_pool_generator.h:370
const nullopt_t nullopt
Definition optional.h:70
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:666
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:681
pair holds two objects of arbitrary type
Definition utility.h:164