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