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>
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 void emplace(TArgs&& ... args)
488 {
489 storage.construct(etl::forward<TArgs>(args)...);
490 }
491#else
492 //*************************************************************************
495 //*************************************************************************
497 {
498 if (has_value())
499 {
500 // Destroy the old one.
501 storage.destroy();
502 }
503
504 T* p = ::new (&storage.u.value) T();
505 storage.valid = true;
506
507 return *p;
508 }
509
510 //*************************************************************************
513 //*************************************************************************
514 template <typename T1>
515 T& emplace(const T1& value1)
516 {
517 if (has_value())
518 {
519 // Destroy the old one.
520 storage.destroy();
521 }
522
523 T* p = ::new (&storage.u.value) T(value1);
524 storage.valid = true;
525
526 return *p;
527 }
528
529 //*************************************************************************
532 //*************************************************************************
533 template <typename T1, typename T2>
534 T& emplace(const T1& value1, const T2& value2)
535 {
536 if (has_value())
537 {
538 // Destroy the old one.
539 storage.destroy();
540 }
541
542 T* p = ::new (&storage.u.value) T(value1, value2);
543 storage.valid = true;
544
545 return *p;
546 }
547
548 //*************************************************************************
551 //*************************************************************************
552 template <typename T1, typename T2, typename T3>
553 T& emplace(const T1& value1, const T2& value2, const T3& value3)
554 {
555 if (has_value())
556 {
557 // Destroy the old one.
558 storage.destroy();
559 }
560
561 T* p = ::new (&storage.u.value) T(value1, value2, value3);
562 storage.valid = true;
563
564 return *p;
565 }
566
567 //*************************************************************************
570 //*************************************************************************
571 template <typename T1, typename T2, typename T3, typename T4>
572 T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
573 {
574 if (has_value())
575 {
576 // Destroy the old one.
577 storage.destroy();
578 }
579
580 T* p = ::new (&storage.u.value) T(value1, value2, value3, value4);
581 storage.valid = true;
582
583 return *p;
584 }
585#endif
586
587 private:
588
589 struct dummy_t {};
590
591 //*************************************
592 // The storage for the optional value.
593 //*************************************
594 struct storage_type
595 {
596 //*******************************
597 ETL_CONSTEXPR20_STL
598 storage_type()
599 : u()
600 , valid(false)
601 {
602 }
603
604 //*******************************
605 ETL_CONSTEXPR20_STL
606 void construct(const T& value_)
607 {
608 if (valid)
609 {
610 etl::destroy_at(&u.value);
611 }
612
613 etl::construct_at(&u.value, value_);
614 valid = true;
615 }
616
617#if ETL_USING_CPP11
618 //*******************************
619 ETL_CONSTEXPR20_STL
620 void construct(T&& value_)
621 {
622 if (valid)
623 {
624 etl::destroy_at(&u.value);
625 }
626
627 etl::construct_at(&u.value, etl::move(value_));
628 valid = true;
629 }
630
631 //*******************************
632 template <typename... TArgs>
633 ETL_CONSTEXPR20_STL
634 void construct(TArgs&&... args)
635 {
636 if (valid)
637 {
638 etl::destroy_at(&u.value);
639 }
640
641 etl::construct_at(&u.value, etl::forward<TArgs>(args)...);
642 valid = true;
643 }
644#endif
645
646 //*******************************
647 ETL_CONSTEXPR20_STL
648 void destroy()
649 {
650 if (valid)
651 {
652 etl::destroy_at(&u.value);
653 valid = false;
654 }
655 }
656
657 //*******************************
658 union union_type
659 {
660 ETL_CONSTEXPR20_STL
661 union_type()
662 : dummy()
663 {
664 }
665
666 ETL_CONSTEXPR20_STL
667 ~union_type()
668 {
669 }
670
671 dummy_t dummy;
672 T value;
673 } u;
674
675 bool valid;
676 };
677
678 storage_type storage;
679 };
680
681 //*****************************************************************************
682 // Implementation for fundamental types.
683 //*****************************************************************************
684 template <typename T>
686 {
687 protected:
688
689 typedef T value_type;
690
691 //***************************************************************************
693 //***************************************************************************
694 ETL_CONSTEXPR14
696 : storage()
697 {
698 }
699
700 //***************************************************************************
702 //***************************************************************************
703 ETL_CONSTEXPR14
705 : storage()
706 {
707 }
708
710 //***************************************************************************
712 //***************************************************************************
713 ETL_CONSTEXPR14
715 {
716 if (other.has_value())
717 {
718 storage.construct(other.value());
719 }
720 }
722
723#if ETL_USING_CPP11
724 //***************************************************************************
726 //***************************************************************************
727 ETL_CONSTEXPR14
729 {
730 if (other.has_value())
731 {
732 storage.construct(etl::move(other.value()));
733 }
734 }
735#endif
736
737 //***************************************************************************
739 //***************************************************************************
740 ETL_CONSTEXPR14
742 {
743 storage.construct(value_);
744 }
745
746#if ETL_USING_CPP11
747 //***************************************************************************
749 //***************************************************************************
750 ETL_CONSTEXPR14
752 {
753 storage.construct(etl::move(value_));
754 }
755#endif
756
757 //***************************************************************************
759 //***************************************************************************
760 ETL_CONSTEXPR14
762 {
763 if (has_value())
764 {
765 storage.destroy();
766 }
767
768 return *this;
769 }
770
771 //***************************************************************************
773 //***************************************************************************
774 ETL_CONSTEXPR14
776 {
777 if (this != &other)
778 {
779 if (other.has_value())
780 {
781 storage.construct(other.value());
782 }
783 else
784 {
785 storage.destroy();
786 }
787 }
788
789 return *this;
790 }
791
792#if ETL_USING_CPP11
793 //***************************************************************************
795 //***************************************************************************
796 ETL_CONSTEXPR14
798 {
799 if (this != &other)
800 {
801 if (other.has_value())
802 {
803 storage.construct(etl::move(other.value()));
804 }
805 else
806 {
807 storage.destroy();
808 }
809 }
810
811 return *this;
812 }
813#endif
814
815 //***************************************************************************
817 //***************************************************************************
818 ETL_CONSTEXPR14
820 {
821 storage.construct(value_);
822
823 return *this;
824 }
825
826#if ETL_USING_CPP11
827 //***************************************************************************
829 //***************************************************************************
830 ETL_CONSTEXPR14
832 {
833 storage.construct(etl::move(value_));
834
835 return *this;
836 }
837#endif
838
839 public:
840
841 //***************************************************************************
843 //***************************************************************************
844 ETL_CONSTEXPR14
846 {
847#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
848 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
849#endif
850
851 return &storage.value;
852 }
853
854 //***************************************************************************
856 //***************************************************************************
857 ETL_CONSTEXPR14
858 const T* operator ->() const
859 {
860#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
861 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
862#endif
863
864 return &storage.value;
865 }
866
867 //***************************************************************************
869 //***************************************************************************
870 ETL_CONSTEXPR14
871 T& operator *() ETL_LVALUE_REF_QUALIFIER
872 {
873#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
874 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
875#endif
876
877 return storage.value;
878 }
879
880 //***************************************************************************
882 //***************************************************************************
883 ETL_CONSTEXPR14
884 const T& operator *() const ETL_LVALUE_REF_QUALIFIER
885 {
886#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
887 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
888#endif
889
890 return storage.value;
891 }
892
893#if ETL_USING_CPP11
894 //***************************************************************************
896 //***************************************************************************
897 ETL_CONSTEXPR14
898 T&& operator *()&&
899 {
900#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
901 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
902#endif
903
904 return etl::move(storage.value);
905 }
906
907 //***************************************************************************
909 //***************************************************************************
910 ETL_CONSTEXPR14
911 const T&& operator *() const&&
912 {
913#if ETL_IS_DEBUG_BUILD && !(ETL_USING_CPP20 && ETL_USING_STL)
914 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
915#endif
916
917 return etl::move(storage.value);
918 }
919#endif
920
921 //***************************************************************************
922 // Check whether optional contains value
923 //***************************************************************************
924 ETL_CONSTEXPR14
925 bool has_value() const ETL_NOEXCEPT
926 {
927 return storage.valid;
928 }
929
930 //***************************************************************************
932 //***************************************************************************
933 ETL_CONSTEXPR14
934 ETL_EXPLICIT operator bool() const
935 {
936 return has_value();
937 }
938
939 //***************************************************************************
941 //***************************************************************************
942 ETL_CONSTEXPR14
943 T& value() ETL_LVALUE_REF_QUALIFIER
944 {
945#if ETL_IS_DEBUG_BUILD
946 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
947#endif
948
949 return storage.value;
950 }
951
952 //***************************************************************************
954 //***************************************************************************
955 ETL_CONSTEXPR14
956 const T& value() const ETL_LVALUE_REF_QUALIFIER
957 {
958#if ETL_IS_DEBUG_BUILD
959 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
960#endif
961
962 return storage.value;
963 }
964
965 //***************************************************************************
967 //***************************************************************************
968 ETL_CONSTEXPR14
969 T value_or(const T& default_value) const ETL_LVALUE_REF_QUALIFIER
970 {
971 return has_value() ? value() : default_value;
972 }
973
974#if ETL_USING_CPP11
975 //***************************************************************************
977 //***************************************************************************
978 ETL_CONSTEXPR14
979 T&& value()&&
980 {
981#if ETL_IS_DEBUG_BUILD
982 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
983#endif
984
985 return etl::move(storage.value);
986 }
987
988 //***************************************************************************
990 //***************************************************************************
991 ETL_CONSTEXPR14
992 const T&& value() const&&
993 {
994#if ETL_IS_DEBUG_BUILD
995 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
996#endif
997
998 return etl::move(storage.value);
999 }
1000
1001 //***************************************************************************
1003 //***************************************************************************
1004 template <typename U>
1005 ETL_CONSTEXPR14
1007 value_or(U&& default_value) const&
1008 {
1009 return has_value() ? value() : etl::forward<T>(default_value);
1010 }
1011
1012 //***************************************************************************
1014 //***************************************************************************
1015 template <typename U>
1016 ETL_CONSTEXPR14
1018 value_or(U&& default_value)&&
1019 {
1020 return has_value() ? etl::move(value()) : etl::forward<T>(default_value);
1021 }
1022#endif
1023
1024 //***************************************************************************
1026 //***************************************************************************
1027 ETL_CONSTEXPR14
1029 {
1030 optional_impl temp(*this);
1031 *this = other;
1032 other = temp;
1033 }
1034
1035 //***************************************************************************
1037 //***************************************************************************
1038 ETL_CONSTEXPR14
1039 void reset()
1040 {
1041 storage.destroy();
1042 }
1043
1044#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
1045 //*************************************************************************
1048 //*************************************************************************
1049 template <typename... TArgs>
1050 ETL_CONSTEXPR14
1051 void emplace(TArgs&& ... args)
1052 {
1053 storage.construct(etl::forward<TArgs>(args)...);
1054 }
1055#else
1056 //*************************************************************************
1059 //*************************************************************************
1061 {
1062 if (has_value())
1063 {
1064 // Destroy the old one.
1065 storage.destroy();
1066 }
1067
1068 T* p = ::new (&storage.value) T();
1069 storage.valid = true;
1070
1071 return *p;
1072 }
1073
1074 //*************************************************************************
1077 //*************************************************************************
1078 template <typename T1>
1079 T& emplace(const T1& value1)
1080 {
1081 if (has_value())
1082 {
1083 // Destroy the old one.
1084 storage.destroy();
1085 }
1086
1087 T* p = ::new (&storage.value) T(value1);
1088 storage.valid = true;
1089
1090 return *p;
1091 }
1092
1093 //*************************************************************************
1096 //*************************************************************************
1097 template <typename T1, typename T2>
1098 T& emplace(const T1& value1, const T2& value2)
1099 {
1100 if (has_value())
1101 {
1102 // Destroy the old one.
1103 storage.destroy();
1104 }
1105
1106 T* p = ::new (&storage.value) T(value1, value2);
1107 storage.valid = true;
1108
1109 return *p;
1110 }
1111
1112 //*************************************************************************
1115 //*************************************************************************
1116 template <typename T1, typename T2, typename T3>
1117 T& emplace(const T1& value1, const T2& value2, const T3& value3)
1118 {
1119 if (has_value())
1120 {
1121 // Destroy the old one.
1122 storage.destroy();
1123 }
1124
1125 T* p = ::new (&storage.value) T(value1, value2, value3);
1126 storage.valid = true;
1127
1128 return *p;
1129 }
1130
1131 //*************************************************************************
1134 //*************************************************************************
1135 template <typename T1, typename T2, typename T3, typename T4>
1136 T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1137 {
1138 if (has_value())
1139 {
1140 // Destroy the old one.
1141 storage.destroy();
1142 }
1143
1144 T* p = ::new (&storage.value) T(value1, value2, value3, value4);
1145 storage.valid = true;
1146
1147 return *p;
1148 }
1149#endif
1150
1151 private:
1152
1153 //*************************************
1154 // The storage for the optional value.
1155 //*************************************
1156 struct storage_type
1157 {
1158 //*******************************
1159 ETL_CONSTEXPR14
1160 storage_type()
1161 : value()
1162 , valid(false)
1163 {
1164 }
1165
1166 //*******************************
1167 ETL_CONSTEXPR14
1168 void construct(const T& value_)
1169 {
1170 value = value_;
1171 valid = true;
1172 }
1173
1174#if ETL_USING_CPP11
1175 //*******************************
1176 ETL_CONSTEXPR14
1177 void construct(T&& value_)
1178 {
1179 value = value_;
1180 valid = true;
1181 }
1182
1183 //*******************************
1184 template <typename... TArgs>
1185 ETL_CONSTEXPR14
1186 void construct(TArgs&&... args)
1187 {
1188 value = T(etl::forward<TArgs>(args)...);
1189 valid = true;
1190 }
1191#endif
1192
1193 //*******************************
1194 ETL_CONSTEXPR14
1195 void destroy()
1196 {
1197 valid = false;
1198 }
1199
1200 T value;
1201 bool valid;
1202 };
1203
1204 storage_type storage;
1205 };
1206 }
1207
1208#define ETL_OPTIONAL_ENABLE_CPP14 typename etl::enable_if< etl::is_pod<U>::value, int>::type = 0
1209#define ETL_OPTIONAL_ENABLE_CPP20_STL typename etl::enable_if<!etl::is_pod<U>::value, int>::type = 0
1210
1211#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 ETL_CONSTEXPR14 typename etl::enable_if< etl::is_pod<T>::value, bool>::type
1212#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL ETL_CONSTEXPR20_STL typename etl::enable_if<!etl::is_pod<T>::value, bool>::type
1213
1214 //*****************************************************************************
1220 //*****************************************************************************
1221 template <typename T>
1223 {
1224 private:
1225
1227
1228 public:
1229
1230 typedef T value_type;
1231
1232#if ETL_USING_CPP11
1233 //***************************************************************************
1235 //***************************************************************************
1236 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1237 ETL_CONSTEXPR14
1238 optional()
1239 : impl_t()
1240 {
1241 }
1242
1243 //***************************************************************************
1245 //***************************************************************************
1246 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1247 ETL_CONSTEXPR20_STL
1248 optional()
1249 : impl_t()
1250 {
1251 }
1252#else
1253 optional()
1254 : impl_t()
1255 {
1256 }
1257#endif
1258
1259#if ETL_USING_CPP11
1260 //***************************************************************************
1262 //***************************************************************************
1263 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1264 ETL_CONSTEXPR14
1267 {
1268 }
1269
1270 //***************************************************************************
1272 //***************************************************************************
1273 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1274 ETL_CONSTEXPR20_STL
1277 {
1278 }
1279#else
1280 //***************************************************************************
1282 //***************************************************************************
1284 : impl_t(etl::nullopt)
1285 {
1286 }
1287#endif
1288
1290#if ETL_USING_CPP11
1291 //***************************************************************************
1293 //***************************************************************************
1294 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1295 ETL_CONSTEXPR14
1296 optional(const optional& other)
1297 : impl_t(other)
1298 {
1299 }
1300
1301 //***************************************************************************
1303 //***************************************************************************
1304 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1305 ETL_CONSTEXPR20_STL
1306 optional(const optional& other)
1307 : impl_t(other)
1308 {
1309 }
1310#else
1311 //***************************************************************************
1313 //***************************************************************************
1315 : impl_t(other)
1316 {
1317 }
1318#endif
1319#include "private/diagnostic_pop.h"
1320
1321#if ETL_USING_CPP11
1322 //***************************************************************************
1324 //***************************************************************************
1325 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1326 ETL_CONSTEXPR14
1328 : impl_t(other)
1329 {
1330 }
1331
1332 //***************************************************************************
1334 //***************************************************************************
1335 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1336 ETL_CONSTEXPR20_STL
1337 optional(optional&& other)
1338 : impl_t(other)
1339 {
1340 }
1341#endif
1342
1343#if ETL_USING_CPP11
1344 //***************************************************************************
1346 //***************************************************************************
1347 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1348 ETL_CONSTEXPR14
1349 optional(const T& value_)
1350 : impl_t(value_)
1351 {
1352 }
1353
1354 //***************************************************************************
1356 //***************************************************************************
1357 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1358 ETL_CONSTEXPR20_STL
1359 optional(const T& value_)
1360 : impl_t(value_)
1361 {
1362 }
1363#else
1364 //***************************************************************************
1366 //***************************************************************************
1368 : impl_t(value_)
1369 {
1370 }
1371#endif
1372
1373
1374#if ETL_USING_CPP11
1375 //***************************************************************************
1377 //***************************************************************************
1378 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1379 ETL_CONSTEXPR14
1380 optional(T&& value_)
1381 : impl_t(etl::move(value_))
1382 {
1383 }
1384
1385 //***************************************************************************
1387 //***************************************************************************
1388 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1389 ETL_CONSTEXPR20_STL
1390 optional(T&& value_)
1391 : impl_t(etl::move(value_))
1392 {
1393 }
1394#endif
1395
1396#if ETL_USING_CPP11
1397 //***************************************************************************
1399 //***************************************************************************
1400 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1401 ETL_CONSTEXPR14
1402 optional& operator =(etl::nullopt_t)
1403 {
1404 impl_t::operator=(etl::nullopt);
1405
1406 return *this;
1407 }
1408
1409 //***************************************************************************
1411 //***************************************************************************
1412 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1413 ETL_CONSTEXPR20_STL
1414 optional& operator =(etl::nullopt_t)
1415 {
1416 impl_t::operator=(etl::nullopt);
1417
1418 return *this;
1419 }
1420#else
1421 //***************************************************************************
1423 //***************************************************************************
1425 {
1426 impl_t::operator=(etl::nullopt);
1427
1428 return *this;
1429 }
1430#endif
1431
1432#if ETL_USING_CPP11
1433 //***************************************************************************
1435 //***************************************************************************
1436 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1437 ETL_CONSTEXPR14
1439 {
1440 impl_t::operator=(other);
1441
1442 return *this;
1443 }
1444
1445 //***************************************************************************
1447 //***************************************************************************
1448 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1449 ETL_CONSTEXPR20_STL
1450 optional& operator =(const optional& other)
1451 {
1452 impl_t::operator=(other);
1453
1454 return *this;
1455 }
1456#else
1457 //***************************************************************************
1459 //***************************************************************************
1461 {
1462 impl_t::operator=(other);
1463
1464 return *this;
1465 }
1466#endif
1467
1468#if ETL_USING_CPP11
1469 //***************************************************************************
1471 //***************************************************************************
1472 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1473 ETL_CONSTEXPR14
1475 {
1476 impl_t::operator=(etl::move(other));
1477
1478 return *this;
1479 }
1480
1481 //***************************************************************************
1483 //***************************************************************************
1484 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1485 ETL_CONSTEXPR20_STL
1486 optional& operator =(optional&& other)
1487 {
1488 impl_t::operator=(etl::move(other));
1489
1490 return *this;
1491 }
1492#endif
1493
1494#if ETL_USING_CPP11
1495 //***************************************************************************
1497 //***************************************************************************
1498 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1499 ETL_CONSTEXPR14
1500 optional& operator =(const T& value_)
1501 {
1502 impl_t::operator=(value_);
1503
1504 return *this;
1505 }
1506
1507 //***************************************************************************
1509 //***************************************************************************
1510 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1511 ETL_CONSTEXPR20_STL
1512 optional& operator =(const T& value_)
1513 {
1514 impl_t::operator=(value_);
1515
1516 return *this;
1517 }
1518#else
1519 //***************************************************************************
1521 //***************************************************************************
1523 {
1524 impl_t::operator=(value_);
1525
1526 return *this;
1527 }
1528#endif
1529
1530#if ETL_USING_CPP11
1531 //***************************************************************************
1533 //***************************************************************************
1534 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1535 ETL_CONSTEXPR14
1537 {
1538 impl_t::operator=(etl::move(value_));
1539
1540 return *this;
1541 }
1542
1543 //***************************************************************************
1545 //***************************************************************************
1546 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1547 ETL_CONSTEXPR20_STL
1548 optional& operator =(T&& value_)
1549 {
1550 impl_t::operator=(etl::move(value_));
1551
1552 return *this;
1553 }
1554#endif
1555 };
1556
1558
1559 //***************************************************************************
1561 //***************************************************************************
1562 template <typename T>
1563 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1564 {
1565 if (lhs.has_value() != rhs.has_value())
1566 {
1567 return false;
1568 }
1569 else if (!lhs.has_value() && !rhs.has_value())
1570 {
1571 return true;
1572 }
1573 else
1574 {
1575 return lhs.value() == rhs.value();
1576 }
1577 }
1578
1579 //***************************************************************************
1581 //***************************************************************************
1582 template <typename T>
1583 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1584 {
1585 if (lhs.has_value() != rhs.has_value())
1586 {
1587 return false;
1588 }
1589 else if (!lhs.has_value() && !rhs.has_value())
1590 {
1591 return true;
1592 }
1593 else
1594 {
1595 return lhs.value() == rhs.value();
1596 }
1597 }
1598
1599 //***************************************************************************
1601 //***************************************************************************
1602 template <typename T>
1603 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1604 {
1605 return !(lhs == rhs);
1606 }
1607
1608 //***************************************************************************
1610 //***************************************************************************
1611 template <typename T>
1612 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1613 {
1614 return !(lhs == rhs);
1615 }
1616
1617 //***************************************************************************
1619 //***************************************************************************
1620 template <typename T>
1621 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1622 {
1623 if (!rhs.has_value())
1624 {
1625 return false;
1626 }
1627 else if (!lhs.has_value())
1628 {
1629 return true;
1630 }
1631 else
1632 {
1633 return lhs.value() < rhs.value();
1634 }
1635 }
1636
1637 //***************************************************************************
1639 //***************************************************************************
1640 template <typename T>
1641 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1642 {
1643 if (!rhs.has_value())
1644 {
1645 return false;
1646 }
1647 else if (!lhs.has_value())
1648 {
1649 return true;
1650 }
1651 else
1652 {
1653 return lhs.value() < rhs.value();
1654 }
1655 }
1656
1657 //***************************************************************************
1659 //***************************************************************************
1660 template <typename T>
1661 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1662 {
1663 return !(rhs < lhs);
1664 }
1665
1666 //***************************************************************************
1668 //***************************************************************************
1669 template <typename T>
1670 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1671 {
1672 return !(rhs < lhs);
1673 }
1674
1675 //***************************************************************************
1677 //***************************************************************************
1678 template <typename T>
1679 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1680 {
1681 return (rhs < lhs);
1682 }
1683
1684 //***************************************************************************
1686 //***************************************************************************
1687 template <typename T>
1688 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1689 {
1690 return (rhs < lhs);
1691 }
1692
1693 //***************************************************************************
1695 //***************************************************************************
1696 template <typename T>
1697 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1698 {
1699 return !(lhs < rhs);
1700 }
1701
1702 //***************************************************************************
1704 //***************************************************************************
1705 template <typename T>
1706 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1707 {
1708 return !(lhs < rhs);
1709 }
1710
1711 //***************************************************************************
1713 //***************************************************************************
1714 template <typename T>
1715 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
1716 {
1717 return !lhs.has_value();
1718 }
1719
1720 //***************************************************************************
1722 //***************************************************************************
1723 template <typename T>
1724 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
1725 {
1726 return !lhs.has_value();
1727 }
1728
1729 //***************************************************************************
1731 //***************************************************************************
1732 template <typename T>
1733 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
1734 {
1735 return !rhs.has_value();
1736 }
1737
1738 //***************************************************************************
1740 //***************************************************************************
1741 template <typename T>
1742 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
1743 {
1744 return !rhs.has_value();
1745 }
1746
1747 //***************************************************************************
1749 //***************************************************************************
1750 template <typename T>
1751 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
1752 {
1753 return !(lhs == etl::nullopt);
1754 }
1755
1756 //***************************************************************************
1758 //***************************************************************************
1759 template <typename T>
1760 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
1761 {
1762 return !(lhs == etl::nullopt);
1763 }
1764
1765 //***************************************************************************
1767 //***************************************************************************
1768 template <typename T>
1769 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(etl::nullopt_t , const etl::optional<T>& rhs)
1770 {
1771 return !(etl::nullopt == rhs);
1772 }
1773
1774 //***************************************************************************
1776 //***************************************************************************
1777 template <typename T>
1778 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(etl::nullopt_t, const etl::optional<T>& rhs)
1779 {
1780 return !(etl::nullopt == rhs);
1781 }
1782
1783 //***************************************************************************
1785 //***************************************************************************
1786 template <typename T>
1787 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>&, etl::nullopt_t)
1788 {
1789 return false;
1790 }
1791
1792 //***************************************************************************
1794 //***************************************************************************
1795 template <typename T>
1796 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>&, etl::nullopt_t)
1797 {
1798 return false;
1799 }
1800
1801 //***************************************************************************
1803 //***************************************************************************
1804 template <typename T>
1805 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(etl::nullopt_t, const etl::optional<T>& rhs)
1806 {
1807 return rhs.has_value();
1808 }
1809
1810 //***************************************************************************
1812 //***************************************************************************
1813 template <typename T>
1814 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(etl::nullopt_t, const etl::optional<T>& rhs)
1815 {
1816 return rhs.has_value();
1817 }
1818
1819 //***************************************************************************
1821 //***************************************************************************
1822 template <typename T>
1823 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
1824 {
1825 return !lhs.has_value();
1826 }
1827
1828 //***************************************************************************
1830 //***************************************************************************
1831 template <typename T>
1832 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
1833 {
1834 return !lhs.has_value();
1835 }
1836
1837 //***************************************************************************
1839 //***************************************************************************
1840 template <typename T>
1841 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(etl::nullopt_t, const etl::optional<T>&)
1842 {
1843 return true;
1844 }
1845
1846 //***************************************************************************
1848 //***************************************************************************
1849 template <typename T>
1850 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(etl::nullopt_t, const etl::optional<T>&)
1851 {
1852 return true;
1853 }
1854
1855 //***************************************************************************
1857 //***************************************************************************
1858 template <typename T>
1859 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, etl::nullopt_t)
1860 {
1861 return lhs.has_value();
1862 }
1863
1864 //***************************************************************************
1866 //***************************************************************************
1867 template <typename T>
1868 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, etl::nullopt_t)
1869 {
1870 return lhs.has_value();
1871 }
1872
1873 //***************************************************************************
1875 //***************************************************************************
1876 template <typename T>
1877 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(etl::nullopt_t, const etl::optional<T>&)
1878 {
1879 return false;
1880 }
1881
1882 //***************************************************************************
1884 //***************************************************************************
1885 template <typename T>
1886 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(etl::nullopt_t, const etl::optional<T>&)
1887 {
1888 return false;
1889 }
1890
1891 //***************************************************************************
1893 //***************************************************************************
1894 template <typename T>
1895 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>&, etl::nullopt_t)
1896 {
1897 return true;
1898 }
1899
1900 //***************************************************************************
1902 //***************************************************************************
1903 template <typename T>
1904 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>&, etl::nullopt_t)
1905 {
1906 return true;
1907 }
1908
1909 //***************************************************************************
1911 //***************************************************************************
1912 template <typename T>
1913 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
1914 {
1915 return !rhs.has_value();
1916 }
1917
1918 //***************************************************************************
1920 //***************************************************************************
1921 template <typename T>
1922 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
1923 {
1924 return !rhs.has_value();
1925 }
1926
1927 //***************************************************************************
1929 //**************************************************************************
1930 template <typename T, typename U>
1931 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const U& rhs)
1932 {
1933 return lhs.has_value() ? lhs.value() == rhs : false;
1934 }
1935
1936 //***************************************************************************
1938 //**************************************************************************
1939 template <typename T, typename U>
1940 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const U& rhs)
1941 {
1942 return lhs.has_value() ? lhs.value() == rhs : false;
1943 }
1944
1945 //***************************************************************************
1947 //**************************************************************************
1948 template <typename T, typename U>
1949 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const U& rhs)
1950 {
1951 return !(lhs == rhs);
1952 }
1953
1954 //***************************************************************************
1956 //**************************************************************************
1957 template <typename T, typename U>
1958 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const U& rhs)
1959 {
1960 return !(lhs == rhs);
1961 }
1962
1963 //***************************************************************************
1965 //**************************************************************************
1966 template <typename T, typename U>
1967 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const U& lhs, const etl::optional<T>& rhs)
1968 {
1969 return rhs.has_value() ? rhs.value() == lhs : false;
1970 }
1971
1972 //***************************************************************************
1974 //**************************************************************************
1975 template <typename T, typename U>
1976 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const U& lhs, const etl::optional<T>& rhs)
1977 {
1978 return rhs.has_value() ? rhs.value() == lhs : false;
1979 }
1980
1981 //***************************************************************************
1983 //**************************************************************************
1984 template <typename T, typename U>
1985 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const U& lhs, const etl::optional<T>& rhs)
1986 {
1987 return !(lhs == rhs);
1988 }
1989
1990 //***************************************************************************
1992 //**************************************************************************
1993 template <typename T, typename U>
1994 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const U& lhs, const etl::optional<T>& rhs)
1995 {
1996 return !(lhs == rhs);
1997 }
1998
1999 //***************************************************************************
2001 //***************************************************************************
2002 template <typename T, typename U>
2003 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const U& rhs)
2004 {
2005 return lhs.has_value() ? lhs.value() < rhs : true;
2006 }
2007
2008 //***************************************************************************
2010 //***************************************************************************
2011 template <typename T, typename U>
2012 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const U& rhs)
2013 {
2014 return lhs.has_value() ? lhs.value() < rhs : true;
2015 }
2016
2017 //***************************************************************************
2019 //***************************************************************************
2020 template <typename T, typename U>
2021 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const U& lhs, const etl::optional<T>& rhs)
2022 {
2023 return rhs.has_value() ? lhs < rhs.value() : false;
2024 }
2025
2026 //***************************************************************************
2028 //***************************************************************************
2029 template <typename T, typename U>
2030 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const U& lhs, const etl::optional<T>& rhs)
2031 {
2032 return rhs.has_value() ? lhs < rhs.value() : false;
2033 }
2034
2035 //***************************************************************************
2037 //***************************************************************************
2038 template <typename T, typename U>
2039 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const U& rhs)
2040 {
2041 return lhs.has_value() ? lhs.value() <= rhs : true;
2042 }
2043
2044 //***************************************************************************
2046 //***************************************************************************
2047 template <typename T, typename U>
2048 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const U& rhs)
2049 {
2050 return lhs.has_value() ? lhs.value() <= rhs : true;
2051 }
2052
2053 //***************************************************************************
2055 //***************************************************************************
2056 template <typename T, typename U>
2057 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const U& lhs, const etl::optional<T>& rhs)
2058 {
2059 return rhs.has_value() ? lhs <= rhs.value() : false;
2060 }
2061
2062 //***************************************************************************
2064 //***************************************************************************
2065 template <typename T, typename U>
2066 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const U& lhs, const etl::optional<T>& rhs)
2067 {
2068 return rhs.has_value() ? lhs <= rhs.value() : false;
2069 }
2070
2071 //***************************************************************************
2073 //***************************************************************************
2074 template <typename T, typename U>
2075 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const U& rhs)
2076 {
2077 return lhs.has_value() ? lhs.value() > rhs : false;
2078 }
2079
2080 //***************************************************************************
2082 //***************************************************************************
2083 template <typename T, typename U>
2084 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const U& rhs)
2085 {
2086 return lhs.has_value() ? lhs.value() > rhs : false;
2087 }
2088
2089 //***************************************************************************
2091 //***************************************************************************
2092 template <typename T, typename U>
2093 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const U& lhs, const etl::optional<T>& rhs)
2094 {
2095 return rhs.has_value() ? lhs > rhs.value() : true;
2096 }
2097
2098 //***************************************************************************
2100 //***************************************************************************
2101 template <typename T, typename U>
2102 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const U& lhs, const etl::optional<T>& rhs)
2103 {
2104 return rhs.has_value() ? lhs > rhs.value() : true;
2105 }
2106
2107 //***************************************************************************
2109 //***************************************************************************
2110 template <typename T, typename U>
2111 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const U& rhs)
2112 {
2113 return lhs.has_value() ? lhs.value() >= rhs : false;
2114 }
2115
2116 //***************************************************************************
2118 //***************************************************************************
2119 template <typename T, typename U>
2120 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const U& rhs)
2121 {
2122 return lhs.has_value() ? lhs.value() >= rhs : false;
2123 }
2124
2125 //***************************************************************************
2127 //***************************************************************************
2128 template <typename T, typename U>
2129 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const U& lhs, const etl::optional<T>& rhs)
2130 {
2131 return rhs.has_value() ? lhs >= rhs.value() : true;
2132 }
2133
2134 //***************************************************************************
2136 //***************************************************************************
2137 template <typename T, typename U>
2138 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const U& lhs, const etl::optional<T>& rhs)
2139 {
2140 return rhs.has_value() ? lhs >= rhs.value() : true;
2141 }
2142
2143#include "private/diagnostic_pop.h"
2144
2145 //***************************************************************************
2147 //***************************************************************************
2148 template <typename T>
2150 {
2152 }
2153
2154 //***************************************************************************
2156 //***************************************************************************
2157#if ETL_CPP17_SUPPORTED
2158 template <typename T>
2159 optional(T) -> optional<T>;
2160#endif
2161}
2162
2163//*************************************************************************
2165//*************************************************************************
2166template <typename T>
2167ETL_CONSTEXPR20_STL void swap(etl::optional<T>& lhs, etl::optional<T>& rhs)
2168{
2169 lhs.swap(rhs);
2170}
2171
2172#undef ETL_OPTIONAL_ENABLE_CPP14
2173#undef ETL_OPTIONAL_ENABLE_CPP20_STL
2174
2175#undef ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL
2176#undef ETL_OPTIONAL_ENABLE_COMSTEXPR_BOOL_RETURN_CPP20_STL
2177
2178#endif
Definition optional.h:50
Definition optional.h:1223
optional(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:1283
optional(const T &value_)
Construct from value type.
Definition optional.h:1367
optional(const optional &other)
Copy constructor.
Definition optional.h:1314
optional & operator=(etl::nullopt_t)
Assignment operator from nullopt.
Definition optional.h:1424
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:553
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:572
T & emplace(const T1 &value1)
Definition optional.h:515
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:534
T & emplace()
Definition optional.h:496
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:1117
T & emplace()
Definition optional.h:1060
ETL_CONSTEXPR14 T & value() ETL_LVALUE_REF_QUALIFIER
Get a reference to the value.
Definition optional.h:943
ETL_CONSTEXPR14 optional_impl(const T &value_)
Constructor from value type.
Definition optional.h:741
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:969
ETL_CONSTEXPR14 optional_impl(const optional_impl< T > &other)
Copy constructor.
Definition optional.h:714
ETL_CONSTEXPR14 const T & value() const ETL_LVALUE_REF_QUALIFIER
Get a const reference to the value.
Definition optional.h:956
T & emplace(const T1 &value1, const T2 &value2)
Definition optional.h:1098
ETL_CONSTEXPR14 void reset()
Reset back to invalid.
Definition optional.h:1039
ETL_CONSTEXPR14 void swap(optional_impl &other)
Swaps this value with another.
Definition optional.h:1028
ETL_CONSTEXPR14 optional_impl(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:704
ETL_CONSTEXPR14 optional_impl()
Constructor.
Definition optional.h:695
T & emplace(const T1 &value1)
Definition optional.h:1079
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition optional.h:1136
Definition optional.h:106
#define ETL_ASSERT(b, e)
Definition error_handler.h:316
Definition exception.h:47
Definition optional.h:77
Definition optional.h:91
T * construct_at(T *p)
Definition memory.h:956
etl::enable_if< etl::is_trivially_destructible< T >::value, void >::type destroy_at(T *)
Definition memory.h:1006
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:2149
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