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#include "initializer_list.h"
43
44namespace etl
45{
46 //*****************************************************************************
47 // Forward declaration of etl::optional
48 //*****************************************************************************
49 template <typename T>
50 class optional;
51
52 //*****************************************************************************
55 //*****************************************************************************
57 {
58 public:
59
60 // Convertible to any type of null non-member pointer.
61 template<class T>
62 operator T*() const
63 {
64 return 0;
65 }
66
67 private:
68
69 // Can't take address of nullopt.
70 void operator&() const ETL_DELETE;
71 };
72
73 //*****************************************************************************
76 //*****************************************************************************
77 const nullopt_t nullopt = {};
78
79 //***************************************************************************
82 //***************************************************************************
83 class optional_exception : public exception
84 {
85 public:
86
87 optional_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
88 : exception(reason_, file_name_, line_number_)
89 {
90 }
91 };
92
93 //***************************************************************************
96 //***************************************************************************
97 class optional_invalid : public optional_exception
98 {
99 public:
100
101 optional_invalid(string_type file_name_, numeric_type line_number_)
102 : optional_exception("optional:invalid", file_name_, line_number_)
103 {
104 }
105 };
106
107 //*****************************************************************************
108 // Implementations for fundamental and non fundamental types.
109 //*****************************************************************************
110 namespace private_optional
111 {
112 template <typename T, bool UseFundamentalPath = etl::is_fundamental<T>::value && !etl::is_const<T>::value>
114
115 //*****************************************************************************
116 // Implementation for non fundamental types.
117 //*****************************************************************************
118 template <typename T>
119 class optional_impl<T, false>
120 {
121 protected:
122
123 typedef T value_type;
124 typedef optional_impl<T, false> this_type;
125
126 //***************************************************************************
128 //***************************************************************************
129 ETL_CONSTEXPR20_STL
131 : storage()
132 {
133 }
134
135 //***************************************************************************
137 //***************************************************************************
138 ETL_CONSTEXPR20_STL
140 : storage()
141 {
142 }
143
145 //***************************************************************************
147 //***************************************************************************
148 ETL_CONSTEXPR20_STL
150 {
151 if (other.has_value())
152 {
153 storage.construct(other.value());
154 }
155 }
157
158#if ETL_USING_CPP11
159 //***************************************************************************
161 //***************************************************************************
162 ETL_CONSTEXPR20_STL
164 {
165 if (other.has_value())
166 {
167 storage.construct(etl::move(other.value()));
168 }
169 }
170
171 //***************************************************************************
173 //***************************************************************************
174 ETL_CONSTEXPR20_STL
175 optional_impl(const T& value_)
176 {
177 storage.construct(value_);
178 }
179
180 //***************************************************************************
182 //***************************************************************************
183 ETL_CONSTEXPR20_STL
184 optional_impl(T&& value_)
185 {
186 storage.construct(etl::move(value_));
187 }
188
189 //***************************************************************************
191 //***************************************************************************
192 template <typename... TArgs>
193 ETL_CONSTEXPR20_STL
194 optional_impl(etl::in_place_t, TArgs&&... args)
195 {
196 storage.construct(etl::forward<TArgs>(args)...);
197 }
198
199#if ETL_HAS_INITIALIZER_LIST
200 //*******************************************
202 //*******************************************
203 template <typename U, typename... TArgs >
204 ETL_CONSTEXPR20_STL optional_impl(etl::in_place_t,
205 std::initializer_list<U> ilist,
206 TArgs&&... args)
207 {
208 storage.construct(ilist, etl::forward<TArgs>(args)...);
209 }
210#endif
211#endif
212
213 //***************************************************************************
215 //***************************************************************************
216 ETL_CONSTEXPR20_STL
218 {
219 storage.destroy();
220 }
221
222 //***************************************************************************
224 //***************************************************************************
225 ETL_CONSTEXPR20_STL
227 {
228 if (has_value())
229 {
230 storage.destroy();
231 }
232
233 return *this;
234 }
235
236 //***************************************************************************
238 //***************************************************************************
239 ETL_CONSTEXPR20_STL
240 optional_impl& operator =(const optional_impl<T>& other)
241 {
242 if (this != &other)
243 {
244 if (other.has_value())
245 {
246 storage.construct(other.value());
247 }
248 else
249 {
250 storage.destroy();
251 }
252 }
253
254 return *this;
255 }
256
257#if ETL_USING_CPP11
258 //***************************************************************************
260 //***************************************************************************
261 ETL_CONSTEXPR20_STL
262 optional_impl& operator =(optional_impl&& other)
263 {
264 if (this != &other)
265 {
266 if (other.has_value())
267 {
268 storage.construct(etl::move(other.value()));
269 }
270 else
271 {
272 storage.destroy();
273 }
274 }
275
276 return *this;
277 }
278#endif
279
280 //***************************************************************************
282 //***************************************************************************
283 ETL_CONSTEXPR20_STL
284 optional_impl& operator =(const T& value_)
285 {
286 storage.construct(value_);
287
288 return *this;
289 }
290
291#if ETL_USING_CPP11
292 //***************************************************************************
294 //***************************************************************************
295 ETL_CONSTEXPR20_STL
296 optional_impl& operator =(T&& value_)
297 {
298 storage.construct(etl::move(value_));
299
300 return *this;
301 }
302#endif
303
304 public:
305
306 //***************************************************************************
308 //***************************************************************************
309 ETL_CONSTEXPR20_STL
310 T* operator ->()
311 {
312#if ETL_IS_DEBUG_BUILD
313 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
314#endif
315
316 return &storage.u.value;
317 }
318
319 //***************************************************************************
321 //***************************************************************************
322 ETL_CONSTEXPR20_STL
323 const T* operator ->() const
324 {
325#if ETL_IS_DEBUG_BUILD
326 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
327#endif
328
329 return &storage.u.value;
330 }
331
332 //***************************************************************************
334 //***************************************************************************
335 ETL_CONSTEXPR20_STL
336 T& operator *() ETL_LVALUE_REF_QUALIFIER
337 {
338#if ETL_IS_DEBUG_BUILD
339 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
340#endif
341
342 return storage.u.value;
343 }
344
345 //***************************************************************************
347 //***************************************************************************
348 ETL_CONSTEXPR20_STL
349 const T& operator *() const ETL_LVALUE_REF_QUALIFIER
350 {
351#if ETL_IS_DEBUG_BUILD
352 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
353#endif
354
355 return storage.u.value;
356 }
357
358#if ETL_USING_CPP11
359 //***************************************************************************
361 //***************************************************************************
362 ETL_CONSTEXPR20_STL
363 T&& operator *()&&
364 {
365#if ETL_IS_DEBUG_BUILD
366 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
367#endif
368
369 return etl::move(storage.u.value);
370 }
371
372 //***************************************************************************
374 //***************************************************************************
375 ETL_CONSTEXPR20_STL
376 const T&& operator *() const&&
377 {
378#if ETL_IS_DEBUG_BUILD
379 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
380#endif
381
382 return etl::move(storage.u.value);
383 }
384#endif
385
386 //***************************************************************************
387 // Check whether optional contains value
388 //***************************************************************************
389 ETL_CONSTEXPR20_STL
390 bool has_value() const ETL_NOEXCEPT
391 {
392 return storage.valid;
393 }
394
395 //***************************************************************************
397 //***************************************************************************
398 ETL_CONSTEXPR20_STL
399 ETL_EXPLICIT operator bool() const
400 {
401 return has_value();
402 }
403
404 //***************************************************************************
406 //***************************************************************************
407 ETL_CONSTEXPR20_STL
408 T& value() ETL_LVALUE_REF_QUALIFIER
409 {
410#if ETL_IS_DEBUG_BUILD
411 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
412#endif
413
414 return storage.u.value;
415 }
416
417 //***************************************************************************
419 //***************************************************************************
420 ETL_CONSTEXPR20_STL
421 const T& value() const ETL_LVALUE_REF_QUALIFIER
422 {
423#if ETL_IS_DEBUG_BUILD
424 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
425#endif
426
427 return storage.u.value;
428 }
429
430 //***************************************************************************
432 //***************************************************************************
433 ETL_CONSTEXPR20_STL
434 T value_or(const T& default_value) const ETL_LVALUE_REF_QUALIFIER
435 {
436 return has_value() ? value() : default_value;
437 }
438
439#if ETL_USING_CPP11
440 //***************************************************************************
442 //***************************************************************************
443 ETL_CONSTEXPR20_STL
444 T&& value()&&
445 {
446#if ETL_IS_DEBUG_BUILD
447 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
448#endif
449
450 return etl::move(storage.u.value);
451 }
452
453 //***************************************************************************
455 //***************************************************************************
456 ETL_CONSTEXPR20_STL
457 const T&& value() const&&
458 {
459#if ETL_IS_DEBUG_BUILD
460 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
461#endif
462
463 return etl::move(storage.u.value);
464 }
465
466 //***************************************************************************
468 //***************************************************************************
469 template <typename U>
470 ETL_CONSTEXPR20_STL
471 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
472 value_or(U&& default_value) const&
473 {
474 return has_value() ? value() : static_cast<T>(etl::forward<U>(default_value));
475 }
476
477 //***************************************************************************
479 //***************************************************************************
480 template <typename U>
481 ETL_CONSTEXPR20_STL
482 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
483 value_or(U&& default_value)&&
484 {
485 return has_value() ? etl::move(value()) : static_cast<T>(etl::forward<U>(default_value));
486 }
487#endif
488
489 //***************************************************************************
491 //***************************************************************************
492 ETL_CONSTEXPR20_STL
493 void swap(optional_impl& other)
494 {
495 optional_impl temp(*this);
496 *this = other;
497 other = temp;
498 }
499
500 //***************************************************************************
502 //***************************************************************************
503 ETL_CONSTEXPR20_STL
504 void reset()
505 {
506 storage.destroy();
507 }
508
509 //*************************************************************************
511 //*************************************************************************
512 ETL_CONSTEXPR20_STL
513 T& emplace(const optional_impl<T>& other)
514 {
515#if ETL_IS_DEBUG_BUILD
516 ETL_ASSERT(other.has_value(), ETL_ERROR(optional_invalid));
517#endif
518
519 storage.construct(other.value());
520
521 return storage.u.value;
522 }
523
524#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
525 //*************************************************************************
530 //*************************************************************************
531 template <typename U,
532 typename... URest,
533 typename etl::enable_if<!etl::is_base_of<optional_impl,
535 ETL_CONSTEXPR20_STL
536 T& emplace(U&& first, URest&&... rest)
537 {
538 storage.construct(etl::forward<U>(first), etl::forward<URest>(rest)...);
539
540 return storage.u.value;
541 }
542
543 //*************************************************************************
545 //*************************************************************************
546 ETL_CONSTEXPR20_STL
547 T& emplace()
548 {
549 storage.construct();
550
551 return storage.u.value;
552 }
553#else
554 //*************************************************************************
557 //*************************************************************************
559 {
560 if (has_value())
561 {
562 // Destroy the old one.
563 storage.destroy();
564 }
565
566 T* p = ::new (&storage.u.value) T();
567 storage.valid = true;
568
569 return *p;
570 }
571
572 //*************************************************************************
575 //*************************************************************************
576 template <typename T1>
579 emplace(const T1& value1)
580 {
581 if (has_value())
582 {
583 // Destroy the old one.
584 storage.destroy();
585 }
586
587 T* p = ::new (&storage.u.value) T(value1);
588 storage.valid = true;
589
590 return *p;
591 }
592
593 //*************************************************************************
596 //*************************************************************************
597 template <typename T1, typename T2>
598 T& emplace(const T1& value1, const T2& value2)
599 {
600 if (has_value())
601 {
602 // Destroy the old one.
603 storage.destroy();
604 }
605
606 T* p = ::new (&storage.u.value) T(value1, value2);
607 storage.valid = true;
608
609 return *p;
610 }
611
612 //*************************************************************************
615 //*************************************************************************
616 template <typename T1, typename T2, typename T3>
617 T& emplace(const T1& value1, const T2& value2, const T3& value3)
618 {
619 if (has_value())
620 {
621 // Destroy the old one.
622 storage.destroy();
623 }
624
625 T* p = ::new (&storage.u.value) T(value1, value2, value3);
626 storage.valid = true;
627
628 return *p;
629 }
630
631 //*************************************************************************
634 //*************************************************************************
635 template <typename T1, typename T2, typename T3, typename T4>
636 T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
637 {
638 if (has_value())
639 {
640 // Destroy the old one.
641 storage.destroy();
642 }
643
644 T* p = ::new (&storage.u.value) T(value1, value2, value3, value4);
645 storage.valid = true;
646
647 return *p;
648 }
649#endif
650
651 private:
652
653 struct dummy_t {};
654
655 //*************************************
656 // The storage for the optional value.
657 //*************************************
658 struct storage_type
659 {
660 typedef typename etl::remove_const<T>::type* pointer_type;
661
662 //*******************************
663 ETL_CONSTEXPR20_STL
664 storage_type()
665 : u()
666 , valid(false)
667 {
668 }
669
670 //*******************************
671 ETL_CONSTEXPR20_STL
672 void construct(const T& value_)
673 {
674 destroy();
675
676 etl::construct_at(const_cast<pointer_type>(&u.value), value_);
677 valid = true;
678 }
679
680#if ETL_USING_CPP11
681 //*******************************
682 ETL_CONSTEXPR20_STL
683 void construct(T&& value_)
684 {
685 destroy();
686
687 etl::construct_at(const_cast<pointer_type>(&u.value), etl::move(value_));
688 valid = true;
689 }
690
691 //*******************************
692 template <typename... TArgs>
693 ETL_CONSTEXPR20_STL
694 void construct(TArgs&&... args)
695 {
696 destroy();
697
698 etl::construct_at(const_cast<pointer_type>(&u.value), etl::forward<TArgs>(args)...);
699 valid = true;
700 }
701#endif
702
703 //*******************************
704 ETL_CONSTEXPR20_STL
705 void destroy()
706 {
707 if (valid)
708 {
709 etl::destroy_at(const_cast<pointer_type>(&u.value));
710 valid = false;
711 }
712 }
713
714 //*******************************
715 union union_type
716 {
717 ETL_CONSTEXPR20_STL
718 union_type()
719 : dummy()
720 {
721 }
722
723 ETL_CONSTEXPR20_STL
724 ~union_type()
725 {
726 }
727
728 dummy_t dummy;
729 T value;
730 } u;
731
732 bool valid;
733 };
734
735 storage_type storage;
736 };
737
738 //*****************************************************************************
739 // Implementation for fundamental types.
740 //*****************************************************************************
741 template <typename T>
742 class optional_impl<T, true>
743 {
744 protected:
745
746 typedef T value_type;
747 typedef optional_impl<T, true> this_type;
748
749 //***************************************************************************
751 //***************************************************************************
752 ETL_CONSTEXPR14
754 : storage()
755 {
756 }
757
758 //***************************************************************************
760 //***************************************************************************
761 ETL_CONSTEXPR14
763 : storage()
764 {
765 }
766
768 //***************************************************************************
770 //***************************************************************************
771 ETL_CONSTEXPR14
773 {
774 if (other.has_value())
775 {
776 storage.construct(other.value());
777 }
778 }
780
781#if ETL_USING_CPP11
782 //***************************************************************************
784 //***************************************************************************
785 ETL_CONSTEXPR14
787 {
788 if (other.has_value())
789 {
790 storage.construct(etl::move(other.value()));
791 }
792 }
793
794 //***************************************************************************
796 //***************************************************************************
797 ETL_CONSTEXPR14
798 optional_impl(const T& value_)
799 {
800 storage.construct(value_);
801 }
802
803 //***************************************************************************
805 //***************************************************************************
806 ETL_CONSTEXPR14
807 optional_impl(T&& value_)
808 {
809 storage.construct(etl::move(value_));
810 }
811
812 //***************************************************************************
814 //***************************************************************************
815 template <typename... TArgs>
816 ETL_CONSTEXPR14
817 optional_impl(etl::in_place_t, TArgs&&... args)
818 {
819 storage.construct(etl::forward<TArgs>(args)...);
820 }
821
822#if ETL_HAS_INITIALIZER_LIST
823 //*******************************************
825 //*******************************************
826 template <typename U, typename... TArgs >
827 ETL_CONSTEXPR14 optional_impl(etl::in_place_t,
828 std::initializer_list<U> ilist,
829 TArgs&&... args)
830 {
831 storage.construct(ilist, etl::forward<TArgs>(args)...);
832 }
833#endif
834#endif
835
836 //***************************************************************************
838 //***************************************************************************
839 ETL_CONSTEXPR14
841 {
842 if (has_value())
843 {
844 storage.destroy();
845 }
846
847 return *this;
848 }
849
850 //***************************************************************************
852 //***************************************************************************
853 ETL_CONSTEXPR14
854 optional_impl& operator =(const optional_impl<T>& other)
855 {
856 if (this != &other)
857 {
858 if (other.has_value())
859 {
860 storage.construct(other.value());
861 }
862 else
863 {
864 storage.destroy();
865 }
866 }
867
868 return *this;
869 }
870
871#if ETL_USING_CPP11
872 //***************************************************************************
874 //***************************************************************************
875 ETL_CONSTEXPR14
876 optional_impl& operator =(optional_impl&& other)
877 {
878 if (this != &other)
879 {
880 if (other.has_value())
881 {
882 storage.construct(etl::move(other.value()));
883 }
884 else
885 {
886 storage.destroy();
887 }
888 }
889
890 return *this;
891 }
892#endif
893
894 //***************************************************************************
896 //***************************************************************************
897 ETL_CONSTEXPR14
898 optional_impl& operator =(const T& value_)
899 {
900 storage.construct(value_);
901
902 return *this;
903 }
904
905#if ETL_USING_CPP11
906 //***************************************************************************
908 //***************************************************************************
909 ETL_CONSTEXPR14
910 optional_impl& operator =(T&& value_)
911 {
912 storage.construct(etl::move(value_));
913
914 return *this;
915 }
916#endif
917
918 public:
919
920 //***************************************************************************
922 //***************************************************************************
923 ETL_CONSTEXPR14
924 T* operator ->()
925 {
926#if ETL_IS_DEBUG_BUILD
927 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
928#endif
929
930 return &storage.value;
931 }
932
933 //***************************************************************************
935 //***************************************************************************
936 ETL_CONSTEXPR14
937 const T* operator ->() const
938 {
939#if ETL_IS_DEBUG_BUILD
940 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
941#endif
942
943 return &storage.value;
944 }
945
946 //***************************************************************************
948 //***************************************************************************
949 ETL_CONSTEXPR14
950 T& operator *() ETL_LVALUE_REF_QUALIFIER
951 {
952#if ETL_IS_DEBUG_BUILD
953 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
954#endif
955
956 return storage.value;
957 }
958
959 //***************************************************************************
961 //***************************************************************************
962 ETL_CONSTEXPR14
963 const T& operator *() const ETL_LVALUE_REF_QUALIFIER
964 {
965#if ETL_IS_DEBUG_BUILD
966 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
967#endif
968
969 return storage.value;
970 }
971
972#if ETL_USING_CPP11
973 //***************************************************************************
975 //***************************************************************************
976 ETL_CONSTEXPR14
977 T&& operator *()&&
978 {
979#if ETL_IS_DEBUG_BUILD
980 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
981#endif
982
983 return etl::move(storage.value);
984 }
985
986 //***************************************************************************
988 //***************************************************************************
989 ETL_CONSTEXPR14
990 const T&& operator *() const&&
991 {
992#if ETL_IS_DEBUG_BUILD
993 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
994#endif
995
996 return etl::move(storage.value);
997 }
998#endif
999
1000 //***************************************************************************
1001 // Check whether optional contains value
1002 //***************************************************************************
1003 ETL_CONSTEXPR14
1004 bool has_value() const ETL_NOEXCEPT
1005 {
1006 return storage.valid;
1007 }
1008
1009 //***************************************************************************
1011 //***************************************************************************
1012 ETL_CONSTEXPR14
1013 ETL_EXPLICIT operator bool() const
1014 {
1015 return has_value();
1016 }
1017
1018 //***************************************************************************
1020 //***************************************************************************
1021 ETL_CONSTEXPR14
1022 T& value() ETL_LVALUE_REF_QUALIFIER
1023 {
1024#if ETL_IS_DEBUG_BUILD
1025 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
1026#endif
1027
1028 return storage.value;
1029 }
1030
1031 //***************************************************************************
1033 //***************************************************************************
1034 ETL_CONSTEXPR14
1035 const T& value() const ETL_LVALUE_REF_QUALIFIER
1036 {
1037#if ETL_IS_DEBUG_BUILD
1038 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
1039#endif
1040
1041 return storage.value;
1042 }
1043
1044 //***************************************************************************
1046 //***************************************************************************
1047 ETL_CONSTEXPR14
1048 T value_or(const T& default_value) const ETL_LVALUE_REF_QUALIFIER
1049 {
1050 return has_value() ? value() : default_value;
1051 }
1052
1053#if ETL_USING_CPP11
1054 //***************************************************************************
1056 //***************************************************************************
1057 ETL_CONSTEXPR14
1058 T&& value()&&
1059 {
1060#if ETL_IS_DEBUG_BUILD
1061 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
1062#endif
1063
1064 return etl::move(storage.value);
1065 }
1066
1067 //***************************************************************************
1069 //***************************************************************************
1070 ETL_CONSTEXPR14
1071 const T&& value() const&&
1072 {
1073#if ETL_IS_DEBUG_BUILD
1074 ETL_ASSERT(has_value(), ETL_ERROR(optional_invalid));
1075#endif
1076
1077 return etl::move(storage.value);
1078 }
1079
1080 //***************************************************************************
1082 //***************************************************************************
1083 template <typename U>
1084 ETL_CONSTEXPR14
1085 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
1086 value_or(U&& default_value) const&
1087 {
1088 return has_value() ? value() : static_cast<T>(etl::forward<U>(default_value));
1089 }
1090
1091 //***************************************************************************
1093 //***************************************************************************
1094 template <typename U>
1095 ETL_CONSTEXPR14
1096 etl::enable_if_t<etl::is_convertible<U, T>::value, T>
1097 value_or(U&& default_value)&&
1098 {
1099 return has_value() ? etl::move(value()) : static_cast<T>(etl::forward<U>(default_value));
1100 }
1101#endif
1102
1103 //***************************************************************************
1105 //***************************************************************************
1106 ETL_CONSTEXPR14
1107 void swap(optional_impl& other)
1108 {
1109 optional_impl temp(*this);
1110 *this = other;
1111 other = temp;
1112 }
1113
1114 //***************************************************************************
1116 //***************************************************************************
1117 ETL_CONSTEXPR14
1118 void reset()
1119 {
1120 storage.destroy();
1121 }
1122
1123 //*************************************************************************
1125 //*************************************************************************
1126 ETL_CONSTEXPR20_STL
1127 T& emplace(const optional_impl<T>& other)
1128 {
1129#if ETL_IS_DEBUG_BUILD
1130 ETL_ASSERT(other.has_value(), ETL_ERROR(optional_invalid));
1131#endif
1132
1133 storage.construct(other.value());
1134
1135 return storage.u.value;
1136 }
1137
1138#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION)
1139 //*************************************************************************
1142 //*************************************************************************
1143 template <typename... TArgs>
1144 ETL_CONSTEXPR14
1145 T& emplace(TArgs&& ... args)
1146 {
1147 storage.construct(etl::forward<TArgs>(args)...);
1148
1149 return storage.value;
1150 }
1151#else
1152 //*************************************************************************
1155 //*************************************************************************
1157 {
1158 if (has_value())
1159 {
1160 // Destroy the old one.
1161 storage.destroy();
1162 }
1163
1164 T* p = ::new (&storage.value) T();
1165 storage.valid = true;
1166
1167 return *p;
1168 }
1169
1170 //*************************************************************************
1173 //*************************************************************************
1174 template <typename T1>
1177 emplace(const T1& value1)
1178 {
1179 if (has_value())
1180 {
1181 // Destroy the old one.
1182 storage.destroy();
1183 }
1184
1185 T* p = ::new (&storage.value) T(value1);
1186 storage.valid = true;
1187
1188 return *p;
1189 }
1190
1191 //*************************************************************************
1194 //*************************************************************************
1195 template <typename T1, typename T2>
1196 T& emplace(const T1& value1, const T2& value2)
1197 {
1198 if (has_value())
1199 {
1200 // Destroy the old one.
1201 storage.destroy();
1202 }
1203
1204 T* p = ::new (&storage.value) T(value1, value2);
1205 storage.valid = true;
1206
1207 return *p;
1208 }
1209
1210 //*************************************************************************
1213 //*************************************************************************
1214 template <typename T1, typename T2, typename T3>
1215 T& emplace(const T1& value1, const T2& value2, const T3& value3)
1216 {
1217 if (has_value())
1218 {
1219 // Destroy the old one.
1220 storage.destroy();
1221 }
1222
1223 T* p = ::new (&storage.value) T(value1, value2, value3);
1224 storage.valid = true;
1225
1226 return *p;
1227 }
1228
1229 //*************************************************************************
1232 //*************************************************************************
1233 template <typename T1, typename T2, typename T3, typename T4>
1234 T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
1235 {
1236 if (has_value())
1237 {
1238 // Destroy the old one.
1239 storage.destroy();
1240 }
1241
1242 T* p = ::new (&storage.value) T(value1, value2, value3, value4);
1243 storage.valid = true;
1244
1245 return *p;
1246 }
1247#endif
1248
1249 private:
1250
1251 //*************************************
1252 // The storage for the optional value.
1253 //*************************************
1254 struct storage_type
1255 {
1256 //*******************************
1257 ETL_CONSTEXPR14
1258 storage_type()
1259 : value()
1260 , valid(false)
1261 {
1262 }
1263
1264 //*******************************
1265 ETL_CONSTEXPR14
1266 void construct(const T& value_)
1267 {
1268 value = value_;
1269 valid = true;
1270 }
1271
1272#if ETL_USING_CPP11
1273 //*******************************
1274 ETL_CONSTEXPR14
1275 void construct(T&& value_)
1276 {
1277 value = value_;
1278 valid = true;
1279 }
1280
1281 //*******************************
1282 template <typename... TArgs>
1283 ETL_CONSTEXPR14
1284 void construct(TArgs&&... args)
1285 {
1286 value = T(etl::forward<TArgs>(args)...);
1287 valid = true;
1288 }
1289#endif
1290
1291 //*******************************
1292 ETL_CONSTEXPR14
1293 void destroy()
1294 {
1295 valid = false;
1296 }
1297
1298 T value;
1299 bool valid;
1300 };
1301
1302 storage_type storage;
1303 };
1304 }
1305
1306#define ETL_OPTIONAL_ENABLE_CPP14 typename etl::enable_if< etl::is_pod<typename etl::remove_cv<U>::type>::value, int>::type = 0
1307#define ETL_OPTIONAL_ENABLE_CPP20_STL typename etl::enable_if<!etl::is_pod<typename etl::remove_cv<U>::type>::value, int>::type = 0
1308
1309#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 ETL_CONSTEXPR14 typename etl::enable_if< etl::is_pod<typename etl::remove_cv<T>::type>::value, bool>::type
1310#define ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL ETL_CONSTEXPR20_STL typename etl::enable_if<!etl::is_pod<typename etl::remove_cv<T>::type>::value, bool>::type
1311
1312 //*****************************************************************************
1318 //*****************************************************************************
1319 template <typename T>
1320 class optional : public private_optional::optional_impl<T>
1321 {
1322 private:
1323
1325
1326 public:
1327
1328 typedef T value_type;
1329
1330#if ETL_USING_CPP11
1331 //***************************************************************************
1333 //***************************************************************************
1334 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1335 ETL_CONSTEXPR14
1336 optional()
1337 : impl_t()
1338 {
1339 }
1340
1341 //***************************************************************************
1343 //***************************************************************************
1344 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1345 ETL_CONSTEXPR20_STL
1346 optional()
1347 : impl_t()
1348 {
1349 }
1350#else
1351 optional()
1352 : impl_t()
1353 {
1354 }
1355#endif
1356
1357#if ETL_USING_CPP11
1358 //***************************************************************************
1360 //***************************************************************************
1361 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1362 ETL_CONSTEXPR14
1363 optional(etl::nullopt_t)
1364 : impl_t(etl::nullopt)
1365 {
1366 }
1367
1368 //***************************************************************************
1370 //***************************************************************************
1371 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1372 ETL_CONSTEXPR20_STL
1373 optional(etl::nullopt_t)
1374 : impl_t(etl::nullopt)
1375 {
1376 }
1377#else
1378 //***************************************************************************
1380 //***************************************************************************
1382 : impl_t(etl::nullopt)
1383 {
1384 }
1385#endif
1386
1388#if ETL_USING_CPP11
1389 //***************************************************************************
1391 //***************************************************************************
1392 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1393 ETL_CONSTEXPR14
1394 optional(const optional& other)
1395 : impl_t(other)
1396 {
1397 }
1398
1399 //***************************************************************************
1401 //***************************************************************************
1402 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1403 ETL_CONSTEXPR20_STL
1404 optional(const optional& other)
1405 : impl_t(other)
1406 {
1407 }
1408#else
1409 //***************************************************************************
1411 //***************************************************************************
1412 optional(const optional& other)
1413 : impl_t(other)
1414 {
1415 }
1416#endif
1417#include "private/diagnostic_pop.h"
1418
1419#if ETL_USING_CPP11
1420 //***************************************************************************
1422 //***************************************************************************
1423 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1424 ETL_CONSTEXPR14
1425 optional(optional&& other)
1426 : impl_t(other)
1427 {
1428 }
1429
1430 //***************************************************************************
1432 //***************************************************************************
1433 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1434 ETL_CONSTEXPR20_STL
1435 optional(optional&& other)
1436 : impl_t(other)
1437 {
1438 }
1439#endif
1440
1441#if ETL_USING_CPP11
1442 //***************************************************************************
1444 //***************************************************************************
1445 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1446 ETL_CONSTEXPR14
1447 optional(const T& value_)
1448 : impl_t(value_)
1449 {
1450 }
1451
1452 //***************************************************************************
1454 //***************************************************************************
1455 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1456 ETL_CONSTEXPR20_STL
1457 optional(const T& value_)
1458 : impl_t(value_)
1459 {
1460 }
1461#else
1462 //***************************************************************************
1464 //***************************************************************************
1465 optional(const T& value_)
1466 : impl_t(value_)
1467 {
1468 }
1469#endif
1470
1471
1472#if ETL_USING_CPP11
1473 //***************************************************************************
1475 //***************************************************************************
1476 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1477 ETL_CONSTEXPR14
1478 optional(T&& value_)
1479 : impl_t(etl::move(value_))
1480 {
1481 }
1482
1483 //***************************************************************************
1485 //***************************************************************************
1486 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1487 ETL_CONSTEXPR20_STL
1488 optional(T&& value_)
1489 : impl_t(etl::move(value_))
1490 {
1491 }
1492#endif
1493
1494#if ETL_USING_CPP11
1495 //***************************************************************************
1497 //***************************************************************************
1498 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14, typename... Args>
1499 ETL_CONSTEXPR14
1500 explicit optional(etl::in_place_t, Args&&... args)
1501 : impl_t(etl::in_place_t{}, etl::forward<Args>(args)...)
1502 {
1503 }
1504
1505 //***************************************************************************
1507 //***************************************************************************
1508 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL, typename... Args>
1509 ETL_CONSTEXPR20_STL
1510 explicit optional(etl::in_place_t, Args&&... args)
1511 : impl_t(etl::in_place_t{}, etl::forward<Args>(args)...)
1512 {
1513 }
1514
1515#if ETL_HAS_INITIALIZER_LIST
1516 //*******************************************
1518 //*******************************************
1519 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14, typename... TArgs>
1520 ETL_CONSTEXPR14
1521 explicit optional(etl::in_place_t,
1522 std::initializer_list<U> ilist,
1523 TArgs&&... args)
1524 : impl_t(etl::in_place_t{}, ilist, etl::forward<TArgs>(args)...)
1525 {
1526 }
1527
1528 //*******************************************
1530 //*******************************************
1531 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL, typename... TArgs>
1532 ETL_CONSTEXPR20_STL
1533 explicit optional(etl::in_place_t,
1534 std::initializer_list<U> ilist,
1535 TArgs&&... args)
1536 : impl_t(etl::in_place_t{}, ilist, etl::forward<TArgs>(args)...)
1537 {
1538 }
1539#endif
1540#endif
1541
1542#if ETL_USING_CPP11
1543 //***************************************************************************
1545 //***************************************************************************
1546 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1547 ETL_CONSTEXPR14
1548 optional& operator =(etl::nullopt_t)
1549 {
1550 impl_t::operator=(etl::nullopt);
1551
1552 return *this;
1553 }
1554
1555 //***************************************************************************
1557 //***************************************************************************
1558 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1559 ETL_CONSTEXPR20_STL
1560 optional& operator =(etl::nullopt_t)
1561 {
1562 impl_t::operator=(etl::nullopt);
1563
1564 return *this;
1565 }
1566#else
1567 //***************************************************************************
1569 //***************************************************************************
1571 {
1572 impl_t::operator=(etl::nullopt);
1573
1574 return *this;
1575 }
1576#endif
1577
1578#if ETL_USING_CPP11
1579 //***************************************************************************
1581 //***************************************************************************
1582 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1583 ETL_CONSTEXPR14
1584 optional& operator =(const optional& other)
1585 {
1586 impl_t::operator=(other);
1587
1588 return *this;
1589 }
1590
1591 //***************************************************************************
1593 //***************************************************************************
1594 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1595 ETL_CONSTEXPR20_STL
1596 optional& operator =(const optional& other)
1597 {
1598 impl_t::operator=(other);
1599
1600 return *this;
1601 }
1602#else
1603 //***************************************************************************
1605 //***************************************************************************
1606 optional& operator =(const optional& other)
1607 {
1608 impl_t::operator=(other);
1609
1610 return *this;
1611 }
1612#endif
1613
1614#if ETL_USING_CPP11
1615 //***************************************************************************
1617 //***************************************************************************
1618 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1619 ETL_CONSTEXPR14
1620 optional& operator =(optional&& other)
1621 {
1622 impl_t::operator=(etl::move(other));
1623
1624 return *this;
1625 }
1626
1627 //***************************************************************************
1629 //***************************************************************************
1630 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1631 ETL_CONSTEXPR20_STL
1632 optional& operator =(optional&& other)
1633 {
1634 impl_t::operator=(etl::move(other));
1635
1636 return *this;
1637 }
1638#endif
1639
1640#if ETL_USING_CPP11
1641 //***************************************************************************
1643 //***************************************************************************
1644 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1645 ETL_CONSTEXPR14
1646 optional& operator =(const T& value_)
1647 {
1648 impl_t::operator=(value_);
1649
1650 return *this;
1651 }
1652
1653 //***************************************************************************
1655 //***************************************************************************
1656 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1657 ETL_CONSTEXPR20_STL
1658 optional& operator =(const T& value_)
1659 {
1660 impl_t::operator=(value_);
1661
1662 return *this;
1663 }
1664#else
1665 //***************************************************************************
1667 //***************************************************************************
1668 optional& operator =(const T& value_)
1669 {
1670 impl_t::operator=(value_);
1671
1672 return *this;
1673 }
1674#endif
1675
1676#if ETL_USING_CPP11
1677 //***************************************************************************
1679 //***************************************************************************
1680 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP14>
1681 ETL_CONSTEXPR14
1682 optional& operator =(T&& value_)
1683 {
1684 impl_t::operator=(etl::move(value_));
1685
1686 return *this;
1687 }
1688
1689 //***************************************************************************
1691 //***************************************************************************
1692 template <typename U = T, ETL_OPTIONAL_ENABLE_CPP20_STL>
1693 ETL_CONSTEXPR20_STL
1694 optional& operator =(T&& value_)
1695 {
1696 impl_t::operator=(etl::move(value_));
1697
1698 return *this;
1699 }
1700#endif
1701 };
1702
1704
1705 //***************************************************************************
1707 //***************************************************************************
1708 template <typename T>
1709 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1710 {
1711 if (lhs.has_value() != rhs.has_value())
1712 {
1713 return false;
1714 }
1715 else if (!lhs.has_value() && !rhs.has_value())
1716 {
1717 return true;
1718 }
1719 else
1720 {
1721 return lhs.value() == rhs.value();
1722 }
1723 }
1724
1725 //***************************************************************************
1727 //***************************************************************************
1728 template <typename T>
1729 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1730 {
1731 if (lhs.has_value() != rhs.has_value())
1732 {
1733 return false;
1734 }
1735 else if (!lhs.has_value() && !rhs.has_value())
1736 {
1737 return true;
1738 }
1739 else
1740 {
1741 return lhs.value() == rhs.value();
1742 }
1743 }
1744
1745 //***************************************************************************
1747 //***************************************************************************
1748 template <typename T>
1749 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1750 {
1751 return !(lhs == rhs);
1752 }
1753
1754 //***************************************************************************
1756 //***************************************************************************
1757 template <typename T>
1758 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1759 {
1760 return !(lhs == rhs);
1761 }
1762
1763 //***************************************************************************
1765 //***************************************************************************
1766 template <typename T>
1767 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1768 {
1769 if (!rhs.has_value())
1770 {
1771 return false;
1772 }
1773 else if (!lhs.has_value())
1774 {
1775 return true;
1776 }
1777 else
1778 {
1779 return lhs.value() < rhs.value();
1780 }
1781 }
1782
1783 //***************************************************************************
1785 //***************************************************************************
1786 template <typename T>
1787 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1788 {
1789 if (!rhs.has_value())
1790 {
1791 return false;
1792 }
1793 else if (!lhs.has_value())
1794 {
1795 return true;
1796 }
1797 else
1798 {
1799 return lhs.value() < rhs.value();
1800 }
1801 }
1802
1803 //***************************************************************************
1805 //***************************************************************************
1806 template <typename T>
1807 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1808 {
1809 return !(rhs < lhs);
1810 }
1811
1812 //***************************************************************************
1814 //***************************************************************************
1815 template <typename T>
1816 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1817 {
1818 return !(rhs < lhs);
1819 }
1820
1821 //***************************************************************************
1823 //***************************************************************************
1824 template <typename T>
1825 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1826 {
1827 return (rhs < lhs);
1828 }
1829
1830 //***************************************************************************
1832 //***************************************************************************
1833 template <typename T>
1834 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1835 {
1836 return (rhs < lhs);
1837 }
1838
1839 //***************************************************************************
1841 //***************************************************************************
1842 template <typename T>
1843 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1844 {
1845 return !(lhs < rhs);
1846 }
1847
1848 //***************************************************************************
1850 //***************************************************************************
1851 template <typename T>
1852 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const etl::optional<T>& rhs)
1853 {
1854 return !(lhs < rhs);
1855 }
1856
1857 //***************************************************************************
1859 //***************************************************************************
1860 template <typename T>
1861 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
1862 {
1863 return !lhs.has_value();
1864 }
1865
1866 //***************************************************************************
1868 //***************************************************************************
1869 template <typename T>
1870 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, etl::nullopt_t)
1871 {
1872 return !lhs.has_value();
1873 }
1874
1875 //***************************************************************************
1877 //***************************************************************************
1878 template <typename T>
1879 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
1880 {
1881 return !rhs.has_value();
1882 }
1883
1884 //***************************************************************************
1886 //***************************************************************************
1887 template <typename T>
1888 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(etl::nullopt_t, const etl::optional<T>& rhs)
1889 {
1890 return !rhs.has_value();
1891 }
1892
1893 //***************************************************************************
1895 //***************************************************************************
1896 template <typename T>
1897 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
1898 {
1899 return !(lhs == etl::nullopt);
1900 }
1901
1902 //***************************************************************************
1904 //***************************************************************************
1905 template <typename T>
1906 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, etl::nullopt_t)
1907 {
1908 return !(lhs == etl::nullopt);
1909 }
1910
1911 //***************************************************************************
1913 //***************************************************************************
1914 template <typename T>
1915 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(etl::nullopt_t , const etl::optional<T>& rhs)
1916 {
1917 return !(etl::nullopt == rhs);
1918 }
1919
1920 //***************************************************************************
1922 //***************************************************************************
1923 template <typename T>
1924 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(etl::nullopt_t, const etl::optional<T>& rhs)
1925 {
1926 return !(etl::nullopt == rhs);
1927 }
1928
1929 //***************************************************************************
1931 //***************************************************************************
1932 template <typename T>
1933 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>&, etl::nullopt_t)
1934 {
1935 return false;
1936 }
1937
1938 //***************************************************************************
1940 //***************************************************************************
1941 template <typename T>
1942 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>&, etl::nullopt_t)
1943 {
1944 return false;
1945 }
1946
1947 //***************************************************************************
1949 //***************************************************************************
1950 template <typename T>
1951 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(etl::nullopt_t, const etl::optional<T>& rhs)
1952 {
1953 return rhs.has_value();
1954 }
1955
1956 //***************************************************************************
1958 //***************************************************************************
1959 template <typename T>
1960 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(etl::nullopt_t, const etl::optional<T>& rhs)
1961 {
1962 return rhs.has_value();
1963 }
1964
1965 //***************************************************************************
1967 //***************************************************************************
1968 template <typename T>
1969 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
1970 {
1971 return !lhs.has_value();
1972 }
1973
1974 //***************************************************************************
1976 //***************************************************************************
1977 template <typename T>
1978 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, etl::nullopt_t)
1979 {
1980 return !lhs.has_value();
1981 }
1982
1983 //***************************************************************************
1985 //***************************************************************************
1986 template <typename T>
1987 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(etl::nullopt_t, const etl::optional<T>&)
1988 {
1989 return true;
1990 }
1991
1992 //***************************************************************************
1994 //***************************************************************************
1995 template <typename T>
1996 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(etl::nullopt_t, const etl::optional<T>&)
1997 {
1998 return true;
1999 }
2000
2001 //***************************************************************************
2003 //***************************************************************************
2004 template <typename T>
2005 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, etl::nullopt_t)
2006 {
2007 return lhs.has_value();
2008 }
2009
2010 //***************************************************************************
2012 //***************************************************************************
2013 template <typename T>
2014 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, etl::nullopt_t)
2015 {
2016 return lhs.has_value();
2017 }
2018
2019 //***************************************************************************
2021 //***************************************************************************
2022 template <typename T>
2023 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(etl::nullopt_t, const etl::optional<T>&)
2024 {
2025 return false;
2026 }
2027
2028 //***************************************************************************
2030 //***************************************************************************
2031 template <typename T>
2032 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(etl::nullopt_t, const etl::optional<T>&)
2033 {
2034 return false;
2035 }
2036
2037 //***************************************************************************
2039 //***************************************************************************
2040 template <typename T>
2041 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>&, etl::nullopt_t)
2042 {
2043 return true;
2044 }
2045
2046 //***************************************************************************
2048 //***************************************************************************
2049 template <typename T>
2050 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>&, etl::nullopt_t)
2051 {
2052 return true;
2053 }
2054
2055 //***************************************************************************
2057 //***************************************************************************
2058 template <typename T>
2059 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
2060 {
2061 return !rhs.has_value();
2062 }
2063
2064 //***************************************************************************
2066 //***************************************************************************
2067 template <typename T>
2068 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(etl::nullopt_t, const etl::optional<T>& rhs)
2069 {
2070 return !rhs.has_value();
2071 }
2072
2073 //***************************************************************************
2075 //**************************************************************************
2076 template <typename T, typename U>
2077 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const etl::optional<T>& lhs, const U& rhs)
2078 {
2079 return lhs.has_value() ? lhs.value() == rhs : false;
2080 }
2081
2082 //***************************************************************************
2084 //**************************************************************************
2085 template <typename T, typename U>
2086 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const etl::optional<T>& lhs, const U& rhs)
2087 {
2088 return lhs.has_value() ? lhs.value() == rhs : false;
2089 }
2090
2091 //***************************************************************************
2093 //**************************************************************************
2094 template <typename T, typename U>
2095 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const etl::optional<T>& lhs, const U& rhs)
2096 {
2097 return !(lhs == rhs);
2098 }
2099
2100 //***************************************************************************
2102 //**************************************************************************
2103 template <typename T, typename U>
2104 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const etl::optional<T>& lhs, const U& rhs)
2105 {
2106 return !(lhs == rhs);
2107 }
2108
2109 //***************************************************************************
2111 //**************************************************************************
2112 template <typename T, typename U>
2113 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator ==(const U& lhs, const etl::optional<T>& rhs)
2114 {
2115 return rhs.has_value() ? rhs.value() == lhs : false;
2116 }
2117
2118 //***************************************************************************
2120 //**************************************************************************
2121 template <typename T, typename U>
2122 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator ==(const U& lhs, const etl::optional<T>& rhs)
2123 {
2124 return rhs.has_value() ? rhs.value() == lhs : false;
2125 }
2126
2127 //***************************************************************************
2129 //**************************************************************************
2130 template <typename T, typename U>
2131 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator !=(const U& lhs, const etl::optional<T>& rhs)
2132 {
2133 return !(lhs == rhs);
2134 }
2135
2136 //***************************************************************************
2138 //**************************************************************************
2139 template <typename T, typename U>
2140 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator !=(const U& lhs, const etl::optional<T>& rhs)
2141 {
2142 return !(lhs == rhs);
2143 }
2144
2145 //***************************************************************************
2147 //***************************************************************************
2148 template <typename T, typename U>
2149 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const etl::optional<T>& lhs, const U& rhs)
2150 {
2151 return lhs.has_value() ? lhs.value() < rhs : true;
2152 }
2153
2154 //***************************************************************************
2156 //***************************************************************************
2157 template <typename T, typename U>
2158 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const etl::optional<T>& lhs, const U& rhs)
2159 {
2160 return lhs.has_value() ? lhs.value() < rhs : true;
2161 }
2162
2163 //***************************************************************************
2165 //***************************************************************************
2166 template <typename T, typename U>
2167 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <(const U& lhs, const etl::optional<T>& rhs)
2168 {
2169 return rhs.has_value() ? lhs < rhs.value() : false;
2170 }
2171
2172 //***************************************************************************
2174 //***************************************************************************
2175 template <typename T, typename U>
2176 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <(const U& lhs, const etl::optional<T>& rhs)
2177 {
2178 return rhs.has_value() ? lhs < rhs.value() : false;
2179 }
2180
2181 //***************************************************************************
2183 //***************************************************************************
2184 template <typename T, typename U>
2185 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const etl::optional<T>& lhs, const U& rhs)
2186 {
2187 return lhs.has_value() ? lhs.value() <= rhs : true;
2188 }
2189
2190 //***************************************************************************
2192 //***************************************************************************
2193 template <typename T, typename U>
2194 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const etl::optional<T>& lhs, const U& rhs)
2195 {
2196 return lhs.has_value() ? lhs.value() <= rhs : true;
2197 }
2198
2199 //***************************************************************************
2201 //***************************************************************************
2202 template <typename T, typename U>
2203 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator <=(const U& lhs, const etl::optional<T>& rhs)
2204 {
2205 return rhs.has_value() ? lhs <= rhs.value() : false;
2206 }
2207
2208 //***************************************************************************
2210 //***************************************************************************
2211 template <typename T, typename U>
2212 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator <=(const U& lhs, const etl::optional<T>& rhs)
2213 {
2214 return rhs.has_value() ? lhs <= rhs.value() : false;
2215 }
2216
2217 //***************************************************************************
2219 //***************************************************************************
2220 template <typename T, typename U>
2221 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const etl::optional<T>& lhs, const U& rhs)
2222 {
2223 return lhs.has_value() ? lhs.value() > rhs : false;
2224 }
2225
2226 //***************************************************************************
2228 //***************************************************************************
2229 template <typename T, typename U>
2230 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const etl::optional<T>& lhs, const U& rhs)
2231 {
2232 return lhs.has_value() ? lhs.value() > rhs : false;
2233 }
2234
2235 //***************************************************************************
2237 //***************************************************************************
2238 template <typename T, typename U>
2239 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >(const U& lhs, const etl::optional<T>& rhs)
2240 {
2241 return rhs.has_value() ? lhs > rhs.value() : true;
2242 }
2243
2244 //***************************************************************************
2246 //***************************************************************************
2247 template <typename T, typename U>
2248 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >(const U& lhs, const etl::optional<T>& rhs)
2249 {
2250 return rhs.has_value() ? lhs > rhs.value() : true;
2251 }
2252
2253 //***************************************************************************
2255 //***************************************************************************
2256 template <typename T, typename U>
2257 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const etl::optional<T>& lhs, const U& rhs)
2258 {
2259 return lhs.has_value() ? lhs.value() >= rhs : false;
2260 }
2261
2262 //***************************************************************************
2264 //***************************************************************************
2265 template <typename T, typename U>
2266 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const etl::optional<T>& lhs, const U& rhs)
2267 {
2268 return lhs.has_value() ? lhs.value() >= rhs : false;
2269 }
2270
2271 //***************************************************************************
2273 //***************************************************************************
2274 template <typename T, typename U>
2275 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 operator >=(const U& lhs, const etl::optional<T>& rhs)
2276 {
2277 return rhs.has_value() ? lhs >= rhs.value() : true;
2278 }
2279
2280 //***************************************************************************
2282 //***************************************************************************
2283 template <typename T, typename U>
2284 ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL operator >=(const U& lhs, const etl::optional<T>& rhs)
2285 {
2286 return rhs.has_value() ? lhs >= rhs.value() : true;
2287 }
2288
2289#include "private/diagnostic_pop.h"
2290
2291 //***************************************************************************
2293 //***************************************************************************
2294 template <typename T>
2296 {
2298 }
2299
2300 //***************************************************************************
2302 //***************************************************************************
2303#if ETL_CPP17_SUPPORTED
2304 template <typename T>
2305 optional(T) -> optional<T>;
2306#endif
2307}
2308
2309//*************************************************************************
2311//*************************************************************************
2312template <typename T>
2313ETL_CONSTEXPR20_STL void swap(etl::optional<T>& lhs, etl::optional<T>& rhs)
2314{
2315 lhs.swap(rhs);
2316}
2317
2318#undef ETL_OPTIONAL_ENABLE_CPP14
2319#undef ETL_OPTIONAL_ENABLE_CPP20_STL
2320
2321#undef ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14
2322#undef ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL
2323
2324#endif
Definition optional.h:57
Definition optional.h:1321
optional(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:1381
optional(const T &value_)
Construct from value type.
Definition optional.h:1465
optional(const optional &other)
Copy constructor.
Definition optional.h:1412
optional & operator=(etl::nullopt_t)
Assignment operator from nullopt.
Definition optional.h:1570
ETL_CONSTEXPR20_STL const T & value() const ETL_LVALUE_REF_QUALIFIER
Get a const reference to the value.
Definition optional.h:421
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition optional.h:617
ETL_CONSTEXPR20_STL optional_impl()
Constructor.
Definition optional.h:130
ETL_CONSTEXPR20_STL void swap(optional_impl &other)
Swaps this value with another.
Definition optional.h:493
ETL_CONSTEXPR20_STL optional_impl(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:139
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition optional.h:636
etl::enable_if<!etl::is_base_of< this_type, typenameetl::remove_cv< typenameetl::remove_reference< T1 >::type >::type >::value &&!etl::is_same< etl::optional< T >, typenameetl::remove_cv< typenameetl::remove_reference< T1 >::type >::type >::value, T & >::type emplace(const T1 &value1)
Definition optional.h:579
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:434
ETL_CONSTEXPR20_STL ~optional_impl()
Destructor.
Definition optional.h:217
ETL_CONSTEXPR20_STL optional_impl(const optional_impl< T > &other)
Copy constructor.
Definition optional.h:149
ETL_CONSTEXPR20_STL void reset()
Reset back to invalid.
Definition optional.h:504
T & emplace(const T1 &value1, const T2 &value2)
Definition optional.h:598
T & emplace()
Definition optional.h:558
ETL_CONSTEXPR20_STL T & value() ETL_LVALUE_REF_QUALIFIER
Get a reference to the value.
Definition optional.h:408
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition optional.h:1215
T & emplace()
Definition optional.h:1156
ETL_CONSTEXPR14 T & value() ETL_LVALUE_REF_QUALIFIER
Get a reference to the value.
Definition optional.h:1022
etl::enable_if<!etl::is_base_of< this_type, typenameetl::remove_cv< typenameetl::remove_reference< T1 >::type >::type >::value &&!etl::is_same< etl::optional< T >, typenameetl::remove_cv< typenameetl::remove_reference< T1 >::type >::type >::value, T & >::type emplace(const T1 &value1)
Definition optional.h:1177
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:1048
ETL_CONSTEXPR14 optional_impl(const optional_impl< T > &other)
Copy constructor.
Definition optional.h:772
ETL_CONSTEXPR14 const T & value() const ETL_LVALUE_REF_QUALIFIER
Get a const reference to the value.
Definition optional.h:1035
T & emplace(const T1 &value1, const T2 &value2)
Definition optional.h:1196
ETL_CONSTEXPR14 void reset()
Reset back to invalid.
Definition optional.h:1118
ETL_CONSTEXPR14 void swap(optional_impl &other)
Swaps this value with another.
Definition optional.h:1107
ETL_CONSTEXPR14 optional_impl(etl::nullopt_t)
Constructor with nullopt.
Definition optional.h:762
ETL_CONSTEXPR14 optional_impl()
Constructor.
Definition optional.h:753
T & emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition optional.h:1234
Definition optional.h:113
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
Definition optional.h:98
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
enable_if
Definition type_traits_generator.h:1254
is_base_of
Definition type_traits_generator.h:1315
is_same
Definition type_traits_generator.h:1104
remove_cv
Definition type_traits_generator.h:1031
bitset_ext
Definition absolute.h:39
ETL_CONSTEXPR20_STL etl::optional< typename etl::decay< T >::type > make_optional(T &value)
Make an optional.
Definition optional.h:2295
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1190
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1202
bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1151
bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1139
ETL_CONSTEXPR14 enable_if<!etl::is_specialization< TRep2, etl::chrono::duration >::value, etl::chrono::duration< typenameetl::common_type< TRep1, TRep2 >::type, TPeriod1 > >::type operator*(const etl::chrono::duration< TRep1, TPeriod1 > &lhs, const TRep2 &rhs) ETL_NOEXCEPT
Operator *.
Definition duration.h:545
void destroy(const T *const p)
Destroys the object.
Definition variant_pool_generator.h:370
const nullopt_t nullopt
Definition optional.h:77
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1163
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1178
ETL_CONSTEXPR20_STL void swap(etl::optional< T > &lhs, etl::optional< T > &rhs)
Swaps the values.
Definition optional.h:2313