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