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