1
+ #ifndef _GHLIBCPP_OPTIONAL
2
+ #define _GHLIBCPP_OPTIONAL
3
+
4
+ #include "initializer_list"
5
+ #include "stddef.h"
6
+
7
+ namespace std {
8
+
9
+ // Forward declarations and helper types
10
+ struct in_place_t {
11
+ explicit in_place_t() = default;
12
+ };
13
+ constexpr in_place_t in_place{};
14
+
15
+ // Type trait helper
16
+ template <class T> struct decay {
17
+ typedef T type;
18
+ };
19
+
20
+ // nullopt_t type and nullopt constant
21
+ struct nullopt_t {
22
+ explicit constexpr nullopt_t(int) {}
23
+ };
24
+ constexpr nullopt_t nullopt{0};
25
+
26
+ // bad_optional_access exception
27
+ class bad_optional_access {};
28
+
29
+ // optional template class
30
+ template <class T> class optional {
31
+ public:
32
+ typedef T value_type;
33
+
34
+ // Constructors
35
+ constexpr optional() noexcept;
36
+ constexpr optional(nullopt_t) noexcept;
37
+ constexpr optional(const optional &other);
38
+ constexpr optional(optional &&other) noexcept;
39
+ template <class U> constexpr explicit optional(const optional<U> &other);
40
+ template <class U> constexpr explicit optional(optional<U> &&other);
41
+ template <class... Args>
42
+ constexpr explicit optional(in_place_t, Args &&...args);
43
+ template <class U, class... Args>
44
+ constexpr explicit optional(in_place_t, initializer_list<U> ilist,
45
+ Args &&...args);
46
+ template <class U = T> constexpr explicit optional(U &&value);
47
+
48
+ // Destructor
49
+ ~optional();
50
+
51
+ // Assignment operators
52
+ optional &operator=(nullopt_t) noexcept;
53
+ constexpr optional &operator=(const optional &other);
54
+ constexpr optional &operator=(optional &&other) noexcept;
55
+ template <class U = T> optional &operator=(U &&value);
56
+ template <class U> optional &operator=(const optional<U> &other);
57
+ template <class U> optional &operator=(optional<U> &&other);
58
+
59
+ // Observers
60
+ constexpr const T *operator->() const;
61
+ constexpr T *operator->();
62
+ constexpr const T &operator*() const &;
63
+ constexpr T &operator*() &;
64
+ constexpr const T &&operator*() const &&;
65
+ constexpr T &&operator*() &&;
66
+ constexpr explicit operator bool() const noexcept;
67
+ constexpr bool has_value() const noexcept;
68
+ constexpr const T &value() const &;
69
+ constexpr T &value() &;
70
+ constexpr const T &&value() const &&;
71
+ constexpr T &&value() &&;
72
+ template <class U> constexpr T value_or(U &&default_value) const &;
73
+ template <class U> constexpr T value_or(U &&default_value) &&;
74
+
75
+ // Modifiers
76
+ void swap(optional &other) noexcept;
77
+ void reset() noexcept;
78
+ template <class... Args> T &emplace(Args &&...args);
79
+ template <class U, class... Args>
80
+ T &emplace(initializer_list<U> ilist, Args &&...args);
81
+ };
82
+
83
+ // Deduction guides
84
+ template <class T> optional(T) -> optional<T>;
85
+
86
+ // Comparison operators
87
+ template <class T, class U>
88
+ constexpr bool operator==(const optional<T> &lhs, const optional<U> &rhs);
89
+ template <class T, class U>
90
+ constexpr bool operator!=(const optional<T> &lhs, const optional<U> &rhs);
91
+ template <class T, class U>
92
+ constexpr bool operator<(const optional<T> &lhs, const optional<U> &rhs);
93
+ template <class T, class U>
94
+ constexpr bool operator<=(const optional<T> &lhs, const optional<U> &rhs);
95
+ template <class T, class U>
96
+ constexpr bool operator>(const optional<T> &lhs, const optional<U> &rhs);
97
+ template <class T, class U>
98
+ constexpr bool operator>=(const optional<T> &lhs, const optional<U> &rhs);
99
+
100
+ // Comparison with nullopt
101
+ template <class T>
102
+ constexpr bool operator==(const optional<T> &opt, nullopt_t) noexcept;
103
+ template <class T>
104
+ constexpr bool operator==(nullopt_t, const optional<T> &opt) noexcept;
105
+ template <class T>
106
+ constexpr bool operator!=(const optional<T> &opt, nullopt_t) noexcept;
107
+ template <class T>
108
+ constexpr bool operator!=(nullopt_t, const optional<T> &opt) noexcept;
109
+ template <class T>
110
+ constexpr bool operator<(const optional<T> &opt, nullopt_t) noexcept;
111
+ template <class T>
112
+ constexpr bool operator<(nullopt_t, const optional<T> &opt) noexcept;
113
+ template <class T>
114
+ constexpr bool operator<=(const optional<T> &opt, nullopt_t) noexcept;
115
+ template <class T>
116
+ constexpr bool operator<=(nullopt_t, const optional<T> &opt) noexcept;
117
+ template <class T>
118
+ constexpr bool operator>(const optional<T> &opt, nullopt_t) noexcept;
119
+ template <class T>
120
+ constexpr bool operator>(nullopt_t, const optional<T> &opt) noexcept;
121
+ template <class T>
122
+ constexpr bool operator>=(const optional<T> &opt, nullopt_t) noexcept;
123
+ template <class T>
124
+ constexpr bool operator>=(nullopt_t, const optional<T> &opt) noexcept;
125
+
126
+ // Comparison with T
127
+ template <class T, class U>
128
+ constexpr bool operator==(const optional<T> &opt, const U &value);
129
+ template <class T, class U>
130
+ constexpr bool operator==(const T &value, const optional<U> &opt);
131
+ template <class T, class U>
132
+ constexpr bool operator!=(const optional<T> &opt, const U &value);
133
+ template <class T, class U>
134
+ constexpr bool operator!=(const T &value, const optional<U> &opt);
135
+ template <class T, class U>
136
+ constexpr bool operator<(const optional<T> &opt, const U &value);
137
+ template <class T, class U>
138
+ constexpr bool operator<(const T &value, const optional<U> &opt);
139
+ template <class T, class U>
140
+ constexpr bool operator<=(const optional<T> &opt, const U &value);
141
+ template <class T, class U>
142
+ constexpr bool operator<=(const T &value, const optional<U> &opt);
143
+ template <class T, class U>
144
+ constexpr bool operator>(const optional<T> &opt, const U &value);
145
+ template <class T, class U>
146
+ constexpr bool operator>(const T &value, const optional<U> &opt);
147
+ template <class T, class U>
148
+ constexpr bool operator>=(const optional<T> &opt, const U &value);
149
+ template <class T, class U>
150
+ constexpr bool operator>=(const T &value, const optional<U> &opt);
151
+
152
+ // Specialized algorithms
153
+ template <class T> void swap(optional<T> &lhs, optional<T> &rhs) noexcept;
154
+
155
+ // Factory functions
156
+ template <class T>
157
+ constexpr optional<typename decay<T>::type> make_optional(T &&value);
158
+ template <class T, class... Args>
159
+ constexpr optional<T> make_optional(Args &&...args);
160
+ template <class T, class U, class... Args>
161
+ constexpr optional<T> make_optional(initializer_list<U> ilist, Args &&...args);
162
+
163
+ } // namespace std
164
+
165
+ #endif // _GHLIBCPP_OPTIONAL
0 commit comments