Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
optional.hpp
Go to the documentation of this file.
1// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
2//
3// Use, modification, and distribution is subject to the Boost Software
4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6//
7// The idea and interface is based on Boost.Optional library
8// authored by Fernando Luis Cacciola Carballal
9
10# ifndef ___OPTIONAL_HPP___
11# define ___OPTIONAL_HPP___
12
13# include <utility>
14# include <type_traits>
15# include <initializer_list>
16# include <cassert>
17# include <functional>
18# include <string>
19# include <stdexcept>
20
21# define TR2_OPTIONAL_REQUIRES(...) typename enable_if<__VA_ARGS__::value, bool>::type = false
22
23# if defined __GNUC__ // NOTE: GNUC is also defined for Clang
24# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
25# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
26# elif (__GNUC__ > 4)
27# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
28# endif
29#
30# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
31# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
32# elif (__GNUC__ > 4)
33# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
34# endif
35#
36# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
37# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
38# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
39# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
40# elif (__GNUC__ > 4)
41# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
42# endif
43# endif
44#
45# if defined __clang_major__
46# if (__clang_major__ == 3 && __clang_minor__ >= 5)
47# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
48# elif (__clang_major__ > 3)
49# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
50# endif
51# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
52# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
53# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
54# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
55# endif
56# endif
57#
58# if defined _MSC_VER
59# if (_MSC_VER >= 1900)
60# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
61# endif
62# endif
63
64# if defined __clang__
65# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
66# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
67# else
68# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
69# endif
70# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
71# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
72# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
73# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
74# else
75# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
76# endif
77
78
79# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
80# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
81# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
82# else
83# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
84# define OPTIONAL_CONSTEXPR_INIT_LIST
85# endif
86
87# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L)
88# define OPTIONAL_HAS_MOVE_ACCESSORS 1
89# else
90# define OPTIONAL_HAS_MOVE_ACCESSORS 0
91# endif
92
93# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr
94# if (defined __cplusplus) && (__cplusplus == 201103L)
95# define OPTIONAL_MUTABLE_CONSTEXPR
96# else
97# define OPTIONAL_MUTABLE_CONSTEXPR constexpr
98# endif
99
100namespace std{
101
102namespace experimental{
103
104// BEGIN workaround for missing is_trivially_destructible
105# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
106 // leave it: it is already there
107# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
108 // leave it: it is already there
109# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
110 // leave it: it is already there
111# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
112 // leave it: the user doesn't want it
113# else
114 template <typename T>
115 using is_trivially_destructible = std::has_trivial_destructor<T>;
116# endif
117// END workaround for missing is_trivially_destructible
118
119# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___)
120 // leave it; our metafunctions are already defined.
121# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
122 // leave it; our metafunctions are already defined.
123# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
124 // leave it: it is already there
125# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
126 // leave it: the user doesn't want it
127# else
128
129
130// workaround for missing traits in GCC and CLANG
131template <class T>
133{
134 constexpr static bool value = std::is_nothrow_constructible<T, T&&>::value;
135};
136
137
138template <class T, class U>
140{
141 template <class X, class Y>
142 constexpr static bool has_assign(...) { return false; }
143
144 template <class X, class Y, size_t S = sizeof((std::declval<X>() = std::declval<Y>(), true)) >
145 // the comma operator is necessary for the cases where operator= returns void
146 constexpr static bool has_assign(bool) { return true; }
147
148 constexpr static bool value = has_assign<T, U>(true);
149};
150
151
152template <class T>
154{
155 template <class X, bool has_any_move_assign>
157 constexpr static bool value = false;
158 };
159
160 template <class X>
161 struct has_nothrow_move_assign<X, true> {
162 constexpr static bool value = noexcept( std::declval<X&>() = std::declval<X&&>() );
163 };
164
166};
167// end workaround
168
169
170# endif
171
172
173
174// 20.5.4, optional for object types
175template <class T> class optional;
176
177// 20.5.5, optional for lvalue reference types
178template <class T> class optional<T&>;
179
180
181// workaround: std utility functions aren't constexpr yet
182template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type& t) noexcept
183{
184 return static_cast<T&&>(t);
185}
186
187template <class T> inline constexpr T&& constexpr_forward(typename std::remove_reference<T>::type&& t) noexcept
188{
189 static_assert(!std::is_lvalue_reference<T>::value, "!!");
190 return static_cast<T&&>(t);
191}
192
193template <class T> inline constexpr typename std::remove_reference<T>::type&& constexpr_move(T&& t) noexcept
194{
195 return static_cast<typename std::remove_reference<T>::type&&>(t);
196}
197
198
199#if defined NDEBUG
200# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
201#else
202# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
203#endif
204
205
206namespace detail_
207{
208
209// static_addressof: a constexpr version of addressof
210template <typename T>
212{
213 template <class X>
214 constexpr static bool has_overload(...) { return false; }
215
216 template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
217 constexpr static bool has_overload(bool) { return true; }
218
219 constexpr static bool value = has_overload<T>(true);
220};
221
222template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
223constexpr T* static_addressof(T& ref)
224{
225 return &ref;
226}
227
228template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
230{
231 return std::addressof(ref);
232}
233
234
235// the call to convert<A>(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A
236template <class U>
237constexpr U convert(U v) { return v; }
238
239
240namespace swap_ns
241{
242 using std::swap;
243
244 template <class T>
245 void adl_swap(T& t, T& u) noexcept(noexcept(swap(t, u)))
246 {
247 swap(t, u);
248 }
249
250} // namespace swap_ns
251
252} // namespace detail
253
254
255constexpr struct trivial_init_t{} trivial_init{};
256
257
258// 20.5.6, In-place construction
259constexpr struct in_place_t{} in_place{};
260
261
262// 20.5.7, Disengaged state indicator
264{
265 struct init{};
266 constexpr explicit nullopt_t(init){}
267};
269
270
271// 20.5.8, class bad_optional_access
272class bad_optional_access : public logic_error {
273public:
274 explicit bad_optional_access(const string& what_arg) : logic_error{what_arg} {}
275 explicit bad_optional_access(const char* what_arg) : logic_error{what_arg} {}
276};
277
278
279template <class T>
281{
282 unsigned char dummy_;
284
285 constexpr storage_t( trivial_init_t ) noexcept : dummy_() {};
286
287 template <class... Args>
288 constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
289
291};
292
293
294template <class T>
296{
297 unsigned char dummy_;
299
300 constexpr constexpr_storage_t( trivial_init_t ) noexcept : dummy_() {};
301
302 template <class... Args>
303 constexpr constexpr_storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
304
306};
307
308
309template <class T>
311{
312 bool init_;
314
315 constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {};
316
317 explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
318
319 explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
320
321 template <class... Args> explicit optional_base(in_place_t, Args&&... args)
322 : init_(true), storage_(constexpr_forward<Args>(args)...) {}
323
324 template <class U, class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
325 explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
326 : init_(true), storage_(il, std::forward<Args>(args)...) {}
327
328 ~optional_base() { if (init_) storage_.value_.T::~T(); }
329};
330
331
332template <class T>
334{
335 bool init_;
337
338 constexpr constexpr_optional_base() noexcept : init_(false), storage_(trivial_init) {};
339
340 explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_(v) {}
341
342 explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
343
344 template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
345 : init_(true), storage_(constexpr_forward<Args>(args)...) {}
346
347 template <class U, class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
348 OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
349 : init_(true), storage_(il, std::forward<Args>(args)...) {}
350
352};
353
354template <class T>
355using OptionalBase = typename std::conditional<
357 constexpr_optional_base<typename std::remove_const<T>::type>, // use base with trivial destructor
359>::type;
360
361
362
363template <class T>
364class optional : private OptionalBase<T>
365{
366 static_assert( !std::is_same<typename std::decay<T>::type, nullopt_t>::value, "bad T" );
367 static_assert( !std::is_same<typename std::decay<T>::type, in_place_t>::value, "bad T" );
368
369
370 constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
371 typename std::remove_const<T>::type* dataptr() { return std::addressof(OptionalBase<T>::storage_.value_); }
372 constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
373
374# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
375 constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
376# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
377 OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
378 OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage_.value_; }
379# else
380 T& contained_val() & { return OptionalBase<T>::storage_.value_; }
381 T&& contained_val() && { return std::move(OptionalBase<T>::storage_.value_); }
382# endif
383# else
384 constexpr const T& contained_val() const { return OptionalBase<T>::storage_.value_; }
386# endif
387
388 void clear() noexcept {
389 if (initialized()) dataptr()->T::~T();
391 }
392
393 template <class... Args>
394 void initialize(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...)))
395 {
396 assert(!OptionalBase<T>::init_);
397 ::new (static_cast<void*>(dataptr())) T(std::forward<Args>(args)...);
399 }
400
401 template <class U, class... Args>
402 void initialize(std::initializer_list<U> il, Args&&... args) noexcept(noexcept(T(il, std::forward<Args>(args)...)))
403 {
404 assert(!OptionalBase<T>::init_);
405 ::new (static_cast<void*>(dataptr())) T(il, std::forward<Args>(args)...);
407 }
408
409public:
410 typedef T value_type;
411
412 // 20.5.5.1, constructors
413 constexpr optional() noexcept : OptionalBase<T>() {};
414 constexpr optional(nullopt_t) noexcept : OptionalBase<T>() {};
415
416 optional(const optional& rhs)
417 : OptionalBase<T>()
418 {
419 if (rhs.initialized()) {
420 ::new (static_cast<void*>(dataptr())) T(*rhs);
422 }
423 }
424
426 : OptionalBase<T>()
427 {
428 if (rhs.initialized()) {
429 ::new (static_cast<void*>(dataptr())) T(std::move(*rhs));
431 }
432 }
433
434 constexpr optional(const T& v) : OptionalBase<T>(v) {}
435
436 constexpr optional(T&& v) : OptionalBase<T>(constexpr_move(v)) {}
437
438 template <class... Args>
439 explicit constexpr optional(in_place_t, Args&&... args)
440 : OptionalBase<T>(in_place_t{}, constexpr_forward<Args>(args)...) {}
441
442 template <class U, class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
443 OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, std::initializer_list<U> il, Args&&... args)
444 : OptionalBase<T>(in_place_t{}, il, constexpr_forward<Args>(args)...) {}
445
446 // 20.5.4.2, Destructor
447 ~optional() = default;
448
449 // 20.5.4.3, assignment
451 {
452 clear();
453 return *this;
454 }
455
457 {
458 if (initialized() == true && rhs.initialized() == false) clear();
459 else if (initialized() == false && rhs.initialized() == true) initialize(*rhs);
460 else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs;
461 return *this;
462 }
463
466 {
467 if (initialized() == true && rhs.initialized() == false) clear();
468 else if (initialized() == false && rhs.initialized() == true) initialize(std::move(*rhs));
469 else if (initialized() == true && rhs.initialized() == true) contained_val() = std::move(*rhs);
470 return *this;
471 }
472
473 template <class U>
474 auto operator=(U&& v)
475 -> typename enable_if
476 <
477 is_same<typename decay<U>::type, T>::value,
478 optional&
479 >::type
480 {
481 if (initialized()) { contained_val() = std::forward<U>(v); }
482 else { initialize(std::forward<U>(v)); }
483 return *this;
484 }
485
486
487 template <class... Args>
488 void emplace(Args&&... args)
489 {
490 clear();
491 initialize(std::forward<Args>(args)...);
492 }
493
494 template <class U, class... Args>
495 void emplace(initializer_list<U> il, Args&&... args)
496 {
497 clear();
498 initialize<U, Args...>(il, std::forward<Args>(args)...);
499 }
500
501 // 20.5.4.4, Swap
503 && noexcept(detail_::swap_ns::adl_swap(declval<T&>(), declval<T&>())))
504 {
505 if (initialized() == true && rhs.initialized() == false) { rhs.initialize(std::move(**this)); clear(); }
506 else if (initialized() == false && rhs.initialized() == true) { initialize(std::move(*rhs)); rhs.clear(); }
507 else if (initialized() == true && rhs.initialized() == true) { using std::swap; swap(**this, *rhs); }
508 }
509
510 // 20.5.4.5, Observers
511
512 explicit constexpr operator bool() const noexcept { return initialized(); }
513 constexpr bool has_value() const noexcept { return initialized(); }
514
515 constexpr T const* operator ->() const {
517 }
518
519# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
520
522 assert (initialized());
523 return dataptr();
524 }
525
526 constexpr T const& operator *() const& {
528 }
529
531 assert (initialized());
532 return contained_val();
533 }
534
536 assert (initialized());
538 }
539
540 constexpr T const& value() const& {
541 return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
542 }
543
545 return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
546 }
547
549 if (!initialized()) throw bad_optional_access("bad optional access");
550 return std::move(contained_val());
551 }
552
553# else
554
556 assert (initialized());
557 return dataptr();
558 }
559
560 constexpr T const& operator *() const {
562 }
563
565 assert (initialized());
566 return contained_val();
567 }
568
569 constexpr T const& value() const {
570 return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
571 }
572
573 T& value() {
574 return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
575 }
576
577# endif
578
579# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
580
581 template <class V>
582 constexpr T value_or(V&& v) const&
583 {
584 return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
585 }
586
587# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
588
589 template <class V>
591 {
592 return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
593 }
594
595# else
596
597 template <class V>
598 T value_or(V&& v) &&
599 {
600 return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
601 }
602
603# endif
604
605# else
606
607 template <class V>
608 constexpr T value_or(V&& v) const
609 {
610 return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
611 }
612
613# endif
614
615 // 20.6.3.6, modifiers
616 void reset() noexcept { clear(); }
617};
618
619
620template <class T>
621class optional<T&>
622{
623 static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
624 static_assert( !std::is_same<T, in_place_t>::value, "bad T" );
626
627public:
628
629 // 20.5.5.1, construction/destruction
630 constexpr optional() noexcept : ref(nullptr) {}
631
632 constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
633
634 constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
635
636 optional(T&&) = delete;
637
638 constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
639
640 explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
641
642 explicit optional(in_place_t, T&&) = delete;
643
644 ~optional() = default;
645
646 // 20.5.5.2, mutation
648 ref = nullptr;
649 return *this;
650 }
651
652 // optional& operator=(const optional& rhs) noexcept {
653 // ref = rhs.ref;
654 // return *this;
655 // }
656
657 // optional& operator=(optional&& rhs) noexcept {
658 // ref = rhs.ref;
659 // return *this;
660 // }
661
662 template <typename U>
663 auto operator=(U&& rhs) noexcept
664 -> typename enable_if
665 <
666 is_same<typename decay<U>::type, optional<T&>>::value,
667 optional&
668 >::type
669 {
670 ref = rhs.ref;
671 return *this;
672 }
673
674 template <typename U>
675 auto operator=(U&& rhs) noexcept
676 -> typename enable_if
677 <
678 !is_same<typename decay<U>::type, optional<T&>>::value,
679 optional&
680 >::type
681 = delete;
682
683 void emplace(T& v) noexcept {
685 }
686
687 void emplace(T&&) = delete;
688
689
690 void swap(optional<T&>& rhs) noexcept
691 {
692 std::swap(ref, rhs.ref);
693 }
694
695 // 20.5.5.3, observers
696 constexpr T* operator->() const {
697 return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
698 }
699
700 constexpr T& operator*() const {
701 return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
702 }
703
704 constexpr T& value() const {
705 return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
706 }
707
708 explicit constexpr operator bool() const noexcept {
709 return ref != nullptr;
710 }
711
712 constexpr bool has_value() const noexcept {
713 return ref != nullptr;
714 }
715
716 template <class V>
717 constexpr typename decay<T>::type value_or(V&& v) const
718 {
719 return *this ? **this : detail_::convert<typename decay<T>::type>(constexpr_forward<V>(v));
720 }
721
722 // x.x.x.x, modifiers
723 void reset() noexcept { ref = nullptr; }
724};
725
726
727template <class T>
728class optional<T&&>
729{
730 static_assert( sizeof(T) == 0, "optional rvalue references disallowed" );
731};
732
733
734// 20.5.8, Relational operators
735template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y)
736{
737 return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
738}
739
740template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y)
741{
742 return !(x == y);
743}
744
745template <class T> constexpr bool operator<(const optional<T>& x, const optional<T>& y)
746{
747 return (!y) ? false : (!x) ? true : *x < *y;
748}
749
750template <class T> constexpr bool operator>(const optional<T>& x, const optional<T>& y)
751{
752 return (y < x);
753}
754
755template <class T> constexpr bool operator<=(const optional<T>& x, const optional<T>& y)
756{
757 return !(y < x);
758}
759
760template <class T> constexpr bool operator>=(const optional<T>& x, const optional<T>& y)
761{
762 return !(x < y);
763}
764
765
766// 20.5.9, Comparison with nullopt
767template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept
768{
769 return (!x);
770}
771
772template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept
773{
774 return (!x);
775}
776
777template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept
778{
779 return bool(x);
780}
781
782template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept
783{
784 return bool(x);
785}
786
787template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept
788{
789 return false;
790}
791
792template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept
793{
794 return bool(x);
795}
796
797template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept
798{
799 return (!x);
800}
801
802template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept
803{
804 return true;
805}
806
807template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept
808{
809 return bool(x);
810}
811
812template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept
813{
814 return false;
815}
816
817template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept
818{
819 return true;
820}
821
822template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept
823{
824 return (!x);
825}
826
827
828
829// 20.5.10, Comparison with T
830template <class T> constexpr bool operator==(const optional<T>& x, const T& v)
831{
832 return bool(x) ? *x == v : false;
833}
834
835template <class T> constexpr bool operator==(const T& v, const optional<T>& x)
836{
837 return bool(x) ? v == *x : false;
838}
839
840template <class T> constexpr bool operator!=(const optional<T>& x, const T& v)
841{
842 return bool(x) ? *x != v : true;
843}
844
845template <class T> constexpr bool operator!=(const T& v, const optional<T>& x)
846{
847 return bool(x) ? v != *x : true;
848}
849
850template <class T> constexpr bool operator<(const optional<T>& x, const T& v)
851{
852 return bool(x) ? *x < v : true;
853}
854
855template <class T> constexpr bool operator>(const T& v, const optional<T>& x)
856{
857 return bool(x) ? v > *x : true;
858}
859
860template <class T> constexpr bool operator>(const optional<T>& x, const T& v)
861{
862 return bool(x) ? *x > v : false;
863}
864
865template <class T> constexpr bool operator<(const T& v, const optional<T>& x)
866{
867 return bool(x) ? v < *x : false;
868}
869
870template <class T> constexpr bool operator>=(const optional<T>& x, const T& v)
871{
872 return bool(x) ? *x >= v : false;
873}
874
875template <class T> constexpr bool operator<=(const T& v, const optional<T>& x)
876{
877 return bool(x) ? v <= *x : false;
878}
879
880template <class T> constexpr bool operator<=(const optional<T>& x, const T& v)
881{
882 return bool(x) ? *x <= v : true;
883}
884
885template <class T> constexpr bool operator>=(const T& v, const optional<T>& x)
886{
887 return bool(x) ? v >= *x : true;
888}
889
890
891// Comparison of optional<T&> with T
892template <class T> constexpr bool operator==(const optional<T&>& x, const T& v)
893{
894 return bool(x) ? *x == v : false;
895}
896
897template <class T> constexpr bool operator==(const T& v, const optional<T&>& x)
898{
899 return bool(x) ? v == *x : false;
900}
901
902template <class T> constexpr bool operator!=(const optional<T&>& x, const T& v)
903{
904 return bool(x) ? *x != v : true;
905}
906
907template <class T> constexpr bool operator!=(const T& v, const optional<T&>& x)
908{
909 return bool(x) ? v != *x : true;
910}
911
912template <class T> constexpr bool operator<(const optional<T&>& x, const T& v)
913{
914 return bool(x) ? *x < v : true;
915}
916
917template <class T> constexpr bool operator>(const T& v, const optional<T&>& x)
918{
919 return bool(x) ? v > *x : true;
920}
921
922template <class T> constexpr bool operator>(const optional<T&>& x, const T& v)
923{
924 return bool(x) ? *x > v : false;
925}
926
927template <class T> constexpr bool operator<(const T& v, const optional<T&>& x)
928{
929 return bool(x) ? v < *x : false;
930}
931
932template <class T> constexpr bool operator>=(const optional<T&>& x, const T& v)
933{
934 return bool(x) ? *x >= v : false;
935}
936
937template <class T> constexpr bool operator<=(const T& v, const optional<T&>& x)
938{
939 return bool(x) ? v <= *x : false;
940}
941
942template <class T> constexpr bool operator<=(const optional<T&>& x, const T& v)
943{
944 return bool(x) ? *x <= v : true;
945}
946
947template <class T> constexpr bool operator>=(const T& v, const optional<T&>& x)
948{
949 return bool(x) ? v >= *x : true;
950}
951
952// Comparison of optional<T const&> with T
953template <class T> constexpr bool operator==(const optional<const T&>& x, const T& v)
954{
955 return bool(x) ? *x == v : false;
956}
957
958template <class T> constexpr bool operator==(const T& v, const optional<const T&>& x)
959{
960 return bool(x) ? v == *x : false;
961}
962
963template <class T> constexpr bool operator!=(const optional<const T&>& x, const T& v)
964{
965 return bool(x) ? *x != v : true;
966}
967
968template <class T> constexpr bool operator!=(const T& v, const optional<const T&>& x)
969{
970 return bool(x) ? v != *x : true;
971}
972
973template <class T> constexpr bool operator<(const optional<const T&>& x, const T& v)
974{
975 return bool(x) ? *x < v : true;
976}
977
978template <class T> constexpr bool operator>(const T& v, const optional<const T&>& x)
979{
980 return bool(x) ? v > *x : true;
981}
982
983template <class T> constexpr bool operator>(const optional<const T&>& x, const T& v)
984{
985 return bool(x) ? *x > v : false;
986}
987
988template <class T> constexpr bool operator<(const T& v, const optional<const T&>& x)
989{
990 return bool(x) ? v < *x : false;
991}
992
993template <class T> constexpr bool operator>=(const optional<const T&>& x, const T& v)
994{
995 return bool(x) ? *x >= v : false;
996}
997
998template <class T> constexpr bool operator<=(const T& v, const optional<const T&>& x)
999{
1000 return bool(x) ? v <= *x : false;
1001}
1002
1003template <class T> constexpr bool operator<=(const optional<const T&>& x, const T& v)
1004{
1005 return bool(x) ? *x <= v : true;
1006}
1007
1008template <class T> constexpr bool operator>=(const T& v, const optional<const T&>& x)
1009{
1010 return bool(x) ? v >= *x : true;
1011}
1012
1013
1014// 20.5.12, Specialized algorithms
1015template <class T>
1016void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)))
1017{
1018 x.swap(y);
1019}
1020
1021
1022template <class T>
1024{
1025 return optional<typename decay<T>::type>(constexpr_forward<T>(v));
1026}
1027
1028template <class X>
1029constexpr optional<X&> make_optional(reference_wrapper<X> v)
1030{
1031 return optional<X&>(v.get());
1032}
1033
1034
1035} // namespace experimental
1036} // namespace std
1037
1038namespace std
1039{
1040 template <typename T>
1042 {
1043 typedef typename hash<T>::result_type result_type;
1045
1046 constexpr result_type operator()(argument_type const& arg) const {
1047 return arg ? std::hash<T>{}(*arg) : result_type{};
1048 }
1049 };
1050
1051 template <typename T>
1052 struct hash<std::experimental::optional<T&>>
1053 {
1054 typedef typename hash<T>::result_type result_type;
1056
1057 constexpr result_type operator()(argument_type const& arg) const {
1058 return arg ? std::hash<T>{}(*arg) : result_type{};
1059 }
1060 };
1061}
1062
1063# undef TR2_OPTIONAL_REQUIRES
1064# undef TR2_OPTIONAL_ASSERTED_EXPRESSION
1065
1066# endif //___OPTIONAL_HPP___
bad_optional_access(const string &what_arg)
Definition optional.hpp:274
bad_optional_access(const char *what_arg)
Definition optional.hpp:275
constexpr decay< T >::type value_or(V &&v) const
Definition optional.hpp:717
constexpr optional(T &v) noexcept
Definition optional.hpp:634
auto operator=(U &&rhs) noexcept -> typename enable_if< !is_same< typename decay< U >::type, optional< T & > >::value, optional & >::type=delete
constexpr optional(in_place_t, T &v) noexcept
Definition optional.hpp:640
constexpr T & value() const
Definition optional.hpp:704
void swap(optional< T & > &rhs) noexcept
Definition optional.hpp:690
constexpr optional(nullopt_t) noexcept
Definition optional.hpp:632
optional & operator=(nullopt_t) noexcept
Definition optional.hpp:647
constexpr bool has_value() const noexcept
Definition optional.hpp:712
constexpr T * operator->() const
Definition optional.hpp:696
constexpr T & operator*() const
Definition optional.hpp:700
optional(in_place_t, T &&)=delete
constexpr optional(const optional &rhs) noexcept
Definition optional.hpp:638
constexpr optional() noexcept
Definition optional.hpp:630
auto operator=(U &&rhs) noexcept -> typename enable_if< is_same< typename decay< U >::type, optional< T & > >::value, optional & >::type
Definition optional.hpp:663
optional(const optional &rhs)
Definition optional.hpp:416
constexpr const T & contained_val() const
Definition optional.hpp:384
constexpr T const & value() const
Definition optional.hpp:569
constexpr optional(T &&v)
Definition optional.hpp:436
constexpr optional() noexcept
Definition optional.hpp:413
void emplace(initializer_list< U > il, Args &&... args)
Definition optional.hpp:495
constexpr const T * dataptr() const
Definition optional.hpp:372
constexpr optional(nullopt_t) noexcept
Definition optional.hpp:414
OPTIONAL_CONSTEXPR_INIT_LIST optional(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition optional.hpp:443
void initialize(std::initializer_list< U > il, Args &&... args) noexcept(noexcept(T(il, std::forward< Args >(args)...)))
Definition optional.hpp:402
void emplace(Args &&... args)
Definition optional.hpp:488
constexpr T value_or(V &&v) const
Definition optional.hpp:608
optional & operator=(nullopt_t) noexcept
Definition optional.hpp:450
void swap(optional< T > &rhs) noexcept(is_nothrow_move_constructible< T >::value &&noexcept(detail_::swap_ns::adl_swap(declval< T & >(), declval< T & >())))
Definition optional.hpp:502
optional & operator=(optional &&rhs) noexcept(is_nothrow_move_assignable< T >::value &&is_nothrow_move_constructible< T >::value)
Definition optional.hpp:464
constexpr T const * operator->() const
Definition optional.hpp:515
optional & operator=(const optional &rhs)
Definition optional.hpp:456
constexpr bool has_value() const noexcept
Definition optional.hpp:513
constexpr T const & operator*() const
Definition optional.hpp:560
constexpr optional(in_place_t, Args &&... args)
Definition optional.hpp:439
void initialize(Args &&... args) noexcept(noexcept(T(std::forward< Args >(args)...)))
Definition optional.hpp:394
constexpr bool initialized() const noexcept
Definition optional.hpp:370
constexpr optional(const T &v)
Definition optional.hpp:434
std::remove_const< T >::type * dataptr()
Definition optional.hpp:371
optional(optional &&rhs) noexcept(is_nothrow_move_constructible< T >::value)
Definition optional.hpp:425
auto operator=(U &&v) -> typename enable_if< is_same< typename decay< U >::type, T >::value, optional & >::type
Definition optional.hpp:474
Double_t y[n]
Double_t x[n]
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
double T(double x)
void convert(AxisAngle const &from, EulerAngles &to)
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
void adl_swap(T &t, T &u) noexcept(noexcept(swap(t, u)))
Definition optional.hpp:245
constexpr T * static_addressof(T &ref)
Definition optional.hpp:223
constexpr U convert(U v)
Definition optional.hpp:237
constexpr bool operator==(const optional< T > &x, const optional< T > &y)
Definition optional.hpp:735
constexpr bool operator>(const optional< T > &x, const optional< T > &y)
Definition optional.hpp:750
constexpr bool operator<(const optional< T > &x, const optional< T > &y)
Definition optional.hpp:745
constexpr bool operator>=(const optional< T > &x, const optional< T > &y)
Definition optional.hpp:760
constexpr T && constexpr_forward(typename std::remove_reference< T >::type &t) noexcept
Definition optional.hpp:182
typename std::conditional< is_trivially_destructible< T >::value, constexpr_optional_base< typename std::remove_const< T >::type >, optional_base< typename std::remove_const< T >::type > >::type OptionalBase
Definition optional.hpp:359
std::has_trivial_destructor< T > is_trivially_destructible
Definition optional.hpp:115
constexpr optional< typename decay< T >::type > make_optional(T &&v)
constexpr struct std::experimental::trivial_init_t trivial_init
constexpr std::remove_reference< T >::type && constexpr_move(T &&t) noexcept
Definition optional.hpp:193
constexpr bool operator!=(const optional< T > &x, const optional< T > &y)
Definition optional.hpp:740
constexpr struct std::experimental::in_place_t in_place
constexpr nullopt_t nullopt
Definition optional.hpp:268
constexpr bool operator<=(const optional< T > &x, const optional< T > &y)
Definition optional.hpp:755
STL namespace.
#define TR2_OPTIONAL_REQUIRES(...)
Definition optional.hpp:21
#define OPTIONAL_CONSTEXPR_INIT_LIST
Definition optional.hpp:84
#define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR)
Definition optional.hpp:202
#define OPTIONAL_MUTABLE_CONSTEXPR
Definition optional.hpp:97
v
constexpr constexpr_optional_base(in_place_t, Args &&... args)
Definition optional.hpp:344
constexpr constexpr_optional_base(const T &v)
Definition optional.hpp:340
OPTIONAL_CONSTEXPR_INIT_LIST constexpr_optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition optional.hpp:348
static constexpr bool value
Definition optional.hpp:148
static constexpr bool has_assign(bool)
Definition optional.hpp:146
static constexpr bool has_assign(...)
Definition optional.hpp:142
constexpr optional_base() noexcept
Definition optional.hpp:315
optional_base(in_place_t, Args &&... args)
Definition optional.hpp:321
optional_base(in_place_t, std::initializer_list< U > il, Args &&... args)
Definition optional.hpp:325
constexpr optional_base(const T &v)
Definition optional.hpp:317
constexpr result_type operator()(argument_type const &arg) const
std::experimental::optional< T > argument_type
constexpr result_type operator()(argument_type const &arg) const
std::experimental::optional< T & > argument_type
constexpr constexpr_storage_t(trivial_init_t) noexcept
Definition optional.hpp:300
constexpr constexpr_storage_t(Args &&... args)
Definition optional.hpp:303
constexpr storage_t(trivial_init_t) noexcept
Definition optional.hpp:285
constexpr storage_t(Args &&... args)
Definition optional.hpp:288