Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / libc++ / trunk / include / experimental / optional
1 // -*- C++ -*-
2 //===-------------------------- optional ----------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _LIBCPP_OPTIONAL
12 #define _LIBCPP_OPTIONAL
13
14 /*
15     optional synopsis
16
17 // C++1y
18
19 #include <initializer_list>
20
21 namespace std { namespace experimental {
22
23 // optional for object types
24 template <class T>
25 class optional
26 {
27 public:
28     typedef T value_type;
29
30     // constructors
31     constexpr optional() noexcept;
32     constexpr optional(nullopt_t) noexcept;
33     optional(const optional&);
34     optional(optional&&) noexcept(is_nothrow_move_constructible<T>::value);
35     constexpr optional(const T&);
36     constexpr optional(T&&);
37     template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
38     template <class U, class... Args>
39         constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
40
41     // destructor
42     ~optional();
43
44     // assignment
45     optional& operator=(nullopt_t) noexcept;
46     optional& operator=(const optional&);
47     optional& operator=(optional&&)
48         noexcept(is_nothrow_move_assignable<T>::value &&
49                  is_nothrow_move_constructible<T>::value);
50     template <class U> optional& operator=(U&&);
51     template <class... Args> void emplace(Args&&...);
52     template <class U, class... Args> void emplace(initializer_list<U>, Args&&...);
53
54     // swap
55     void swap(optional&)
56         noexcept(is_nothrow_move_constructible<T>::value &&
57                  noexcept(swap(declval<T&>(), declval<T&>())));
58
59     // observers
60     constexpr T const* operator->() const;
61     T* operator->();
62     constexpr T const& operator*() const;
63     T& operator*();
64     constexpr explicit operator bool() const noexcept;
65     constexpr T const& value() const;
66     T& value();
67     template <class U> constexpr T value_or(U&&) const&;
68     template <class U> T value_or(U&&) &&;
69 };
70
71 // In-place construction
72 struct in_place_t{};
73 constexpr in_place_t in_place{};
74
75 // Disengaged state indicator
76 struct nullopt_t{see below};
77 constexpr nullopt_t nullopt(unspecified);
78
79 // class bad_optional_access
80 class bad_optional_access
81     : public logic_error
82 {
83 public:
84     explicit bad_optional_access(const string& what_arg);
85     explicit bad_optional_access(const char* what_arg);
86 };
87
88 // Relational operators
89 template <class T> constexpr bool operator==(const optional<T>&, const optional<T>&);
90 template <class T> constexpr bool operator< (const optional<T>&, const optional<T>&);
91
92 // Comparison with nullopt
93 template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
94 template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
95 template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
96 template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
97
98 // Comparison with T
99 template <class T> constexpr bool operator==(const optional<T>&, const T&);
100 template <class T> constexpr bool operator==(const T&, const optional<T>&);
101 template <class T> constexpr bool operator<(const optional<T>&, const T&);
102 template <class T> constexpr bool operator<(const T&, const optional<T>&);
103
104 // Specialized algorithms
105 template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below);
106 template <class T> constexpr optional<typename decay<T>::type> make_optional(T&&);
107
108 // hash support
109 template <class T> struct hash;
110 template <class T> struct hash<optional<T>>;
111
112 }}  // std::experimental
113
114 */
115
116 #include <__config>
117 #include <functional>
118 #include <stdexcept>
119
120 namespace std { namespace experimental {
121
122 class _LIBCPP_EXCEPTION_ABI bad_optional_access
123     : public logic_error
124 {
125 public:
126 #if _LIBCPP_STD_VER > 11
127     _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const string& __arg)
128         : logic_error(__arg) {}
129     _LIBCPP_INLINE_VISIBILITY explicit bad_optional_access(const char* __arg)
130         : logic_error(__arg) {}
131     _LIBCPP_INLINE_VISIBILITY bad_optional_access(const bad_optional_access&) noexcept = default;
132     _LIBCPP_INLINE_VISIBILITY bad_optional_access& operator=(const bad_optional_access&) noexcept = default;
133 #else
134 private:
135     bad_optional_access(const bad_optional_access&);
136     bad_optional_access& operator=(const bad_optional_access&);
137 public:
138 #endif  // _LIBCPP_STD_VER > 11
139     // Get the key function ~bad_optional_access() into the dylib even if not compiling for C++1y
140     virtual ~bad_optional_access() _NOEXCEPT;
141 };
142
143 }}  // std::experimental
144
145 #if _LIBCPP_STD_VER > 11
146
147 #include <initializer_list>
148 #include <type_traits>
149 #include <new>
150 #include <__functional_base>
151
152 #include <__undef_min_max>
153
154 #include <__debug>
155
156 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
157 #pragma GCC system_header
158 #endif
159
160 namespace std { namespace experimental { inline namespace __library_fundamentals_v1 {
161
162 struct in_place_t {};
163 constexpr in_place_t in_place{};
164
165 struct nullopt_t
166 {
167     explicit constexpr nullopt_t(int) noexcept {}
168 };
169
170 constexpr nullopt_t nullopt{0};
171
172 template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
173 class __optional_storage
174 {
175 protected:
176     typedef _Tp value_type;
177     union
178     {
179         char __null_state_;
180         value_type __val_;
181     };
182     bool __engaged_ = false;
183
184     _LIBCPP_INLINE_VISIBILITY
185     ~__optional_storage()
186     {
187         if (__engaged_)
188             __val_.~value_type();
189     }
190
191     _LIBCPP_INLINE_VISIBILITY
192     constexpr __optional_storage() noexcept
193         :  __null_state_('\0') {}
194
195     _LIBCPP_INLINE_VISIBILITY
196     __optional_storage(const __optional_storage& __x)
197         :  __engaged_(__x.__engaged_)
198         {
199             if (__engaged_)
200                 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
201         }
202
203     _LIBCPP_INLINE_VISIBILITY
204     __optional_storage(__optional_storage&& __x)
205                       noexcept(is_nothrow_move_constructible<value_type>::value)
206         :  __engaged_(__x.__engaged_)
207         {
208             if (__engaged_)
209                 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
210         }
211
212     _LIBCPP_INLINE_VISIBILITY
213     constexpr __optional_storage(const value_type& __v)
214         :  __val_(__v),
215            __engaged_(true) {}
216
217     _LIBCPP_INLINE_VISIBILITY
218     constexpr __optional_storage(value_type&& __v)
219         :  __val_(_VSTD::move(__v)),
220            __engaged_(true) {}
221
222     template <class... _Args>
223     _LIBCPP_INLINE_VISIBILITY
224     constexpr
225     explicit __optional_storage(in_place_t, _Args&&... __args)
226        :  __val_(_VSTD::forward<_Args>(__args)...),
227            __engaged_(true) {}
228 };
229
230 template <class _Tp>
231 class __optional_storage<_Tp, true>
232 {
233 protected:
234     typedef _Tp value_type;
235     union
236     {
237         char __null_state_;
238         value_type __val_;
239     };
240     bool __engaged_ = false;
241
242     _LIBCPP_INLINE_VISIBILITY
243     constexpr __optional_storage() noexcept
244         :  __null_state_('\0') {}
245
246     _LIBCPP_INLINE_VISIBILITY
247     __optional_storage(const __optional_storage& __x)
248         :  __engaged_(__x.__engaged_)
249         {
250             if (__engaged_)
251                 ::new(_VSTD::addressof(__val_)) value_type(__x.__val_);
252         }
253
254     _LIBCPP_INLINE_VISIBILITY
255     __optional_storage(__optional_storage&& __x)
256                       noexcept(is_nothrow_move_constructible<value_type>::value)
257         :  __engaged_(__x.__engaged_)
258         {
259             if (__engaged_)
260                 ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_));
261         }
262
263     _LIBCPP_INLINE_VISIBILITY
264     constexpr __optional_storage(const value_type& __v)
265         :  __val_(__v),
266            __engaged_(true) {}
267
268     _LIBCPP_INLINE_VISIBILITY
269     constexpr __optional_storage(value_type&& __v)
270         :  __val_(_VSTD::move(__v)),
271            __engaged_(true) {}
272
273     template <class... _Args>
274     _LIBCPP_INLINE_VISIBILITY
275     constexpr
276     explicit __optional_storage(in_place_t, _Args&&... __args)
277        :  __val_(_VSTD::forward<_Args>(__args)...),
278            __engaged_(true) {}
279 };
280
281 template <class _Tp>
282 class optional
283     : private __optional_storage<_Tp>
284 {
285     typedef __optional_storage<_Tp> __base;
286 public:
287     typedef _Tp value_type;
288
289     static_assert(!is_reference<value_type>::value,
290               "Instantiation of optional with a reference type is ill-formed.");
291     static_assert(!is_same<typename remove_cv<value_type>::type, in_place_t>::value,
292               "Instantiation of optional with a in_place_t type is ill-formed.");
293     static_assert(!is_same<typename remove_cv<value_type>::type, nullopt_t>::value,
294               "Instantiation of optional with a nullopt_t type is ill-formed.");
295     static_assert(is_object<value_type>::value,
296         "Instantiation of optional with a non-object type is undefined behavior.");
297     static_assert(is_nothrow_destructible<value_type>::value,
298         "Instantiation of optional with an object type that is not noexcept destructible is undefined behavior.");
299
300     _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
301     _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default;
302     _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default;
303     _LIBCPP_INLINE_VISIBILITY ~optional() = default;
304     _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
305     _LIBCPP_INLINE_VISIBILITY constexpr optional(const value_type& __v)
306         : __base(__v) {}
307     _LIBCPP_INLINE_VISIBILITY constexpr optional(value_type&& __v)
308         : __base(_VSTD::move(__v)) {}
309
310     template <class... _Args,
311               class = typename enable_if
312                       <
313                            is_constructible<value_type, _Args...>::value
314                       >::type
315              >
316     _LIBCPP_INLINE_VISIBILITY
317     constexpr
318     explicit optional(in_place_t, _Args&&... __args)
319         : __base(in_place, _VSTD::forward<_Args>(__args)...) {}
320
321     template <class _Up, class... _Args,
322               class = typename enable_if
323                       <
324                            is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
325                       >::type
326              >
327     _LIBCPP_INLINE_VISIBILITY
328     constexpr
329     explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
330         : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
331
332     _LIBCPP_INLINE_VISIBILITY
333     optional& operator=(nullopt_t) noexcept
334     {
335         if (this->__engaged_)
336         {
337             this->__val_.~value_type();
338             this->__engaged_ = false;
339         }
340         return *this;
341     }
342
343     _LIBCPP_INLINE_VISIBILITY
344     optional&
345     operator=(const optional& __opt)
346     {
347         if (this->__engaged_ == __opt.__engaged_)
348         {
349             if (this->__engaged_)
350                 this->__val_ = __opt.__val_;
351         }
352         else
353         {
354             if (this->__engaged_)
355                 this->__val_.~value_type();
356             else
357                 ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_);
358             this->__engaged_ = __opt.__engaged_;
359         }
360         return *this;
361     }
362
363     _LIBCPP_INLINE_VISIBILITY
364     optional&
365     operator=(optional&& __opt)
366         noexcept(is_nothrow_move_assignable<value_type>::value &&
367                  is_nothrow_move_constructible<value_type>::value)
368     {
369         if (this->__engaged_ == __opt.__engaged_)
370         {
371             if (this->__engaged_)
372                 this->__val_ = _VSTD::move(__opt.__val_);
373         }
374         else
375         {
376             if (this->__engaged_)
377                 this->__val_.~value_type();
378             else
379                 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
380             this->__engaged_ = __opt.__engaged_;
381         }
382         return *this;
383     }
384
385     template <class _Up,
386               class = typename enable_if
387                       <
388                           is_same<typename remove_reference<_Up>::type, value_type>::value &&
389                           is_constructible<value_type, _Up>::value &&
390                           is_assignable<value_type&, _Up>::value
391                       >::type
392              >
393     _LIBCPP_INLINE_VISIBILITY
394     optional&
395     operator=(_Up&& __v)
396     {
397         if (this->__engaged_)
398             this->__val_ = _VSTD::forward<_Up>(__v);
399         else
400         {
401             ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v));
402             this->__engaged_ = true;
403         }
404         return *this;
405     }
406
407     template <class... _Args,
408               class = typename enable_if
409                       <
410                           is_constructible<value_type, _Args...>::value
411                       >::type
412              >
413     _LIBCPP_INLINE_VISIBILITY
414     void
415     emplace(_Args&&... __args)
416     {
417         *this = nullopt;
418         ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
419         this->__engaged_ = true;
420     }
421
422     template <class _Up, class... _Args,
423               class = typename enable_if
424                       <
425                           is_constructible<value_type, initializer_list<_Up>&, _Args...>::value
426                       >::type
427              >
428     _LIBCPP_INLINE_VISIBILITY
429     void
430     emplace(initializer_list<_Up> __il, _Args&&... __args)
431     {
432         *this = nullopt;
433         ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...);
434         this->__engaged_ = true;
435     }
436
437     _LIBCPP_INLINE_VISIBILITY
438     void
439     swap(optional& __opt)
440         noexcept(is_nothrow_move_constructible<value_type>::value &&
441                  __is_nothrow_swappable<value_type>::value)
442     {
443         using _VSTD::swap;
444         if (this->__engaged_ == __opt.__engaged_)
445         {
446             if (this->__engaged_)
447                 swap(this->__val_, __opt.__val_);
448         }
449         else
450         {
451             if (this->__engaged_)
452             {
453                 ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_));
454                 this->__val_.~value_type();
455             }
456             else
457             {
458                 ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_));
459                 __opt.__val_.~value_type();
460             }
461             swap(this->__engaged_, __opt.__engaged_);
462         }
463     }
464
465     _LIBCPP_INLINE_VISIBILITY
466     constexpr
467     value_type const*
468     operator->() const
469     {
470         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
471         return __operator_arrow(__has_operator_addressof<value_type>{});
472     }
473
474     _LIBCPP_INLINE_VISIBILITY
475     value_type*
476     operator->()
477     {
478         _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value");
479         return _VSTD::addressof(this->__val_);
480     }
481
482     _LIBCPP_INLINE_VISIBILITY
483     constexpr
484     const value_type&
485     operator*() const
486     {
487         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
488         return this->__val_;
489     }
490
491     _LIBCPP_INLINE_VISIBILITY
492     value_type&
493     operator*()
494     {
495         _LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
496         return this->__val_;
497     }
498
499     _LIBCPP_INLINE_VISIBILITY
500     constexpr explicit operator bool() const noexcept {return this->__engaged_;}
501
502     _LIBCPP_INLINE_VISIBILITY
503     constexpr value_type const& value() const
504     {
505         if (!this->__engaged_)
506             throw bad_optional_access("optional<T>::value: not engaged");
507         return this->__val_;
508     }
509
510     _LIBCPP_INLINE_VISIBILITY
511     value_type& value()
512     {
513         if (!this->__engaged_)
514             throw bad_optional_access("optional<T>::value: not engaged");
515         return this->__val_;
516     }
517
518     template <class _Up>
519     _LIBCPP_INLINE_VISIBILITY
520     constexpr value_type value_or(_Up&& __v) const&
521     {
522         static_assert(is_copy_constructible<value_type>::value,
523                       "optional<T>::value_or: T must be copy constructible");
524         static_assert(is_convertible<_Up, value_type>::value,
525                       "optional<T>::value_or: U must be convertible to T");
526         return this->__engaged_ ? this->__val_ :
527                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
528     }
529
530     template <class _Up>
531     _LIBCPP_INLINE_VISIBILITY
532     value_type value_or(_Up&& __v) &&
533     {
534         static_assert(is_move_constructible<value_type>::value,
535                       "optional<T>::value_or: T must be move constructible");
536         static_assert(is_convertible<_Up, value_type>::value,
537                       "optional<T>::value_or: U must be convertible to T");
538         return this->__engaged_ ? _VSTD::move(this->__val_) :
539                                   static_cast<value_type>(_VSTD::forward<_Up>(__v));
540     }
541
542 private:
543     _LIBCPP_INLINE_VISIBILITY
544     value_type const*
545     __operator_arrow(true_type) const
546     {
547         return _VSTD::addressof(this->__val_);
548     }
549
550     _LIBCPP_INLINE_VISIBILITY
551     constexpr
552     value_type const*
553     __operator_arrow(false_type) const
554     {
555         return &this->__val_;
556     }
557 };
558
559 template <class _Tp>
560 inline _LIBCPP_INLINE_VISIBILITY
561 constexpr
562 bool
563 operator==(const optional<_Tp>& __x, const optional<_Tp>& __y)
564 {
565     if (static_cast<bool>(__x) != static_cast<bool>(__y))
566         return false;
567     if (!static_cast<bool>(__x))
568         return true;
569     return *__x == *__y;
570 }
571
572 template <class _Tp>
573 inline _LIBCPP_INLINE_VISIBILITY
574 constexpr
575 bool
576 operator<(const optional<_Tp>& __x, const optional<_Tp>& __y)
577 {
578     if (!static_cast<bool>(__y))
579         return false;
580     if (!static_cast<bool>(__x))
581         return true;
582     return less<_Tp>{}(*__x, *__y);
583 }
584
585 template <class _Tp>
586 inline _LIBCPP_INLINE_VISIBILITY
587 constexpr
588 bool
589 operator==(const optional<_Tp>& __x, nullopt_t) noexcept
590 {
591     return !static_cast<bool>(__x);
592 }
593
594 template <class _Tp>
595 inline _LIBCPP_INLINE_VISIBILITY
596 constexpr
597 bool
598 operator==(nullopt_t, const optional<_Tp>& __x) noexcept
599 {
600     return !static_cast<bool>(__x);
601 }
602
603 template <class _Tp>
604 inline _LIBCPP_INLINE_VISIBILITY
605 constexpr
606 bool
607 operator<(const optional<_Tp>&, nullopt_t) noexcept
608 {
609     return false;
610 }
611
612 template <class _Tp>
613 inline _LIBCPP_INLINE_VISIBILITY
614 constexpr
615 bool
616 operator<(nullopt_t, const optional<_Tp>& __x) noexcept
617 {
618     return static_cast<bool>(__x);
619 }
620
621 template <class _Tp>
622 inline _LIBCPP_INLINE_VISIBILITY
623 constexpr
624 bool
625 operator==(const optional<_Tp>& __x, const _Tp& __v)
626 {
627     return static_cast<bool>(__x) ? *__x == __v : false;
628 }
629
630 template <class _Tp>
631 inline _LIBCPP_INLINE_VISIBILITY
632 constexpr
633 bool
634 operator==(const _Tp& __v, const optional<_Tp>& __x)
635 {
636     return static_cast<bool>(__x) ? *__x == __v : false;
637 }
638
639 template <class _Tp>
640 inline _LIBCPP_INLINE_VISIBILITY
641 constexpr
642 bool
643 operator<(const optional<_Tp>& __x, const _Tp& __v)
644 {
645     return static_cast<bool>(__x) ? less<_Tp>{}(*__x, __v) : true;
646 }
647
648 template <class _Tp>
649 inline _LIBCPP_INLINE_VISIBILITY
650 constexpr
651 bool
652 operator<(const _Tp& __v, const optional<_Tp>& __x)
653 {
654     return static_cast<bool>(__x) ? less<_Tp>{}(__v, *__x) : false;
655 }
656
657 template <class _Tp>
658 inline _LIBCPP_INLINE_VISIBILITY
659 void
660 swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
661 {
662     __x.swap(__y);
663 }
664
665 template <class _Tp>
666 inline _LIBCPP_INLINE_VISIBILITY
667 constexpr
668 optional<typename decay<_Tp>::type>
669 make_optional(_Tp&& __v)
670 {
671     return optional<typename decay<_Tp>::type>(_VSTD::forward<_Tp>(__v));
672 }
673
674 }}}  // namespace std::experimental::__library_fundamentals_v1
675
676 _LIBCPP_BEGIN_NAMESPACE_STD
677
678 template <class _Tp>
679 struct _LIBCPP_TYPE_VIS_ONLY hash<std::experimental::optional<_Tp> >
680 {
681     typedef std::experimental::optional<_Tp> argument_type;
682     typedef size_t        result_type;
683
684     _LIBCPP_INLINE_VISIBILITY
685     result_type operator()(const argument_type& __opt) const _NOEXCEPT
686     {
687         return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0;
688     }
689 };
690
691 _LIBCPP_END_NAMESPACE_STD
692
693 #endif  // _LIBCPP_STD_VER > 11
694
695 #endif  // _LIBCPP_ARRAY