You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1715 lines
48 KiB

  1. //
  2. // Copyright (c) 2014-2018 Martin Moene
  3. //
  4. // https://github.com/martinmoene/optional-lite
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. #pragma once
  9. #ifndef NONSTD_OPTIONAL_LITE_HPP
  10. #define NONSTD_OPTIONAL_LITE_HPP
  11. #define optional_lite_MAJOR 3
  12. #define optional_lite_MINOR 2
  13. #define optional_lite_PATCH 0
  14. #define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
  15. #define optional_STRINGIFY( x ) optional_STRINGIFY_( x )
  16. #define optional_STRINGIFY_( x ) #x
  17. // optional-lite configuration:
  18. #define optional_OPTIONAL_DEFAULT 0
  19. #define optional_OPTIONAL_NONSTD 1
  20. #define optional_OPTIONAL_STD 2
  21. #if !defined( optional_CONFIG_SELECT_OPTIONAL )
  22. # define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
  23. #endif
  24. // Control presence of exception handling (try and auto discover):
  25. #ifndef optional_CONFIG_NO_EXCEPTIONS
  26. # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)
  27. # define optional_CONFIG_NO_EXCEPTIONS 0
  28. # else
  29. # define optional_CONFIG_NO_EXCEPTIONS 1
  30. # endif
  31. #endif
  32. // C++ language version detection (C++20 is speculative):
  33. // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
  34. #ifndef optional_CPLUSPLUS
  35. # if defined(_MSVC_LANG ) && !defined(__clang__)
  36. # define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
  37. # else
  38. # define optional_CPLUSPLUS __cplusplus
  39. # endif
  40. #endif
  41. #define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
  42. #define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
  43. #define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
  44. #define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
  45. #define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
  46. #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
  47. // C++ language version (represent 98 as 3):
  48. #define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
  49. // Use C++17 std::optional if available and requested:
  50. #if optional_CPP17_OR_GREATER && defined(__has_include )
  51. # if __has_include( <optional> )
  52. # define optional_HAVE_STD_OPTIONAL 1
  53. # else
  54. # define optional_HAVE_STD_OPTIONAL 0
  55. # endif
  56. #else
  57. # define optional_HAVE_STD_OPTIONAL 0
  58. #endif
  59. #define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) )
  60. //
  61. // in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
  62. //
  63. #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
  64. #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
  65. // C++17 std::in_place in <utility>:
  66. #if optional_CPP17_OR_GREATER
  67. #include <utility>
  68. namespace nonstd {
  69. using std::in_place;
  70. using std::in_place_type;
  71. using std::in_place_index;
  72. using std::in_place_t;
  73. using std::in_place_type_t;
  74. using std::in_place_index_t;
  75. #define nonstd_lite_in_place_t( T) std::in_place_t
  76. #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
  77. #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
  78. #define nonstd_lite_in_place( T) std::in_place_t{}
  79. #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
  80. #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
  81. } // namespace nonstd
  82. #else // optional_CPP17_OR_GREATER
  83. #include <cstddef>
  84. namespace nonstd {
  85. namespace detail {
  86. template< class T >
  87. struct in_place_type_tag {};
  88. template< std::size_t K >
  89. struct in_place_index_tag {};
  90. } // namespace detail
  91. struct in_place_t {};
  92. template< class T >
  93. inline in_place_t in_place( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
  94. {
  95. return in_place_t();
  96. }
  97. template< std::size_t K >
  98. inline in_place_t in_place( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
  99. {
  100. return in_place_t();
  101. }
  102. template< class T >
  103. inline in_place_t in_place_type( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
  104. {
  105. return in_place_t();
  106. }
  107. template< std::size_t K >
  108. inline in_place_t in_place_index( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
  109. {
  110. return in_place_t();
  111. }
  112. // mimic templated typedef:
  113. #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
  114. #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
  115. #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
  116. #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
  117. #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
  118. #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
  119. } // namespace nonstd
  120. #endif // optional_CPP17_OR_GREATER
  121. #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
  122. //
  123. // Using std::optional:
  124. //
  125. #if optional_USES_STD_OPTIONAL
  126. #include <optional>
  127. namespace nonstd {
  128. using std::optional;
  129. using std::bad_optional_access;
  130. using std::hash;
  131. using std::nullopt;
  132. using std::nullopt_t;
  133. using std::operator==;
  134. using std::operator!=;
  135. using std::operator<;
  136. using std::operator<=;
  137. using std::operator>;
  138. using std::operator>=;
  139. using std::make_optional;
  140. using std::swap;
  141. }
  142. #else // optional_USES_STD_OPTIONAL
  143. #include <cassert>
  144. #include <utility>
  145. // optional-lite alignment configuration:
  146. #ifndef optional_CONFIG_MAX_ALIGN_HACK
  147. # define optional_CONFIG_MAX_ALIGN_HACK 0
  148. #endif
  149. #ifndef optional_CONFIG_ALIGN_AS
  150. // no default, used in #if defined()
  151. #endif
  152. #ifndef optional_CONFIG_ALIGN_AS_FALLBACK
  153. # define optional_CONFIG_ALIGN_AS_FALLBACK double
  154. #endif
  155. // Compiler warning suppression:
  156. #if defined(__clang__)
  157. # pragma clang diagnostic push
  158. # pragma clang diagnostic ignored "-Wundef"
  159. #elif defined(__GNUC__)
  160. # pragma GCC diagnostic push
  161. # pragma GCC diagnostic ignored "-Wundef"
  162. #elif defined(_MSC_VER )
  163. # pragma warning( push )
  164. #endif
  165. // half-open range [lo..hi):
  166. #define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
  167. // Compiler versions:
  168. //
  169. // MSVC++ 6.0 _MSC_VER == 1200 optional_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
  170. // MSVC++ 7.0 _MSC_VER == 1300 optional_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
  171. // MSVC++ 7.1 _MSC_VER == 1310 optional_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
  172. // MSVC++ 8.0 _MSC_VER == 1400 optional_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
  173. // MSVC++ 9.0 _MSC_VER == 1500 optional_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
  174. // MSVC++ 10.0 _MSC_VER == 1600 optional_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
  175. // MSVC++ 11.0 _MSC_VER == 1700 optional_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
  176. // MSVC++ 12.0 _MSC_VER == 1800 optional_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
  177. // MSVC++ 14.0 _MSC_VER == 1900 optional_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
  178. // MSVC++ 14.1 _MSC_VER >= 1910 optional_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
  179. // MSVC++ 14.2 _MSC_VER >= 1920 optional_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
  180. #if defined(_MSC_VER ) && !defined(__clang__)
  181. # define optional_COMPILER_MSVC_VER (_MSC_VER )
  182. # define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
  183. #else
  184. # define optional_COMPILER_MSVC_VER 0
  185. # define optional_COMPILER_MSVC_VERSION 0
  186. #endif
  187. #define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) )
  188. #if defined(__GNUC__) && !defined(__clang__)
  189. # define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
  190. #else
  191. # define optional_COMPILER_GNUC_VERSION 0
  192. #endif
  193. #if defined(__clang__)
  194. # define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
  195. #else
  196. # define optional_COMPILER_CLANG_VERSION 0
  197. #endif
  198. #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
  199. # pragma warning( disable: 4345 ) // initialization behavior changed
  200. #endif
  201. #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
  202. # pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
  203. #endif
  204. // Presence of language and library features:
  205. #define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
  206. #ifdef _HAS_CPP0X
  207. # define optional_HAS_CPP0X _HAS_CPP0X
  208. #else
  209. # define optional_HAS_CPP0X 0
  210. #endif
  211. // Unless defined otherwise below, consider VC14 as C++11 for optional-lite:
  212. #if optional_COMPILER_MSVC_VER >= 1900
  213. # undef optional_CPP11_OR_GREATER
  214. # define optional_CPP11_OR_GREATER 1
  215. #endif
  216. #define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
  217. #define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
  218. #define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
  219. #define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
  220. #define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
  221. #define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
  222. #define optional_CPP11_140_490 ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || (optional_COMPILER_MSVC_VER >= 1910))
  223. #define optional_CPP14_000 (optional_CPP14_OR_GREATER)
  224. #define optional_CPP17_000 (optional_CPP17_OR_GREATER)
  225. // Presence of C++11 language features:
  226. #define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
  227. #define optional_HAVE_IS_DEFAULT optional_CPP11_140
  228. #define optional_HAVE_NOEXCEPT optional_CPP11_140
  229. #define optional_HAVE_NULLPTR optional_CPP11_100
  230. #define optional_HAVE_REF_QUALIFIER optional_CPP11_140_490
  231. #define optional_HAVE_INITIALIZER_LIST optional_CPP11_140
  232. // Presence of C++14 language features:
  233. #define optional_HAVE_CONSTEXPR_14 optional_CPP14_000
  234. // Presence of C++17 language features:
  235. #define optional_HAVE_NODISCARD optional_CPP17_000
  236. // Presence of C++ library features:
  237. #define optional_HAVE_CONDITIONAL optional_CPP11_120
  238. #define optional_HAVE_REMOVE_CV optional_CPP11_120
  239. #define optional_HAVE_TYPE_TRAITS optional_CPP11_90
  240. #define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION )
  241. #define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION )
  242. // C++ feature usage:
  243. #if optional_HAVE( CONSTEXPR_11 )
  244. # define optional_constexpr constexpr
  245. #else
  246. # define optional_constexpr /*constexpr*/
  247. #endif
  248. #if optional_HAVE( IS_DEFAULT )
  249. # define optional_is_default = default;
  250. #else
  251. # define optional_is_default {}
  252. #endif
  253. #if optional_HAVE( CONSTEXPR_14 )
  254. # define optional_constexpr14 constexpr
  255. #else
  256. # define optional_constexpr14 /*constexpr*/
  257. #endif
  258. #if optional_HAVE( NODISCARD )
  259. # define optional_nodiscard [[nodiscard]]
  260. #else
  261. # define optional_nodiscard /*[[nodiscard]]*/
  262. #endif
  263. #if optional_HAVE( NOEXCEPT )
  264. # define optional_noexcept noexcept
  265. #else
  266. # define optional_noexcept /*noexcept*/
  267. #endif
  268. #if optional_HAVE( NULLPTR )
  269. # define optional_nullptr nullptr
  270. #else
  271. # define optional_nullptr NULL
  272. #endif
  273. #if optional_HAVE( REF_QUALIFIER )
  274. // NOLINTNEXTLINE( bugprone-macro-parentheses )
  275. # define optional_ref_qual &
  276. # define optional_refref_qual &&
  277. #else
  278. # define optional_ref_qual /*&*/
  279. # define optional_refref_qual /*&&*/
  280. #endif
  281. // additional includes:
  282. #if optional_CONFIG_NO_EXCEPTIONS
  283. // already included: <cassert>
  284. #else
  285. # include <stdexcept>
  286. #endif
  287. #if optional_CPP11_OR_GREATER
  288. # include <functional>
  289. #endif
  290. #if optional_HAVE( INITIALIZER_LIST )
  291. # include <initializer_list>
  292. #endif
  293. #if optional_HAVE( TYPE_TRAITS )
  294. # include <type_traits>
  295. #elif optional_HAVE( TR1_TYPE_TRAITS )
  296. # include <tr1/type_traits>
  297. #endif
  298. // Method enabling
  299. #if optional_CPP11_OR_GREATER
  300. #define optional_REQUIRES_0(...) \
  301. template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
  302. #define optional_REQUIRES_T(...) \
  303. , typename std::enable_if< (__VA_ARGS__), int >::type = 0
  304. #define optional_REQUIRES_R(R, ...) \
  305. typename std::enable_if< (__VA_ARGS__), R>::type
  306. #define optional_REQUIRES_A(...) \
  307. , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
  308. #endif
  309. //
  310. // optional:
  311. //
  312. namespace nonstd { namespace optional_lite {
  313. namespace std11 {
  314. #if optional_CPP11_OR_GREATER
  315. using std::move;
  316. #else
  317. template< typename T > T & move( T & t ) { return t; }
  318. #endif
  319. #if optional_HAVE( CONDITIONAL )
  320. using std::conditional;
  321. #else
  322. template< bool B, typename T, typename F > struct conditional { typedef T type; };
  323. template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
  324. #endif // optional_HAVE_CONDITIONAL
  325. // gcc < 5:
  326. #if optional_CPP11_OR_GREATER
  327. #if optional_BETWEEN( optional_COMPILER_GNUC_VERSION, 1, 500 )
  328. template< typename T > struct is_trivially_copy_constructible : std::true_type{};
  329. template< typename T > struct is_trivially_move_constructible : std::true_type{};
  330. #else
  331. using std::is_trivially_copy_constructible;
  332. using std::is_trivially_move_constructible;
  333. #endif
  334. #endif
  335. } // namespace std11
  336. #if optional_CPP11_OR_GREATER
  337. /// type traits C++17:
  338. namespace std17 {
  339. #if optional_CPP17_OR_GREATER
  340. using std::is_swappable;
  341. using std::is_nothrow_swappable;
  342. #elif optional_CPP11_OR_GREATER
  343. namespace detail {
  344. using std::swap;
  345. struct is_swappable
  346. {
  347. template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
  348. static std::true_type test( int /*unused*/ );
  349. template< typename >
  350. static std::false_type test(...);
  351. };
  352. struct is_nothrow_swappable
  353. {
  354. // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
  355. template< typename T >
  356. static constexpr bool satisfies()
  357. {
  358. return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
  359. }
  360. template< typename T >
  361. static auto test( int /*unused*/ ) -> std::integral_constant<bool, satisfies<T>()>{}
  362. template< typename >
  363. static auto test(...) -> std::false_type;
  364. };
  365. } // namespace detail
  366. // is [nothow] swappable:
  367. template< typename T >
  368. struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
  369. template< typename T >
  370. struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
  371. #endif // optional_CPP17_OR_GREATER
  372. } // namespace std17
  373. /// type traits C++20:
  374. namespace std20 {
  375. template< typename T >
  376. struct remove_cvref
  377. {
  378. typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
  379. };
  380. } // namespace std20
  381. #endif // optional_CPP11_OR_GREATER
  382. /// class optional
  383. template< typename T >
  384. class optional;
  385. namespace detail {
  386. // C++11 emulation:
  387. struct nulltype{};
  388. template< typename Head, typename Tail >
  389. struct typelist
  390. {
  391. typedef Head head;
  392. typedef Tail tail;
  393. };
  394. #if optional_CONFIG_MAX_ALIGN_HACK
  395. // Max align, use most restricted type for alignment:
  396. #define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
  397. #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
  398. #define optional_UNIQUE3( name, line ) name ## line
  399. #define optional_ALIGN_TYPE( type ) \
  400. type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
  401. template< typename T >
  402. struct struct_t { T _; };
  403. union max_align_t
  404. {
  405. optional_ALIGN_TYPE( char );
  406. optional_ALIGN_TYPE( short int );
  407. optional_ALIGN_TYPE( int );
  408. optional_ALIGN_TYPE( long int );
  409. optional_ALIGN_TYPE( float );
  410. optional_ALIGN_TYPE( double );
  411. optional_ALIGN_TYPE( long double );
  412. optional_ALIGN_TYPE( char * );
  413. optional_ALIGN_TYPE( short int * );
  414. optional_ALIGN_TYPE( int * );
  415. optional_ALIGN_TYPE( long int * );
  416. optional_ALIGN_TYPE( float * );
  417. optional_ALIGN_TYPE( double * );
  418. optional_ALIGN_TYPE( long double * );
  419. optional_ALIGN_TYPE( void * );
  420. #ifdef HAVE_LONG_LONG
  421. optional_ALIGN_TYPE( long long );
  422. #endif
  423. struct Unknown;
  424. Unknown ( * optional_UNIQUE(_) )( Unknown );
  425. Unknown * Unknown::* optional_UNIQUE(_);
  426. Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
  427. struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
  428. struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
  429. struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_);
  430. };
  431. #undef optional_UNIQUE
  432. #undef optional_UNIQUE2
  433. #undef optional_UNIQUE3
  434. #undef optional_ALIGN_TYPE
  435. #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
  436. // Use user-specified type for alignment:
  437. #define optional_ALIGN_AS( unused ) \
  438. optional_CONFIG_ALIGN_AS
  439. #else // optional_CONFIG_MAX_ALIGN_HACK
  440. // Determine POD type to use for alignment:
  441. #define optional_ALIGN_AS( to_align ) \
  442. typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
  443. template< typename T >
  444. struct alignment_of;
  445. template< typename T >
  446. struct alignment_of_hack
  447. {
  448. char c;
  449. T t;
  450. alignment_of_hack();
  451. };
  452. template< size_t A, size_t S >
  453. struct alignment_logic
  454. {
  455. enum { value = A < S ? A : S };
  456. };
  457. template< typename T >
  458. struct alignment_of
  459. {
  460. enum { value = alignment_logic<
  461. sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value };
  462. };
  463. template< typename List, size_t N >
  464. struct type_of_size
  465. {
  466. typedef typename std11::conditional<
  467. N == sizeof( typename List::head ),
  468. typename List::head,
  469. typename type_of_size<typename List::tail, N >::type >::type type;
  470. };
  471. template< size_t N >
  472. struct type_of_size< nulltype, N >
  473. {
  474. typedef optional_CONFIG_ALIGN_AS_FALLBACK type;
  475. };
  476. template< typename T>
  477. struct struct_t { T _; };
  478. #define optional_ALIGN_TYPE( type ) \
  479. typelist< type , typelist< struct_t< type >
  480. struct Unknown;
  481. typedef
  482. optional_ALIGN_TYPE( char ),
  483. optional_ALIGN_TYPE( short ),
  484. optional_ALIGN_TYPE( int ),
  485. optional_ALIGN_TYPE( long ),
  486. optional_ALIGN_TYPE( float ),
  487. optional_ALIGN_TYPE( double ),
  488. optional_ALIGN_TYPE( long double ),
  489. optional_ALIGN_TYPE( char *),
  490. optional_ALIGN_TYPE( short * ),
  491. optional_ALIGN_TYPE( int * ),
  492. optional_ALIGN_TYPE( long * ),
  493. optional_ALIGN_TYPE( float * ),
  494. optional_ALIGN_TYPE( double * ),
  495. optional_ALIGN_TYPE( long double * ),
  496. optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
  497. optional_ALIGN_TYPE( Unknown * Unknown::* ),
  498. optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
  499. nulltype
  500. > > > > > > > > > > > > > >
  501. > > > > > > > > > > > > > >
  502. > > > > > >
  503. alignment_types;
  504. #undef optional_ALIGN_TYPE
  505. #endif // optional_CONFIG_MAX_ALIGN_HACK
  506. /// C++03 constructed union to hold value.
  507. template< typename T >
  508. union storage_t
  509. {
  510. //private:
  511. // template< typename > friend class optional;
  512. typedef T value_type;
  513. storage_t() optional_is_default
  514. explicit storage_t( value_type const & v )
  515. {
  516. construct_value( v );
  517. }
  518. void construct_value( value_type const & v )
  519. {
  520. ::new( value_ptr() ) value_type( v );
  521. }
  522. #if optional_CPP11_OR_GREATER
  523. explicit storage_t( value_type && v )
  524. {
  525. construct_value( std::move( v ) );
  526. }
  527. void construct_value( value_type && v )
  528. {
  529. ::new( value_ptr() ) value_type( std::move( v ) );
  530. }
  531. template< class... Args >
  532. void emplace( Args&&... args )
  533. {
  534. ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
  535. }
  536. template< class U, class... Args >
  537. void emplace( std::initializer_list<U> il, Args&&... args )
  538. {
  539. ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
  540. }
  541. #endif
  542. void destruct_value()
  543. {
  544. value_ptr()->~T();
  545. }
  546. optional_nodiscard value_type const * value_ptr() const
  547. {
  548. return as<value_type>();
  549. }
  550. value_type * value_ptr()
  551. {
  552. return as<value_type>();
  553. }
  554. optional_nodiscard value_type const & value() const optional_ref_qual
  555. {
  556. return * value_ptr();
  557. }
  558. value_type & value() optional_ref_qual
  559. {
  560. return * value_ptr();
  561. }
  562. #if optional_HAVE( REF_QUALIFIER )
  563. optional_nodiscard value_type const && value() const optional_refref_qual
  564. {
  565. return std::move( value() );
  566. }
  567. value_type && value() optional_refref_qual
  568. {
  569. return std::move( value() );
  570. }
  571. #endif
  572. #if optional_CPP11_OR_GREATER
  573. using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
  574. aligned_storage_t data;
  575. #elif optional_CONFIG_MAX_ALIGN_HACK
  576. typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
  577. max_align_t hack;
  578. aligned_storage_t data;
  579. #else
  580. typedef optional_ALIGN_AS(value_type) align_as_type;
  581. typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
  582. aligned_storage_t data;
  583. # undef optional_ALIGN_AS
  584. #endif // optional_CONFIG_MAX_ALIGN_HACK
  585. optional_nodiscard void * ptr() optional_noexcept
  586. {
  587. return &data;
  588. }
  589. optional_nodiscard void const * ptr() const optional_noexcept
  590. {
  591. return &data;
  592. }
  593. template <typename U>
  594. optional_nodiscard U * as()
  595. {
  596. return reinterpret_cast<U*>( ptr() );
  597. }
  598. template <typename U>
  599. optional_nodiscard U const * as() const
  600. {
  601. return reinterpret_cast<U const *>( ptr() );
  602. }
  603. };
  604. } // namespace detail
  605. /// disengaged state tag
  606. struct nullopt_t
  607. {
  608. struct init{};
  609. explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {}
  610. };
  611. #if optional_HAVE( CONSTEXPR_11 )
  612. constexpr nullopt_t nullopt{ nullopt_t::init{} };
  613. #else
  614. // extra parenthesis to prevent the most vexing parse:
  615. const nullopt_t nullopt(( nullopt_t::init() ));
  616. #endif
  617. /// optional access error
  618. #if ! optional_CONFIG_NO_EXCEPTIONS
  619. class bad_optional_access : public std::logic_error
  620. {
  621. public:
  622. explicit bad_optional_access()
  623. : logic_error( "bad optional access" ) {}
  624. };
  625. #endif //optional_CONFIG_NO_EXCEPTIONS
  626. /// optional
  627. template< typename T>
  628. class optional
  629. {
  630. private:
  631. template< typename > friend class optional;
  632. typedef void (optional::*safe_bool)() const;
  633. public:
  634. typedef T value_type;
  635. // x.x.3.1, constructors
  636. // 1a - default construct
  637. optional_constexpr optional() optional_noexcept
  638. : has_value_( false )
  639. , contained()
  640. {}
  641. // 1b - construct explicitly empty
  642. // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
  643. optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept
  644. : has_value_( false )
  645. , contained()
  646. {}
  647. // 2 - copy-construct
  648. #if optional_CPP11_OR_GREATER
  649. // template< typename U = T
  650. // optional_REQUIRES_T(
  651. // std::is_copy_constructible<U>::value
  652. // || std11::is_trivially_copy_constructible<U>::value
  653. // )
  654. // >
  655. #endif
  656. optional_constexpr14 optional( optional const & other )
  657. : has_value_( other.has_value() )
  658. {
  659. if ( other.has_value() )
  660. {
  661. contained.construct_value( other.contained.value() );
  662. }
  663. }
  664. #if optional_CPP11_OR_GREATER
  665. // 3 (C++11) - move-construct from optional
  666. template< typename U = T
  667. optional_REQUIRES_T(
  668. std::is_move_constructible<U>::value
  669. || std11::is_trivially_move_constructible<U>::value
  670. )
  671. >
  672. optional_constexpr14 optional( optional && other )
  673. // NOLINTNEXTLINE( performance-noexcept-move-constructor )
  674. noexcept( std::is_nothrow_move_constructible<T>::value )
  675. : has_value_( other.has_value() )
  676. {
  677. if ( other.has_value() )
  678. {
  679. contained.construct_value( std::move( other.contained.value() ) );
  680. }
  681. }
  682. // 4a (C++11) - explicit converting copy-construct from optional
  683. template< typename U
  684. optional_REQUIRES_T(
  685. std::is_constructible<T, U const &>::value
  686. && !std::is_constructible<T, optional<U> & >::value
  687. && !std::is_constructible<T, optional<U> && >::value
  688. && !std::is_constructible<T, optional<U> const & >::value
  689. && !std::is_constructible<T, optional<U> const && >::value
  690. && !std::is_convertible< optional<U> & , T>::value
  691. && !std::is_convertible< optional<U> && , T>::value
  692. && !std::is_convertible< optional<U> const & , T>::value
  693. && !std::is_convertible< optional<U> const &&, T>::value
  694. && !std::is_convertible< U const & , T>::value /*=> explicit */
  695. )
  696. >
  697. explicit optional( optional<U> const & other )
  698. : has_value_( other.has_value() )
  699. {
  700. if ( other.has_value() )
  701. {
  702. contained.construct_value( T{ other.contained.value() } );
  703. }
  704. }
  705. #endif // optional_CPP11_OR_GREATER
  706. // 4b (C++98 and later) - non-explicit converting copy-construct from optional
  707. template< typename U
  708. #if optional_CPP11_OR_GREATER
  709. optional_REQUIRES_T(
  710. std::is_constructible<T, U const &>::value
  711. && !std::is_constructible<T, optional<U> & >::value
  712. && !std::is_constructible<T, optional<U> && >::value
  713. && !std::is_constructible<T, optional<U> const & >::value
  714. && !std::is_constructible<T, optional<U> const && >::value
  715. && !std::is_convertible< optional<U> & , T>::value
  716. && !std::is_convertible< optional<U> && , T>::value
  717. && !std::is_convertible< optional<U> const & , T>::value
  718. && !std::is_convertible< optional<U> const &&, T>::value
  719. && std::is_convertible< U const & , T>::value /*=> non-explicit */
  720. )
  721. #endif // optional_CPP11_OR_GREATER
  722. >
  723. // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
  724. /*non-explicit*/ optional( optional<U> const & other )
  725. : has_value_( other.has_value() )
  726. {
  727. if ( other.has_value() )
  728. {
  729. contained.construct_value( other.contained.value() );
  730. }
  731. }
  732. #if optional_CPP11_OR_GREATER
  733. // 5a (C++11) - explicit converting move-construct from optional
  734. template< typename U
  735. optional_REQUIRES_T(
  736. std::is_constructible<T, U &&>::value
  737. && !std::is_constructible<T, optional<U> & >::value
  738. && !std::is_constructible<T, optional<U> && >::value
  739. && !std::is_constructible<T, optional<U> const & >::value
  740. && !std::is_constructible<T, optional<U> const && >::value
  741. && !std::is_convertible< optional<U> & , T>::value
  742. && !std::is_convertible< optional<U> && , T>::value
  743. && !std::is_convertible< optional<U> const & , T>::value
  744. && !std::is_convertible< optional<U> const &&, T>::value
  745. && !std::is_convertible< U &&, T>::value /*=> explicit */
  746. )
  747. >
  748. explicit optional( optional<U> && other
  749. )
  750. : has_value_( other.has_value() )
  751. {
  752. if ( other.has_value() )
  753. {
  754. contained.construct_value( T{ std::move( other.contained.value() ) } );
  755. }
  756. }
  757. // 5a (C++11) - non-explicit converting move-construct from optional
  758. template< typename U
  759. optional_REQUIRES_T(
  760. std::is_constructible<T, U &&>::value
  761. && !std::is_constructible<T, optional<U> & >::value
  762. && !std::is_constructible<T, optional<U> && >::value
  763. && !std::is_constructible<T, optional<U> const & >::value
  764. && !std::is_constructible<T, optional<U> const && >::value
  765. && !std::is_convertible< optional<U> & , T>::value
  766. && !std::is_convertible< optional<U> && , T>::value
  767. && !std::is_convertible< optional<U> const & , T>::value
  768. && !std::is_convertible< optional<U> const &&, T>::value
  769. && std::is_convertible< U &&, T>::value /*=> non-explicit */
  770. )
  771. >
  772. // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
  773. /*non-explicit*/ optional( optional<U> && other )
  774. : has_value_( other.has_value() )
  775. {
  776. if ( other.has_value() )
  777. {
  778. contained.construct_value( std::move( other.contained.value() ) );
  779. }
  780. }
  781. // 6 (C++11) - in-place construct
  782. template< typename... Args
  783. optional_REQUIRES_T(
  784. std::is_constructible<T, Args&&...>::value
  785. )
  786. >
  787. optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args )
  788. : has_value_( true )
  789. , contained( T( std::forward<Args>(args)...) )
  790. {}
  791. // 7 (C++11) - in-place construct, initializer-list
  792. template< typename U, typename... Args
  793. optional_REQUIRES_T(
  794. std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
  795. )
  796. >
  797. optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list<U> il, Args&&... args )
  798. : has_value_( true )
  799. , contained( T( il, std::forward<Args>(args)...) )
  800. {}
  801. // 8a (C++11) - explicit move construct from value
  802. template< typename U = T
  803. optional_REQUIRES_T(
  804. std::is_constructible<T, U&&>::value
  805. && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
  806. && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
  807. && !std::is_convertible<U&&, T>::value /*=> explicit */
  808. )
  809. >
  810. optional_constexpr explicit optional( U && value )
  811. : has_value_( true )
  812. , contained( T{ std::forward<U>( value ) } )
  813. {}
  814. // 8b (C++11) - non-explicit move construct from value
  815. template< typename U = T
  816. optional_REQUIRES_T(
  817. std::is_constructible<T, U&&>::value
  818. && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
  819. && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
  820. && std::is_convertible<U&&, T>::value /*=> non-explicit */
  821. )
  822. >
  823. // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
  824. optional_constexpr /*non-explicit*/ optional( U && value )
  825. : has_value_( true )
  826. , contained( std::forward<U>( value ) )
  827. {}
  828. #else // optional_CPP11_OR_GREATER
  829. // 8 (C++98)
  830. optional( value_type const & value )
  831. : has_value_( true )
  832. , contained( value )
  833. {}
  834. #endif // optional_CPP11_OR_GREATER
  835. // x.x.3.2, destructor
  836. ~optional()
  837. {
  838. if ( has_value() )
  839. {
  840. contained.destruct_value();
  841. }
  842. }
  843. // x.x.3.3, assignment
  844. // 1 (C++98and later) - assign explicitly empty
  845. optional & operator=( nullopt_t /*unused*/) optional_noexcept
  846. {
  847. reset();
  848. return *this;
  849. }
  850. // 2 (C++98and later) - copy-assign from optional
  851. #if optional_CPP11_OR_GREATER
  852. // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
  853. optional_REQUIRES_R(
  854. optional &,
  855. true
  856. // std::is_copy_constructible<T>::value
  857. // && std::is_copy_assignable<T>::value
  858. )
  859. operator=( optional const & other )
  860. noexcept(
  861. std::is_nothrow_move_assignable<T>::value
  862. && std::is_nothrow_move_constructible<T>::value
  863. )
  864. #else
  865. optional & operator=( optional const & other )
  866. #endif
  867. {
  868. if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
  869. else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); }
  870. else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; }
  871. return *this;
  872. }
  873. #if optional_CPP11_OR_GREATER
  874. // 3 (C++11) - move-assign from optional
  875. // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
  876. optional_REQUIRES_R(
  877. optional &,
  878. true
  879. // std::is_move_constructible<T>::value
  880. // && std::is_move_assignable<T>::value
  881. )
  882. operator=( optional && other ) noexcept
  883. {
  884. if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
  885. else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); }
  886. else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); }
  887. return *this;
  888. }
  889. // 4 (C++11) - move-assign from value
  890. template< typename U = T >
  891. // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
  892. optional_REQUIRES_R(
  893. optional &,
  894. std::is_constructible<T , U>::value
  895. && std::is_assignable<T&, U>::value
  896. && !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
  897. && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
  898. && !(std::is_scalar<T>::value && std::is_same<T, typename std::decay<U>::type>::value)
  899. )
  900. operator=( U && value )
  901. {
  902. if ( has_value() )
  903. {
  904. contained.value() = std::forward<U>( value );
  905. }
  906. else
  907. {
  908. initialize( T( std::forward<U>( value ) ) );
  909. }
  910. return *this;
  911. }
  912. #else // optional_CPP11_OR_GREATER
  913. // 4 (C++98) - copy-assign from value
  914. template< typename U /*= T*/ >
  915. optional & operator=( U const & value )
  916. {
  917. if ( has_value() ) contained.value() = value;
  918. else initialize( T( value ) );
  919. return *this;
  920. }
  921. #endif // optional_CPP11_OR_GREATER
  922. // 5 (C++98 and later) - converting copy-assign from optional
  923. template< typename U >
  924. #if optional_CPP11_OR_GREATER
  925. // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
  926. optional_REQUIRES_R(
  927. optional&,
  928. std::is_constructible< T , U const &>::value
  929. && std::is_assignable< T&, U const &>::value
  930. && !std::is_constructible<T, optional<U> & >::value
  931. && !std::is_constructible<T, optional<U> && >::value
  932. && !std::is_constructible<T, optional<U> const & >::value
  933. && !std::is_constructible<T, optional<U> const && >::value
  934. && !std::is_convertible< optional<U> & , T>::value
  935. && !std::is_convertible< optional<U> && , T>::value
  936. && !std::is_convertible< optional<U> const & , T>::value
  937. && !std::is_convertible< optional<U> const &&, T>::value
  938. && !std::is_assignable< T&, optional<U> & >::value
  939. && !std::is_assignable< T&, optional<U> && >::value
  940. && !std::is_assignable< T&, optional<U> const & >::value
  941. && !std::is_assignable< T&, optional<U> const && >::value
  942. )
  943. #else
  944. optional&
  945. #endif // optional_CPP11_OR_GREATER
  946. operator=( optional<U> const & other )
  947. {
  948. return *this = optional( other );
  949. }
  950. #if optional_CPP11_OR_GREATER
  951. // 6 (C++11) - converting move-assign from optional
  952. template< typename U >
  953. // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
  954. optional_REQUIRES_R(
  955. optional&,
  956. std::is_constructible< T , U>::value
  957. && std::is_assignable< T&, U>::value
  958. && !std::is_constructible<T, optional<U> & >::value
  959. && !std::is_constructible<T, optional<U> && >::value
  960. && !std::is_constructible<T, optional<U> const & >::value
  961. && !std::is_constructible<T, optional<U> const && >::value
  962. && !std::is_convertible< optional<U> & , T>::value
  963. && !std::is_convertible< optional<U> && , T>::value
  964. && !std::is_convertible< optional<U> const & , T>::value
  965. && !std::is_convertible< optional<U> const &&, T>::value
  966. && !std::is_assignable< T&, optional<U> & >::value
  967. && !std::is_assignable< T&, optional<U> && >::value
  968. && !std::is_assignable< T&, optional<U> const & >::value
  969. && !std::is_assignable< T&, optional<U> const && >::value
  970. )
  971. operator=( optional<U> && other )
  972. {
  973. return *this = optional( std::move( other ) );
  974. }
  975. // 7 (C++11) - emplace
  976. template< typename... Args
  977. optional_REQUIRES_T(
  978. std::is_constructible<T, Args&&...>::value
  979. )
  980. >
  981. T& emplace( Args&&... args )
  982. {
  983. *this = nullopt;
  984. contained.emplace( std::forward<Args>(args)... );
  985. has_value_ = true;
  986. return contained.value();
  987. }
  988. // 8 (C++11) - emplace, initializer-list
  989. template< typename U, typename... Args
  990. optional_REQUIRES_T(
  991. std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value
  992. )
  993. >
  994. T& emplace( std::initializer_list<U> il, Args&&... args )
  995. {
  996. *this = nullopt;
  997. contained.emplace( il, std::forward<Args>(args)... );
  998. has_value_ = true;
  999. return contained.value();
  1000. }
  1001. #endif // optional_CPP11_OR_GREATER
  1002. // x.x.3.4, swap
  1003. void swap( optional & other )
  1004. #if optional_CPP11_OR_GREATER
  1005. noexcept(
  1006. std::is_nothrow_move_constructible<T>::value
  1007. && std17::is_nothrow_swappable<T>::value
  1008. )
  1009. #endif
  1010. {
  1011. using std::swap;
  1012. if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); }
  1013. else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); }
  1014. else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); }
  1015. }
  1016. // x.x.3.5, observers
  1017. optional_constexpr value_type const * operator ->() const
  1018. {
  1019. return assert( has_value() ),
  1020. contained.value_ptr();
  1021. }
  1022. optional_constexpr14 value_type * operator ->()
  1023. {
  1024. return assert( has_value() ),
  1025. contained.value_ptr();
  1026. }
  1027. optional_constexpr value_type const & operator *() const optional_ref_qual
  1028. {
  1029. return assert( has_value() ),
  1030. contained.value();
  1031. }
  1032. optional_constexpr14 value_type & operator *() optional_ref_qual
  1033. {
  1034. return assert( has_value() ),
  1035. contained.value();
  1036. }
  1037. #if optional_HAVE( REF_QUALIFIER )
  1038. optional_constexpr value_type const && operator *() const optional_refref_qual
  1039. {
  1040. return std::move( **this );
  1041. }
  1042. optional_constexpr14 value_type && operator *() optional_refref_qual
  1043. {
  1044. return std::move( **this );
  1045. }
  1046. #endif
  1047. #if optional_CPP11_OR_GREATER
  1048. optional_constexpr explicit operator bool() const optional_noexcept
  1049. {
  1050. return has_value();
  1051. }
  1052. #else
  1053. optional_constexpr operator safe_bool() const optional_noexcept
  1054. {
  1055. return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
  1056. }
  1057. #endif
  1058. // NOLINTNEXTLINE( modernize-use-nodiscard )
  1059. /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept
  1060. {
  1061. return has_value_;
  1062. }
  1063. // NOLINTNEXTLINE( modernize-use-nodiscard )
  1064. /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual
  1065. {
  1066. #if optional_CONFIG_NO_EXCEPTIONS
  1067. assert( has_value() );
  1068. #else
  1069. if ( ! has_value() )
  1070. {
  1071. throw bad_optional_access();
  1072. }
  1073. #endif
  1074. return contained.value();
  1075. }
  1076. optional_constexpr14 value_type & value() optional_ref_qual
  1077. {
  1078. #if optional_CONFIG_NO_EXCEPTIONS
  1079. assert( has_value() );
  1080. #else
  1081. if ( ! has_value() )
  1082. {
  1083. throw bad_optional_access();
  1084. }
  1085. #endif
  1086. return contained.value();
  1087. }
  1088. #if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 )
  1089. // NOLINTNEXTLINE( modernize-use-nodiscard )
  1090. /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual
  1091. {
  1092. return std::move( value() );
  1093. }
  1094. optional_constexpr14 value_type && value() optional_refref_qual
  1095. {
  1096. return std::move( value() );
  1097. }
  1098. #endif
  1099. #if optional_CPP11_OR_GREATER
  1100. template< typename U >
  1101. optional_constexpr value_type value_or( U && v ) const optional_ref_qual
  1102. {
  1103. return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
  1104. }
  1105. template< typename U >
  1106. optional_constexpr14 value_type value_or( U && v ) optional_refref_qual
  1107. {
  1108. return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
  1109. }
  1110. #else
  1111. template< typename U >
  1112. optional_constexpr value_type value_or( U const & v ) const
  1113. {
  1114. return has_value() ? contained.value() : static_cast<value_type>( v );
  1115. }
  1116. #endif // optional_CPP11_OR_GREATER
  1117. // x.x.3.6, modifiers
  1118. void reset() optional_noexcept
  1119. {
  1120. if ( has_value() )
  1121. {
  1122. contained.destruct_value();
  1123. }
  1124. has_value_ = false;
  1125. }
  1126. private:
  1127. void this_type_does_not_support_comparisons() const {}
  1128. template< typename V >
  1129. void initialize( V const & value )
  1130. {
  1131. assert( ! has_value() );
  1132. contained.construct_value( value );
  1133. has_value_ = true;
  1134. }
  1135. #if optional_CPP11_OR_GREATER
  1136. template< typename V >
  1137. void initialize( V && value )
  1138. {
  1139. assert( ! has_value() );
  1140. contained.construct_value( std::move( value ) );
  1141. has_value_ = true;
  1142. }
  1143. #endif
  1144. private:
  1145. bool has_value_;
  1146. detail::storage_t< value_type > contained;
  1147. };
  1148. // Relational operators
  1149. template< typename T, typename U >
  1150. inline optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y )
  1151. {
  1152. return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
  1153. }
  1154. template< typename T, typename U >
  1155. inline optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y )
  1156. {
  1157. return !(x == y);
  1158. }
  1159. template< typename T, typename U >
  1160. inline optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y )
  1161. {
  1162. return (!y) ? false : (!x) ? true : *x < *y;
  1163. }
  1164. template< typename T, typename U >
  1165. inline optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y )
  1166. {
  1167. return (y < x);
  1168. }
  1169. template< typename T, typename U >
  1170. inline optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y )
  1171. {
  1172. return !(y < x);
  1173. }
  1174. template< typename T, typename U >
  1175. inline optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y )
  1176. {
  1177. return !(x < y);
  1178. }
  1179. // Comparison with nullopt
  1180. template< typename T >
  1181. inline optional_constexpr bool operator==( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
  1182. {
  1183. return (!x);
  1184. }
  1185. template< typename T >
  1186. inline optional_constexpr bool operator==( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
  1187. {
  1188. return (!x);
  1189. }
  1190. template< typename T >
  1191. inline optional_constexpr bool operator!=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
  1192. {
  1193. return bool(x);
  1194. }
  1195. template< typename T >
  1196. inline optional_constexpr bool operator!=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
  1197. {
  1198. return bool(x);
  1199. }
  1200. template< typename T >
  1201. inline optional_constexpr bool operator<( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
  1202. {
  1203. return false;
  1204. }
  1205. template< typename T >
  1206. inline optional_constexpr bool operator<( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
  1207. {
  1208. return bool(x);
  1209. }
  1210. template< typename T >
  1211. inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
  1212. {
  1213. return (!x);
  1214. }
  1215. template< typename T >
  1216. inline optional_constexpr bool operator<=( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
  1217. {
  1218. return true;
  1219. }
  1220. template< typename T >
  1221. inline optional_constexpr bool operator>( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
  1222. {
  1223. return bool(x);
  1224. }
  1225. template< typename T >
  1226. inline optional_constexpr bool operator>( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
  1227. {
  1228. return false;
  1229. }
  1230. template< typename T >
  1231. inline optional_constexpr bool operator>=( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
  1232. {
  1233. return true;
  1234. }
  1235. template< typename T >
  1236. inline optional_constexpr bool operator>=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
  1237. {
  1238. return (!x);
  1239. }
  1240. // Comparison with T
  1241. template< typename T, typename U >
  1242. inline optional_constexpr bool operator==( optional<T> const & x, U const & v )
  1243. {
  1244. return bool(x) ? *x == v : false;
  1245. }
  1246. template< typename T, typename U >
  1247. inline optional_constexpr bool operator==( U const & v, optional<T> const & x )
  1248. {
  1249. return bool(x) ? v == *x : false;
  1250. }
  1251. template< typename T, typename U >
  1252. inline optional_constexpr bool operator!=( optional<T> const & x, U const & v )
  1253. {
  1254. return bool(x) ? *x != v : true;
  1255. }
  1256. template< typename T, typename U >
  1257. inline optional_constexpr bool operator!=( U const & v, optional<T> const & x )
  1258. {
  1259. return bool(x) ? v != *x : true;
  1260. }
  1261. template< typename T, typename U >
  1262. inline optional_constexpr bool operator<( optional<T> const & x, U const & v )
  1263. {
  1264. return bool(x) ? *x < v : true;
  1265. }
  1266. template< typename T, typename U >
  1267. inline optional_constexpr bool operator<( U const & v, optional<T> const & x )
  1268. {
  1269. return bool(x) ? v < *x : false;
  1270. }
  1271. template< typename T, typename U >
  1272. inline optional_constexpr bool operator<=( optional<T> const & x, U const & v )
  1273. {
  1274. return bool(x) ? *x <= v : true;
  1275. }
  1276. template< typename T, typename U >
  1277. inline optional_constexpr bool operator<=( U const & v, optional<T> const & x )
  1278. {
  1279. return bool(x) ? v <= *x : false;
  1280. }
  1281. template< typename T, typename U >
  1282. inline optional_constexpr bool operator>( optional<T> const & x, U const & v )
  1283. {
  1284. return bool(x) ? *x > v : false;
  1285. }
  1286. template< typename T, typename U >
  1287. inline optional_constexpr bool operator>( U const & v, optional<T> const & x )
  1288. {
  1289. return bool(x) ? v > *x : true;
  1290. }
  1291. template< typename T, typename U >
  1292. inline optional_constexpr bool operator>=( optional<T> const & x, U const & v )
  1293. {
  1294. return bool(x) ? *x >= v : false;
  1295. }
  1296. template< typename T, typename U >
  1297. inline optional_constexpr bool operator>=( U const & v, optional<T> const & x )
  1298. {
  1299. return bool(x) ? v >= *x : true;
  1300. }
  1301. // Specialized algorithms
  1302. template< typename T
  1303. #if optional_CPP11_OR_GREATER
  1304. optional_REQUIRES_T(
  1305. std::is_move_constructible<T>::value
  1306. && std17::is_swappable<T>::value )
  1307. #endif
  1308. >
  1309. void swap( optional<T> & x, optional<T> & y )
  1310. #if optional_CPP11_OR_GREATER
  1311. noexcept( noexcept( x.swap(y) ) )
  1312. #endif
  1313. {
  1314. x.swap( y );
  1315. }
  1316. #if optional_CPP11_OR_GREATER
  1317. template< typename T >
  1318. optional_constexpr optional< typename std::decay<T>::type > make_optional( T && value )
  1319. {
  1320. return optional< typename std::decay<T>::type >( std::forward<T>( value ) );
  1321. }
  1322. template< typename T, typename...Args >
  1323. optional_constexpr optional<T> make_optional( Args&&... args )
  1324. {
  1325. return optional<T>( nonstd_lite_in_place(T), std::forward<Args>(args)...);
  1326. }
  1327. template< typename T, typename U, typename... Args >
  1328. optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
  1329. {
  1330. return optional<T>( nonstd_lite_in_place(T), il, std::forward<Args>(args)...);
  1331. }
  1332. #else
  1333. template< typename T >
  1334. optional<T> make_optional( T const & value )
  1335. {
  1336. return optional<T>( value );
  1337. }
  1338. #endif // optional_CPP11_OR_GREATER
  1339. } // namespace optional_lite
  1340. using optional_lite::optional;
  1341. using optional_lite::nullopt_t;
  1342. using optional_lite::nullopt;
  1343. #if ! optional_CONFIG_NO_EXCEPTIONS
  1344. using optional_lite::bad_optional_access;
  1345. #endif
  1346. using optional_lite::make_optional;
  1347. } // namespace nonstd
  1348. #if optional_CPP11_OR_GREATER
  1349. // specialize the std::hash algorithm:
  1350. namespace std {
  1351. template< class T >
  1352. struct hash< nonstd::optional<T> >
  1353. {
  1354. public:
  1355. std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
  1356. {
  1357. return bool( v ) ? std::hash<T>{}( *v ) : 0;
  1358. }
  1359. };
  1360. } //namespace std
  1361. #endif // optional_CPP11_OR_GREATER
  1362. #if defined(__clang__)
  1363. # pragma clang diagnostic pop
  1364. #elif defined(__GNUC__)
  1365. # pragma GCC diagnostic pop
  1366. #elif defined(_MSC_VER )
  1367. # pragma warning( pop )
  1368. #endif
  1369. #endif // optional_USES_STD_OPTIONAL
  1370. #endif // NONSTD_OPTIONAL_LITE_HPP