RESTinio
optional.hpp
Go to the documentation of this file.
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 
9 #pragma once
10 
11 #ifndef NONSTD_OPTIONAL_LITE_HPP
12 #define NONSTD_OPTIONAL_LITE_HPP
13 
14 #define optional_lite_MAJOR 3
15 #define optional_lite_MINOR 4
16 #define optional_lite_PATCH 0
17 
19 
20 #define optional_STRINGIFY( x ) optional_STRINGIFY_( x )
21 #define optional_STRINGIFY_( x ) #x
22 
23 // optional-lite configuration:
24 
25 #define optional_OPTIONAL_DEFAULT 0
26 #define optional_OPTIONAL_NONSTD 1
27 #define optional_OPTIONAL_STD 2
28 
29 // tweak header support:
30 
31 #ifdef __has_include
32 # if __has_include(<nonstd/optional.tweak.hpp>)
33 # include <nonstd/optional.tweak.hpp>
34 # endif
35 #define optional_HAVE_TWEAK_HEADER 1
36 #else
37 #define optional_HAVE_TWEAK_HEADER 0
38 //# pragma message("optional.hpp: Note: Tweak header not supported.")
39 #endif
40 
41 // optional selection and configuration:
42 
43 #if !defined( optional_CONFIG_SELECT_OPTIONAL )
44 # define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
45 #endif
46 
47 // Control presence of exception handling (try and auto discover):
48 
49 #ifndef optional_CONFIG_NO_EXCEPTIONS
50 # if _MSC_VER
51 # include <cstddef> // for _HAS_EXCEPTIONS
52 # endif
53 # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
54 # define optional_CONFIG_NO_EXCEPTIONS 0
55 # else
56 # define optional_CONFIG_NO_EXCEPTIONS 1
57 # endif
58 #endif
59 
60 // C++ language version detection (C++20 is speculative):
61 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
62 
63 #ifndef optional_CPLUSPLUS
64 # if defined(_MSVC_LANG ) && !defined(__clang__)
65 # define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
66 # else
67 # define optional_CPLUSPLUS __cplusplus
68 # endif
69 #endif
70 
71 #define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
72 #define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
73 #define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
74 #define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
75 #define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
76 #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
77 
78 // C++ language version (represent 98 as 3):
79 
80 #define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
81 
82 // Use C++17 std::optional if available and requested:
83 
84 #if optional_CPP17_OR_GREATER && defined(__has_include )
85 # if __has_include( <optional> )
86 # define optional_HAVE_STD_OPTIONAL 1
87 # else
88 # define optional_HAVE_STD_OPTIONAL 0
89 # endif
90 #else
91 # define optional_HAVE_STD_OPTIONAL 0
92 #endif
93 
95 
96 //
97 // in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite:
98 //
99 
100 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
101 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
102 
103 // C++17 std::in_place in <utility>:
104 
106 
107 #include <utility>
108 
109 namespace nonstd {
110 
111 using std::in_place;
112 using std::in_place_type;
113 using std::in_place_index;
114 using std::in_place_t;
115 using std::in_place_type_t;
116 using std::in_place_index_t;
117 
118 #define nonstd_lite_in_place_t( T) std::in_place_t
119 #define nonstd_lite_in_place_type_t( T) std::in_place_type_t<T>
120 #define nonstd_lite_in_place_index_t(K) std::in_place_index_t<K>
121 
122 #define nonstd_lite_in_place( T) std::in_place_t{}
123 #define nonstd_lite_in_place_type( T) std::in_place_type_t<T>{}
124 #define nonstd_lite_in_place_index(K) std::in_place_index_t<K>{}
125 
126 } // namespace nonstd
127 
128 #else // optional_CPP17_OR_GREATER
129 
130 #include <cstddef>
131 
132 namespace nonstd {
133 namespace detail {
134 
135 template< class T >
136 struct in_place_type_tag {};
137 
138 template< std::size_t K >
139 struct in_place_index_tag {};
140 
141 } // namespace detail
142 
143 struct in_place_t {};
144 
145 template< class T >
146 inline in_place_t in_place( detail::in_place_type_tag<T> /*unused*/ = detail::in_place_type_tag<T>() )
147 {
148  return in_place_t();
149 }
150 
151 template< std::size_t K >
152 inline in_place_t in_place( detail::in_place_index_tag<K> /*unused*/ = detail::in_place_index_tag<K>() )
153 {
154  return in_place_t();
155 }
156 
157 template< class T >
159 {
160  return in_place_t();
161 }
162 
163 template< std::size_t K >
165 {
166  return in_place_t();
167 }
168 
169 // mimic templated typedef:
170 
171 #define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
172 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
173 #define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<K> )
174 
175 #define nonstd_lite_in_place( T) nonstd::in_place_type<T>
176 #define nonstd_lite_in_place_type( T) nonstd::in_place_type<T>
177 #define nonstd_lite_in_place_index(K) nonstd::in_place_index<K>
178 
179 } // namespace nonstd
180 
181 #endif // optional_CPP17_OR_GREATER
182 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
183 
184 //
185 // Using std::optional:
186 //
187 
189 
190 #include <optional>
191 
192 namespace nonstd {
193 
194  using std::optional;
195  using std::bad_optional_access;
196  using std::hash;
197 
198  using std::nullopt;
199  using std::nullopt_t;
200 
201  using std::operator==;
202  using std::operator!=;
203  using std::operator<;
204  using std::operator<=;
205  using std::operator>;
206  using std::operator>=;
207  using std::make_optional;
208  using std::swap;
209 }
210 
211 #else // optional_USES_STD_OPTIONAL
212 
213 #include <cassert>
214 #include <utility>
215 
216 // optional-lite alignment configuration:
217 
218 #ifndef optional_CONFIG_MAX_ALIGN_HACK
219 # define optional_CONFIG_MAX_ALIGN_HACK 0
220 #endif
221 
222 #ifndef optional_CONFIG_ALIGN_AS
223 // no default, used in #if defined()
224 #endif
225 
226 #ifndef optional_CONFIG_ALIGN_AS_FALLBACK
227 # define optional_CONFIG_ALIGN_AS_FALLBACK double
228 #endif
229 
230 // Compiler warning suppression:
231 
232 #if defined(__clang__)
233 # pragma clang diagnostic push
234 # pragma clang diagnostic ignored "-Wundef"
235 #elif defined(__GNUC__)
236 # pragma GCC diagnostic push
237 # pragma GCC diagnostic ignored "-Wundef"
238 #elif defined(_MSC_VER )
239 # pragma warning( push )
240 #endif
241 
242 // half-open range [lo..hi):
243 #define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) )
244 
245 // Compiler versions:
246 //
247 // MSVC++ 6.0 _MSC_VER == 1200 optional_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0)
248 // MSVC++ 7.0 _MSC_VER == 1300 optional_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002)
249 // MSVC++ 7.1 _MSC_VER == 1310 optional_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003)
250 // MSVC++ 8.0 _MSC_VER == 1400 optional_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005)
251 // MSVC++ 9.0 _MSC_VER == 1500 optional_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008)
252 // MSVC++ 10.0 _MSC_VER == 1600 optional_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010)
253 // MSVC++ 11.0 _MSC_VER == 1700 optional_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012)
254 // MSVC++ 12.0 _MSC_VER == 1800 optional_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013)
255 // MSVC++ 14.0 _MSC_VER == 1900 optional_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015)
256 // MSVC++ 14.1 _MSC_VER >= 1910 optional_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017)
257 // MSVC++ 14.2 _MSC_VER >= 1920 optional_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019)
258 
259 #if defined(_MSC_VER ) && !defined(__clang__)
260 # define optional_COMPILER_MSVC_VER (_MSC_VER )
261 # define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
262 #else
263 # define optional_COMPILER_MSVC_VER 0
264 # define optional_COMPILER_MSVC_VERSION 0
265 #endif
266 
267 #define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) )
268 
269 #if defined(__GNUC__) && !defined(__clang__)
270 # define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
271 #else
272 # define optional_COMPILER_GNUC_VERSION 0
273 #endif
274 
275 #if defined(__clang__)
276 # define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
277 #else
278 # define optional_COMPILER_CLANG_VERSION 0
279 #endif
280 
282 # pragma warning( disable: 4345 ) // initialization behavior changed
283 #endif
284 
286 # pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
287 #endif
288 
289 // Presence of language and library features:
290 
291 #define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
292 
293 #ifdef _HAS_CPP0X
294 # define optional_HAS_CPP0X _HAS_CPP0X
295 #else
296 # define optional_HAS_CPP0X 0
297 #endif
298 
299 // Unless defined otherwise below, consider VC14 as C++11 for optional-lite:
300 
301 #if optional_COMPILER_MSVC_VER >= 1900
302 # undef optional_CPP11_OR_GREATER
303 # define optional_CPP11_OR_GREATER 1
304 #endif
305 
306 #define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500)
307 #define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600)
308 #define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700)
309 #define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800)
310 #define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900)
311 #define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910)
312 
313 #define optional_CPP14_000 (optional_CPP14_OR_GREATER)
314 #define optional_CPP17_000 (optional_CPP17_OR_GREATER)
315 
316 // gcc >= 4.9, msvc >= vc14.1 (vs17):
317 #define optional_CPP11_140_G490 ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || (optional_COMPILER_MSVC_VER >= 1910))
318 
319 // clang >= 3.5, msvc >= vc11 (vs12):
320 #define optional_CPP11_110_C350 ( optional_CPP11_110 && !optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) )
321 
322 // clang >= 3.5, gcc >= 5.0, msvc >= vc11 (vs12):
323 #define optional_CPP11_110_C350_G500
324  ( optional_CPP11_110 &&
327 
328 // Presence of C++11 language features:
329 
330 #define optional_HAVE_CONSTEXPR_11 optional_CPP11_140
331 #define optional_HAVE_IS_DEFAULT optional_CPP11_140
332 #define optional_HAVE_NOEXCEPT optional_CPP11_140
333 #define optional_HAVE_NULLPTR optional_CPP11_100
334 #define optional_HAVE_REF_QUALIFIER optional_CPP11_140_G490
335 #define optional_HAVE_INITIALIZER_LIST optional_CPP11_140
336 
337 // Presence of C++14 language features:
338 
339 #define optional_HAVE_CONSTEXPR_14 optional_CPP14_000
340 
341 // Presence of C++17 language features:
342 
343 #define optional_HAVE_NODISCARD optional_CPP17_000
344 
345 // Presence of C++ library features:
346 
347 #define optional_HAVE_CONDITIONAL optional_CPP11_120
348 #define optional_HAVE_REMOVE_CV optional_CPP11_120
349 #define optional_HAVE_TYPE_TRAITS optional_CPP11_90
350 
351 #define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION )
352 #define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION )
353 
354 #define optional_HAVE_IS_ASSIGNABLE optional_CPP11_110_C350
355 #define optional_HAVE_IS_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350
356 #define optional_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE optional_CPP11_110_C350
357 #define optional_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350
358 #define optional_HAVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE optional_CPP11_110_C350_G500
359 #define optional_HAVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350_G500
360 
361 // C++ feature usage:
362 
363 #if optional_HAVE( CONSTEXPR_11 )
364 # define optional_constexpr constexpr
365 #else
366 # define optional_constexpr /*constexpr*/
367 #endif
368 
369 #if optional_HAVE( IS_DEFAULT )
370 # define optional_is_default = default;
371 #else
372 # define optional_is_default {}
373 #endif
374 
375 #if optional_HAVE( CONSTEXPR_14 )
376 # define optional_constexpr14 constexpr
377 #else
378 # define optional_constexpr14 /*constexpr*/
379 #endif
380 
381 #if optional_HAVE( NODISCARD )
382 # define optional_nodiscard [[nodiscard]]
383 #else
384 # define optional_nodiscard /*[[nodiscard]]*/
385 #endif
386 
387 #if optional_HAVE( NOEXCEPT )
388 # define optional_noexcept noexcept
389 #else
390 # define optional_noexcept /*noexcept*/
391 #endif
392 
393 #if optional_HAVE( NULLPTR )
394 # define optional_nullptr nullptr
395 #else
396 # define optional_nullptr NULL
397 #endif
398 
399 #if optional_HAVE( REF_QUALIFIER )
400 // NOLINTNEXTLINE( bugprone-macro-parentheses )
401 # define optional_ref_qual &
402 # define optional_refref_qual &&
403 #else
404 # define optional_ref_qual /*&*/
405 # define optional_refref_qual /*&&*/
406 #endif
407 
408 // additional includes:
409 
411 // already included: <cassert>
412 #else
413 # include <stdexcept>
414 #endif
415 
417 # include <functional>
418 #endif
419 
420 #if optional_HAVE( INITIALIZER_LIST )
421 # include <initializer_list>
422 #endif
423 
424 #if optional_HAVE( TYPE_TRAITS )
425 # include <type_traits>
426 #elif optional_HAVE( TR1_TYPE_TRAITS )
427 # include <tr1/type_traits>
428 #endif
429 
430 // Method enabling
431 
433 
434 #define optional_REQUIRES_0(...)
435  template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::type = 0 >
436 
437 #define optional_REQUIRES_T(...)
438  , typename std::enable_if< (__VA_ARGS__), int >::type = 0
439 
440 #define optional_REQUIRES_R(R, ...)
441  typename std::enable_if< (__VA_ARGS__), R>::type
442 
443 #define optional_REQUIRES_A(...)
444  , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr
445 
446 #endif
447 
448 //
449 // optional:
450 //
451 
452 namespace nonstd { namespace optional_lite {
453 
454 namespace std11 {
455 
456 template< class T, T v > struct integral_constant { enum { value = v }; };
457 template< bool B > struct bool_constant : integral_constant<bool, B>{};
458 
459 typedef bool_constant< true > true_type;
460 typedef bool_constant< false > false_type;
461 
463  using std::move;
464 #else
465  template< typename T > T & move( T & t ) { return t; }
466 #endif
467 
468 #if optional_HAVE( CONDITIONAL )
469  using std::conditional;
470 #else
471  template< bool B, typename T, typename F > struct conditional { typedef T type; };
472  template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
473 #endif // optional_HAVE_CONDITIONAL
474 
475 #if optional_HAVE( IS_ASSIGNABLE )
476  using std::is_assignable;
477 #else
478  template< class T, class U > struct is_assignable : std11::true_type{};
479 #endif
480 
481 #if optional_HAVE( IS_MOVE_CONSTRUCTIBLE )
482  using std::is_move_constructible;
483 #else
484  template< class T > struct is_move_constructible : std11::true_type{};
485 #endif
486 
487 #if optional_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE )
489 #else
490  template< class T > struct is_nothrow_move_assignable : std11::true_type{};
491 #endif
492 
493 #if optional_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE )
495 #else
496  template< class T > struct is_nothrow_move_constructible : std11::true_type{};
497 #endif
498 
499 #if optional_HAVE( IS_TRIVIALLY_COPY_CONSTRUCTIBLE )
501 #else
502  template< class T > struct is_trivially_copy_constructible : std11::true_type{};
503 #endif
504 
505 #if optional_HAVE( IS_TRIVIALLY_MOVE_CONSTRUCTIBLE )
507 #else
508  template< class T > struct is_trivially_move_constructible : std11::true_type{};
509 #endif
510 
511 } // namespace std11
512 
514 
515 /// type traits C++17:
516 
517 namespace std17 {
518 
520 
521 using std::is_swappable;
522 using std::is_nothrow_swappable;
523 
525 
526 namespace detail {
527 
528 using std::swap;
529 
530 struct is_swappable
531 {
532  template< typename T, typename = decltype( swap( std::declval<T&>(), std::declval<T&>() ) ) >
533  static std11::true_type test( int /*unused*/ );
534 
535  template< typename >
536  static std11::false_type test(...);
537 };
538 
539 struct is_nothrow_swappable
540 {
541  // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015):
542 
543  template< typename T >
544  static constexpr bool satisfies()
545  {
546  return noexcept( swap( std::declval<T&>(), std::declval<T&>() ) );
547  }
548 
549  template< typename T >
550  static auto test( int /*unused*/ ) -> std11::integral_constant<bool, satisfies<T>()>{}
551 
552  template< typename >
553  static auto test(...) -> std11::false_type;
554 };
555 
556 } // namespace detail
557 
558 // is [nothow] swappable:
559 
560 template< typename T >
561 struct is_swappable : decltype( detail::is_swappable::test<T>(0) ){};
562 
563 template< typename T >
564 struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test<T>(0) ){};
565 
566 #endif // optional_CPP17_OR_GREATER
567 
568 } // namespace std17
569 
570 /// type traits C++20:
571 
572 namespace std20 {
573 
574 template< typename T >
575 struct remove_cvref
576 {
577  typedef typename std::remove_cv< typename std::remove_reference<T>::type >::type type;
578 };
579 
580 } // namespace std20
581 
582 #endif // optional_CPP11_OR_GREATER
583 
584 /// class optional
585 
586 template< typename T >
587 class optional;
588 
589 namespace detail {
590 
591 // C++11 emulation:
592 
593 struct nulltype{};
594 
595 template< typename Head, typename Tail >
596 struct typelist
597 {
598  typedef Head head;
599  typedef Tail tail;
600 };
601 
603 
604 // Max align, use most restricted type for alignment:
605 
606 #define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
607 #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
608 #define optional_UNIQUE3( name, line ) name ## line
609 
610 #define optional_ALIGN_TYPE( type )
611  type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
612 
613 template< typename T >
614 struct struct_t { T _; };
615 
616 union max_align_t
617 {
618  optional_ALIGN_TYPE( char );
619  optional_ALIGN_TYPE( short int );
620  optional_ALIGN_TYPE( int );
621  optional_ALIGN_TYPE( long int );
622  optional_ALIGN_TYPE( float );
623  optional_ALIGN_TYPE( double );
624  optional_ALIGN_TYPE( long double );
625  optional_ALIGN_TYPE( char * );
626  optional_ALIGN_TYPE( short int * );
627  optional_ALIGN_TYPE( int * );
628  optional_ALIGN_TYPE( long int * );
629  optional_ALIGN_TYPE( float * );
630  optional_ALIGN_TYPE( double * );
631  optional_ALIGN_TYPE( long double * );
632  optional_ALIGN_TYPE( void * );
633 
634 #ifdef HAVE_LONG_LONG
635  optional_ALIGN_TYPE( long long );
636 #endif
637 
638  struct Unknown;
639 
640  Unknown ( * optional_UNIQUE(_) )( Unknown );
643 
647 };
648 
649 #undef optional_UNIQUE
650 #undef optional_UNIQUE2
651 #undef optional_UNIQUE3
652 
653 #undef optional_ALIGN_TYPE
654 
655 #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
656 
657 // Use user-specified type for alignment:
658 
659 #define optional_ALIGN_AS( unused )
660  optional_CONFIG_ALIGN_AS
661 
662 #else // optional_CONFIG_MAX_ALIGN_HACK
663 
664 // Determine POD type to use for alignment:
665 
666 #define optional_ALIGN_AS( to_align )
667  typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
668 
669 template< typename T >
670 struct alignment_of;
671 
672 template< typename T >
674 {
675  char c;
676  T t;
678 };
679 
680 template< size_t A, size_t S >
682 {
683  enum { value = A < S ? A : S };
684 };
685 
686 template< typename T >
687 struct alignment_of
688 {
690  sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value };
691 };
692 
693 template< typename List, size_t N >
695 {
696  typedef typename std11::conditional<
697  N == sizeof( typename List::head ),
698  typename List::head,
699  typename type_of_size<typename List::tail, N >::type >::type type;
700 };
701 
702 template< size_t N >
703 struct type_of_size< nulltype, N >
704 {
706 };
707 
708 template< typename T>
709 struct struct_t { T _; };
710 
711 #define optional_ALIGN_TYPE( type )
712  typelist< type , typelist< struct_t< type >
713 
714 struct Unknown;
715 
716 typedef
717  optional_ALIGN_TYPE( char ),
718  optional_ALIGN_TYPE( short ),
719  optional_ALIGN_TYPE( int ),
720  optional_ALIGN_TYPE( long ),
721  optional_ALIGN_TYPE( float ),
722  optional_ALIGN_TYPE( double ),
723  optional_ALIGN_TYPE( long double ),
724 
725  optional_ALIGN_TYPE( char *),
726  optional_ALIGN_TYPE( short * ),
727  optional_ALIGN_TYPE( int * ),
728  optional_ALIGN_TYPE( long * ),
729  optional_ALIGN_TYPE( float * ),
730  optional_ALIGN_TYPE( double * ),
731  optional_ALIGN_TYPE( long double * ),
732 
733  optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
734  optional_ALIGN_TYPE( Unknown * Unknown::* ),
735  optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
736 
737  nulltype
738  > > > > > > > > > > > > > >
739  > > > > > > > > > > > > > >
740  > > > > > >
742 
743 #undef optional_ALIGN_TYPE
744 
745 #endif // optional_CONFIG_MAX_ALIGN_HACK
746 
747 /// C++03 constructed union to hold value.
748 
749 template< typename T >
751 {
752 //private:
753 // template< typename > friend class optional;
754 
755  typedef T value_type;
756 
758 
759  explicit storage_t( value_type const & v )
760  {
761  construct_value( v );
762  }
763 
764  void construct_value( value_type const & v )
765  {
766  ::new( value_ptr() ) value_type( v );
767  }
768 
770 
771  explicit storage_t( value_type && v )
772  {
773  construct_value( std::move( v ) );
774  }
775 
776  void construct_value( value_type && v )
777  {
778  ::new( value_ptr() ) value_type( std::move( v ) );
779  }
780 
781  template< class... Args >
782  storage_t( nonstd_lite_in_place_t(T), Args&&... args )
783  {
784  emplace( std::forward<Args>(args)... );
785  }
786 
787  template< class... Args >
788  void emplace( Args&&... args )
789  {
790  ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
791  }
792 
793  template< class U, class... Args >
794  void emplace( std::initializer_list<U> il, Args&&... args )
795  {
796  ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
797  }
798 
799 #endif
800 
802  {
803  value_ptr()->~T();
804  }
805 
807  {
808  return as<value_type>();
809  }
810 
812  {
813  return as<value_type>();
814  }
815 
817  {
818  return * value_ptr();
819  }
820 
822  {
823  return * value_ptr();
824  }
825 
826 #if optional_HAVE( REF_QUALIFIER )
827 
829  {
830  return std::move( value() );
831  }
832 
834  {
835  return std::move( value() );
836  }
837 
838 #endif
839 
841 
842  using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
843  aligned_storage_t data;
844 
845 #elif optional_CONFIG_MAX_ALIGN_HACK
846 
847  typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
848 
851 
852 #else
854 
855  typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
857 
858 # undef optional_ALIGN_AS
859 
860 #endif // optional_CONFIG_MAX_ALIGN_HACK
861 
863  {
864  return &data;
865  }
866 
868  {
869  return &data;
870  }
871 
872  template <typename U>
874  {
875  return reinterpret_cast<U*>( ptr() );
876  }
877 
878  template <typename U>
879  optional_nodiscard U const * as() const
880  {
881  return reinterpret_cast<U const *>( ptr() );
882  }
883 };
884 
885 } // namespace detail
886 
887 /// disengaged state tag
888 
889 struct nullopt_t
890 {
891  struct init{};
893 };
894 
895 #if optional_HAVE( CONSTEXPR_11 )
896 constexpr nullopt_t nullopt{ nullopt_t::init{} };
897 #else
898 // extra parenthesis to prevent the most vexing parse:
899 const nullopt_t nullopt(( nullopt_t::init() ));
900 #endif
901 
902 /// optional access error
903 
905 
906 class bad_optional_access : public std::logic_error
907 {
908 public:
909  explicit bad_optional_access()
910  : logic_error( "bad optional access" ) {}
911 };
912 
913 #endif //optional_CONFIG_NO_EXCEPTIONS
914 
915 /// optional
916 
917 template< typename T>
918 class optional
919 {
920 private:
921  template< typename > friend class optional;
922 
923  typedef void (optional::*safe_bool)() const;
924 
925 public:
926  typedef T value_type;
927 
928  // x.x.3.1, constructors
929 
930  // 1a - default construct
932  : has_value_( false )
933  , contained()
934  {}
935 
936  // 1b - construct explicitly empty
937  // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
939  : has_value_( false )
940  , contained()
941  {}
942 
943  // 2 - copy-construct
945  // template< typename U = T
946  // optional_REQUIRES_T(
947  // std::is_copy_constructible<U>::value
948  // || std11::is_trivially_copy_constructible<U>::value
949  // )
950  // >
951 #endif
953  : has_value_( other.has_value() )
954  {
955  if ( other.has_value() )
956  {
957  contained.construct_value( other.contained.value() );
958  }
959  }
960 
962 
963  // 3 (C++11) - move-construct from optional
964  template< typename U = T
965  optional_REQUIRES_T(
968  )
969  >
971  // NOLINTNEXTLINE( performance-noexcept-move-constructor )
973  : has_value_( other.has_value() )
974  {
975  if ( other.has_value() )
976  {
978  }
979  }
980 
981  // 4a (C++11) - explicit converting copy-construct from optional
982  template< typename U
983  optional_REQUIRES_T(
984  std::is_constructible<T, U const &>::value
985  && !std::is_constructible<T, optional<U> & >::value
986  && !std::is_constructible<T, optional<U> && >::value
987  && !std::is_constructible<T, optional<U> const & >::value
988  && !std::is_constructible<T, optional<U> const && >::value
989  && !std::is_convertible< optional<U> & , T>::value
990  && !std::is_convertible< optional<U> && , T>::value
991  && !std::is_convertible< optional<U> const & , T>::value
992  && !std::is_convertible< optional<U> const &&, T>::value
993  && !std::is_convertible< U const & , T>::value /*=> explicit */
994  )
995  >
996  explicit optional( optional<U> const & other )
997  : has_value_( other.has_value() )
998  {
999  if ( other.has_value() )
1000  {
1002  }
1003  }
1004 #endif // optional_CPP11_OR_GREATER
1005 
1006  // 4b (C++98 and later) - non-explicit converting copy-construct from optional
1007  template< typename U
1009  optional_REQUIRES_T(
1010  std::is_constructible<T, U const &>::value
1011  && !std::is_constructible<T, optional<U> & >::value
1012  && !std::is_constructible<T, optional<U> && >::value
1013  && !std::is_constructible<T, optional<U> const & >::value
1014  && !std::is_constructible<T, optional<U> const && >::value
1015  && !std::is_convertible< optional<U> & , T>::value
1016  && !std::is_convertible< optional<U> && , T>::value
1017  && !std::is_convertible< optional<U> const & , T>::value
1018  && !std::is_convertible< optional<U> const &&, T>::value
1019  && std::is_convertible< U const & , T>::value /*=> non-explicit */
1020  )
1021 #endif // optional_CPP11_OR_GREATER
1022  >
1023  // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
1024  /*non-explicit*/ optional( optional<U> const & other )
1025  : has_value_( other.has_value() )
1026  {
1027  if ( other.has_value() )
1028  {
1030  }
1031  }
1032 
1034 
1035  // 5a (C++11) - explicit converting move-construct from optional
1036  template< typename U
1037  optional_REQUIRES_T(
1038  std::is_constructible<T, U &&>::value
1039  && !std::is_constructible<T, optional<U> & >::value
1040  && !std::is_constructible<T, optional<U> && >::value
1041  && !std::is_constructible<T, optional<U> const & >::value
1042  && !std::is_constructible<T, optional<U> const && >::value
1043  && !std::is_convertible< optional<U> & , T>::value
1044  && !std::is_convertible< optional<U> && , T>::value
1045  && !std::is_convertible< optional<U> const & , T>::value
1046  && !std::is_convertible< optional<U> const &&, T>::value
1047  && !std::is_convertible< U &&, T>::value /*=> explicit */
1048  )
1049  >
1050  explicit optional( optional<U> && other
1051  )
1052  : has_value_( other.has_value() )
1053  {
1054  if ( other.has_value() )
1055  {
1057  }
1058  }
1059 
1060  // 5a (C++11) - non-explicit converting move-construct from optional
1061  template< typename U
1062  optional_REQUIRES_T(
1063  std::is_constructible<T, U &&>::value
1064  && !std::is_constructible<T, optional<U> & >::value
1065  && !std::is_constructible<T, optional<U> && >::value
1066  && !std::is_constructible<T, optional<U> const & >::value
1067  && !std::is_constructible<T, optional<U> const && >::value
1068  && !std::is_convertible< optional<U> & , T>::value
1069  && !std::is_convertible< optional<U> && , T>::value
1070  && !std::is_convertible< optional<U> const & , T>::value
1071  && !std::is_convertible< optional<U> const &&, T>::value
1072  && std::is_convertible< U &&, T>::value /*=> non-explicit */
1073  )
1074  >
1075  // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
1076  /*non-explicit*/ optional( optional<U> && other )
1077  : has_value_( other.has_value() )
1078  {
1079  if ( other.has_value() )
1080  {
1082  }
1083  }
1084 
1085  // 6 (C++11) - in-place construct
1086  template< typename... Args
1087  optional_REQUIRES_T(
1088  std::is_constructible<T, Args&&...>::value
1089  )
1090  >
1092  : has_value_( true )
1093  , contained( T( std::forward<Args>(args)...) )
1094  {}
1095 
1096  // 7 (C++11) - in-place construct, initializer-list
1097  template< typename U, typename... Args
1098  optional_REQUIRES_T(
1100  )
1101  >
1103  : has_value_( true )
1104  , contained( T( il, std::forward<Args>(args)...) )
1105  {}
1106 
1107  // 8a (C++11) - explicit move construct from value
1108  template< typename U = T
1109  optional_REQUIRES_T(
1110  std::is_constructible<T, U&&>::value
1112  && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
1113  && !std::is_convertible<U&&, T>::value /*=> explicit */
1114  )
1115  >
1116  optional_constexpr explicit optional( U && value )
1117  : has_value_( true )
1119  {}
1120 
1121  // 8b (C++11) - non-explicit move construct from value
1122  template< typename U = T
1123  optional_REQUIRES_T(
1124  std::is_constructible<T, U&&>::value
1126  && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
1127  && std::is_convertible<U&&, T>::value /*=> non-explicit */
1128  )
1129  >
1130  // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
1131  optional_constexpr /*non-explicit*/ optional( U && value )
1132  : has_value_( true )
1134  {}
1135 
1136 #else // optional_CPP11_OR_GREATER
1137 
1138  // 8 (C++98)
1140  : has_value_( true )
1141  , contained( value )
1142  {}
1143 
1144 #endif // optional_CPP11_OR_GREATER
1145 
1146  // x.x.3.2, destructor
1147 
1149  {
1150  if ( has_value() )
1151  {
1153  }
1154  }
1155 
1156  // x.x.3.3, assignment
1157 
1158  // 1 (C++98and later) - assign explicitly empty
1160  {
1161  reset();
1162  return *this;
1163  }
1164 
1165  // 2 (C++98and later) - copy-assign from optional
1167  // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1168  optional_REQUIRES_R(
1169  optional &,
1170  true
1171 // std::is_copy_constructible<T>::value
1172 // && std::is_copy_assignable<T>::value
1173  )
1174  operator=( optional const & other )
1175  noexcept(
1178  )
1179 #else
1181 #endif
1182  {
1183  if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
1184  else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); }
1185  else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; }
1186  return *this;
1187  }
1188 
1190 
1191  // 3 (C++11) - move-assign from optional
1192  // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1193  optional_REQUIRES_R(
1194  optional &,
1195  true
1196 // std11::is_move_constructible<T>::value
1197 // && std::is_move_assignable<T>::value
1198  )
1199  operator=( optional && other ) noexcept
1200  {
1201  if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); }
1202  else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); }
1203  else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); }
1204  return *this;
1205  }
1206 
1207  // 4 (C++11) - move-assign from value
1208  template< typename U = T >
1209  // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1210  optional_REQUIRES_R(
1211  optional &,
1213  && std11::is_assignable<T&, U>::value
1215  && !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
1216  && !(std::is_scalar<T>::value && std::is_same<T, typename std::decay<U>::type>::value)
1217  )
1218  operator=( U && value )
1219  {
1220  if ( has_value() )
1221  {
1222  contained.value() = std::forward<U>( value );
1223  }
1224  else
1225  {
1226  initialize( T( std::forward<U>( value ) ) );
1227  }
1228  return *this;
1229  }
1230 
1231 #else // optional_CPP11_OR_GREATER
1232 
1233  // 4 (C++98) - copy-assign from value
1234  template< typename U /*= T*/ >
1235  optional & operator=( U const & value )
1236  {
1237  if ( has_value() ) contained.value() = value;
1238  else initialize( T( value ) );
1239  return *this;
1240  }
1241 
1242 #endif // optional_CPP11_OR_GREATER
1243 
1244  // 5 (C++98 and later) - converting copy-assign from optional
1245  template< typename U >
1247  // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1248  optional_REQUIRES_R(
1249  optional&,
1250  std::is_constructible< T , U const &>::value
1251  && std11::is_assignable< T&, U const &>::value
1252  && !std::is_constructible<T, optional<U> & >::value
1253  && !std::is_constructible<T, optional<U> && >::value
1254  && !std::is_constructible<T, optional<U> const & >::value
1255  && !std::is_constructible<T, optional<U> const && >::value
1256  && !std::is_convertible< optional<U> & , T>::value
1257  && !std::is_convertible< optional<U> && , T>::value
1258  && !std::is_convertible< optional<U> const & , T>::value
1259  && !std::is_convertible< optional<U> const &&, T>::value
1260  && !std11::is_assignable< T&, optional<U> & >::value
1261  && !std11::is_assignable< T&, optional<U> && >::value
1262  && !std11::is_assignable< T&, optional<U> const & >::value
1263  && !std11::is_assignable< T&, optional<U> const && >::value
1264  )
1265 #else
1266  optional&
1267 #endif // optional_CPP11_OR_GREATER
1268  operator=( optional<U> const & other )
1269  {
1270  return *this = optional( other );
1271  }
1272 
1274 
1275  // 6 (C++11) - converting move-assign from optional
1276  template< typename U >
1277  // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator )
1278  optional_REQUIRES_R(
1279  optional&,
1280  std::is_constructible< T , U>::value
1281  && std11::is_assignable< T&, U>::value
1282  && !std::is_constructible<T, optional<U> & >::value
1283  && !std::is_constructible<T, optional<U> && >::value
1284  && !std::is_constructible<T, optional<U> const & >::value
1285  && !std::is_constructible<T, optional<U> const && >::value
1286  && !std::is_convertible< optional<U> & , T>::value
1287  && !std::is_convertible< optional<U> && , T>::value
1288  && !std::is_convertible< optional<U> const & , T>::value
1289  && !std::is_convertible< optional<U> const &&, T>::value
1290  && !std11::is_assignable< T&, optional<U> & >::value
1291  && !std11::is_assignable< T&, optional<U> && >::value
1292  && !std11::is_assignable< T&, optional<U> const & >::value
1293  && !std11::is_assignable< T&, optional<U> const && >::value
1294  )
1295  operator=( optional<U> && other )
1296  {
1297  return *this = optional( std::move( other ) );
1298  }
1299 
1300  // 7 (C++11) - emplace
1301  template< typename... Args
1302  optional_REQUIRES_T(
1303  std::is_constructible<T, Args&&...>::value
1304  )
1305  >
1306  T& emplace( Args&&... args )
1307  {
1308  *this = nullopt;
1309  contained.emplace( std::forward<Args>(args)... );
1310  has_value_ = true;
1311  return contained.value();
1312  }
1313 
1314  // 8 (C++11) - emplace, initializer-list
1315  template< typename U, typename... Args
1316  optional_REQUIRES_T(
1318  )
1319  >
1320  T& emplace( std::initializer_list<U> il, Args&&... args )
1321  {
1322  *this = nullopt;
1323  contained.emplace( il, std::forward<Args>(args)... );
1324  has_value_ = true;
1325  return contained.value();
1326  }
1327 
1328 #endif // optional_CPP11_OR_GREATER
1329 
1330  // x.x.3.4, swap
1331 
1332  void swap( optional & other )
1334  noexcept(
1337  )
1338 #endif
1339  {
1340  using std::swap;
1341  if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); }
1342  else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); }
1343  else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); }
1344  }
1345 
1346  // x.x.3.5, observers
1347 
1349  {
1350  return assert( has_value() ),
1351  contained.value_ptr();
1352  }
1353 
1355  {
1356  return assert( has_value() ),
1357  contained.value_ptr();
1358  }
1359 
1361  {
1362  return assert( has_value() ),
1363  contained.value();
1364  }
1365 
1367  {
1368  return assert( has_value() ),
1369  contained.value();
1370  }
1371 
1372 #if optional_HAVE( REF_QUALIFIER )
1373 
1375  {
1376  return std::move( **this );
1377  }
1378 
1380  {
1381  return std::move( **this );
1382  }
1383 
1384 #endif
1385 
1387  optional_constexpr explicit operator bool() const optional_noexcept
1388  {
1389  return has_value();
1390  }
1391 #else
1393  {
1395  }
1396 #endif
1397 
1398  // NOLINTNEXTLINE( modernize-use-nodiscard )
1399  /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept
1400  {
1401  return has_value_;
1402  }
1403 
1404  // NOLINTNEXTLINE( modernize-use-nodiscard )
1405  /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual
1406  {
1408  assert( has_value() );
1409 #else
1410  if ( ! has_value() )
1411  {
1412  throw bad_optional_access();
1413  }
1414 #endif
1415  return contained.value();
1416  }
1417 
1419  {
1421  assert( has_value() );
1422 #else
1423  if ( ! has_value() )
1424  {
1425  throw bad_optional_access();
1426  }
1427 #endif
1428  return contained.value();
1429  }
1430 
1432 
1433  // NOLINTNEXTLINE( modernize-use-nodiscard )
1434  /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual
1435  {
1436  return std::move( value() );
1437  }
1438 
1440  {
1441  return std::move( value() );
1442  }
1443 
1444 #endif
1445 
1447 
1448  template< typename U >
1450  {
1451  return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
1452  }
1453 
1454  template< typename U >
1456  {
1457  return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
1458  }
1459 
1460 #else
1461 
1462  template< typename U >
1464  {
1465  return has_value() ? contained.value() : static_cast<value_type>( v );
1466  }
1467 
1468 #endif // optional_CPP11_OR_GREATER
1469 
1470  // x.x.3.6, modifiers
1471 
1473  {
1474  if ( has_value() )
1475  {
1477  }
1478 
1479  has_value_ = false;
1480  }
1481 
1482 private:
1484 
1485  template< typename V >
1486  void initialize( V const & value )
1487  {
1488  assert( ! has_value() );
1490  has_value_ = true;
1491  }
1492 
1494  template< typename V >
1495  void initialize( V && value )
1496  {
1497  assert( ! has_value() );
1499  has_value_ = true;
1500  }
1501 
1502 #endif
1503 
1504 private:
1507 
1508 };
1509 
1510 // Relational operators
1511 
1512 template< typename T, typename U >
1513 inline optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y )
1514 {
1515  return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
1516 }
1517 
1518 template< typename T, typename U >
1519 inline optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y )
1520 {
1521  return !(x == y);
1522 }
1523 
1524 template< typename T, typename U >
1525 inline optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y )
1526 {
1527  return (!y) ? false : (!x) ? true : *x < *y;
1528 }
1529 
1530 template< typename T, typename U >
1531 inline optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y )
1532 {
1533  return (y < x);
1534 }
1535 
1536 template< typename T, typename U >
1537 inline optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y )
1538 {
1539  return !(y < x);
1540 }
1541 
1542 template< typename T, typename U >
1543 inline optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y )
1544 {
1545  return !(x < y);
1546 }
1547 
1548 // Comparison with nullopt
1549 
1550 template< typename T >
1551 inline optional_constexpr bool operator==( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1552 {
1553  return (!x);
1554 }
1555 
1556 template< typename T >
1557 inline optional_constexpr bool operator==( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1558 {
1559  return (!x);
1560 }
1561 
1562 template< typename T >
1563 inline optional_constexpr bool operator!=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1564 {
1565  return bool(x);
1566 }
1567 
1568 template< typename T >
1569 inline optional_constexpr bool operator!=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1570 {
1571  return bool(x);
1572 }
1573 
1574 template< typename T >
1575 inline optional_constexpr bool operator<( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
1576 {
1577  return false;
1578 }
1579 
1580 template< typename T >
1581 inline optional_constexpr bool operator<( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1582 {
1583  return bool(x);
1584 }
1585 
1586 template< typename T >
1587 inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1588 {
1589  return (!x);
1590 }
1591 
1592 template< typename T >
1593 inline optional_constexpr bool operator<=( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
1594 {
1595  return true;
1596 }
1597 
1598 template< typename T >
1599 inline optional_constexpr bool operator>( optional<T> const & x, nullopt_t /*unused*/ ) optional_noexcept
1600 {
1601  return bool(x);
1602 }
1603 
1604 template< typename T >
1605 inline optional_constexpr bool operator>( nullopt_t /*unused*/, optional<T> const & /*unused*/ ) optional_noexcept
1606 {
1607  return false;
1608 }
1609 
1610 template< typename T >
1611 inline optional_constexpr bool operator>=( optional<T> const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept
1612 {
1613  return true;
1614 }
1615 
1616 template< typename T >
1617 inline optional_constexpr bool operator>=( nullopt_t /*unused*/, optional<T> const & x ) optional_noexcept
1618 {
1619  return (!x);
1620 }
1621 
1622 // Comparison with T
1623 
1624 template< typename T, typename U >
1625 inline optional_constexpr bool operator==( optional<T> const & x, U const & v )
1626 {
1627  return bool(x) ? *x == v : false;
1628 }
1629 
1630 template< typename T, typename U >
1631 inline optional_constexpr bool operator==( U const & v, optional<T> const & x )
1632 {
1633  return bool(x) ? v == *x : false;
1634 }
1635 
1636 template< typename T, typename U >
1637 inline optional_constexpr bool operator!=( optional<T> const & x, U const & v )
1638 {
1639  return bool(x) ? *x != v : true;
1640 }
1641 
1642 template< typename T, typename U >
1643 inline optional_constexpr bool operator!=( U const & v, optional<T> const & x )
1644 {
1645  return bool(x) ? v != *x : true;
1646 }
1647 
1648 template< typename T, typename U >
1649 inline optional_constexpr bool operator<( optional<T> const & x, U const & v )
1650 {
1651  return bool(x) ? *x < v : true;
1652 }
1653 
1654 template< typename T, typename U >
1655 inline optional_constexpr bool operator<( U const & v, optional<T> const & x )
1656 {
1657  return bool(x) ? v < *x : false;
1658 }
1659 
1660 template< typename T, typename U >
1661 inline optional_constexpr bool operator<=( optional<T> const & x, U const & v )
1662 {
1663  return bool(x) ? *x <= v : true;
1664 }
1665 
1666 template< typename T, typename U >
1667 inline optional_constexpr bool operator<=( U const & v, optional<T> const & x )
1668 {
1669  return bool(x) ? v <= *x : false;
1670 }
1671 
1672 template< typename T, typename U >
1673 inline optional_constexpr bool operator>( optional<T> const & x, U const & v )
1674 {
1675  return bool(x) ? *x > v : false;
1676 }
1677 
1678 template< typename T, typename U >
1679 inline optional_constexpr bool operator>( U const & v, optional<T> const & x )
1680 {
1681  return bool(x) ? v > *x : true;
1682 }
1683 
1684 template< typename T, typename U >
1685 inline optional_constexpr bool operator>=( optional<T> const & x, U const & v )
1686 {
1687  return bool(x) ? *x >= v : false;
1688 }
1689 
1690 template< typename T, typename U >
1691 inline optional_constexpr bool operator>=( U const & v, optional<T> const & x )
1692 {
1693  return bool(x) ? v >= *x : true;
1694 }
1695 
1696 // Specialized algorithms
1697 
1698 template< typename T
1700  optional_REQUIRES_T(
1702  && std17::is_swappable<T>::value )
1703 #endif
1704 >
1705 void swap( optional<T> & x, optional<T> & y )
1707  noexcept( noexcept( x.swap(y) ) )
1708 #endif
1709 {
1710  x.swap( y );
1711 }
1712 
1714 
1715 template< typename T >
1717 {
1718  return optional< typename std::decay<T>::type >( std::forward<T>( value ) );
1719 }
1720 
1721 template< typename T, typename...Args >
1723 {
1724  return optional<T>( nonstd_lite_in_place(T), std::forward<Args>(args)...);
1725 }
1726 
1727 template< typename T, typename U, typename... Args >
1729 {
1730  return optional<T>( nonstd_lite_in_place(T), il, std::forward<Args>(args)...);
1731 }
1732 
1733 #else
1734 
1735 template< typename T >
1737 {
1738  return optional<T>( value );
1739 }
1740 
1741 #endif // optional_CPP11_OR_GREATER
1742 
1743 } // namespace optional_lite
1744 
1745 using optional_lite::optional;
1746 using optional_lite::nullopt_t;
1747 using optional_lite::nullopt;
1748 
1750 using optional_lite::bad_optional_access;
1751 #endif
1752 
1753 using optional_lite::make_optional;
1754 
1755 } // namespace nonstd
1756 
1758 
1759 // specialize the std::hash algorithm:
1760 
1761 namespace std {
1762 
1763 template< class T >
1764 struct hash< nonstd::optional<T> >
1765 {
1766 public:
1767  std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
1768  {
1769  return bool( v ) ? std::hash<T>{}( *v ) : 0;
1770  }
1771 };
1772 
1773 } //namespace std
1774 
1775 #endif // optional_CPP11_OR_GREATER
1776 
1777 #if defined(__clang__)
1778 # pragma clang diagnostic pop
1779 #elif defined(__GNUC__)
1780 # pragma GCC diagnostic pop
1781 #elif defined(_MSC_VER )
1782 # pragma warning( pop )
1783 #endif
1784 
1785 #endif // optional_USES_STD_OPTIONAL
1786 
1787 #endif // NONSTD_OPTIONAL_LITE_HPP
optional_constexpr bool operator==(U const &v, optional< T > const &x)
Definition: optional.hpp:1631
#define optional_CPP11_110_C350_G500
Definition: optional.hpp:323
#define optional_USES_STD_OPTIONAL
Definition: optional.hpp:94
optional_nodiscard U const * as() const
Definition: optional.hpp:879
bool_constant< false > false_type
Definition: optional.hpp:460
optional_constexpr bool operator<(U const &v, optional< T > const &x)
Definition: optional.hpp:1655
optional_constexpr bool operator<=(U const &v, optional< T > const &x)
Definition: optional.hpp:1667
#define optional_COMPILER_GNUC_VERSION
Definition: optional.hpp:272
#define optional_CPP11_90
Definition: optional.hpp:306
optional_nodiscard void * ptr() optional_noexcept
Definition: optional.hpp:862
#define optional_ALIGN_TYPE(type)
Definition: optional.hpp:711
#define optional_CONFIG_SELECT_OPTIONAL
Definition: optional.hpp:44
#define optional_nodiscard
Definition: optional.hpp:384
#define optional_COMPILER_MSVC_VER
Definition: optional.hpp:263
#define nonstd_lite_in_place_t( T)
Definition: expected.hpp:171
optional_constexpr bool operator!=(nullopt_t, optional< T > const &x) optional_noexcept
Definition: optional.hpp:1569
optional_constexpr bool operator==(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:1513
optional_constexpr bool operator==(optional< T > const &x, U const &v)
Definition: optional.hpp:1625
#define optional_BETWEEN(v, lo, hi)
Definition: optional.hpp:243
optional_constexpr bool operator!=(optional< T > const &x, nullopt_t) optional_noexcept
Definition: optional.hpp:1563
typedef optional_ALIGN_AS(value_type) align_as_type
optional< T > make_optional(T const &value)
Definition: optional.hpp:1736
#define optional_CPP11_110_C350
Definition: optional.hpp:320
optional_constexpr bool operator>(optional< T > const &x, U const &v)
Definition: optional.hpp:1673
#define optional_CPP11_140_G490
Definition: optional.hpp:317
in_place_t in_place(detail::in_place_index_tag< K >=detail::in_place_index_tag< K >())
Definition: expected.hpp:152
optional_nodiscard void const * ptr() const optional_noexcept
Definition: optional.hpp:867
#define optional_CPP11_110
Definition: optional.hpp:308
storage_t() optional_is_default explicit storage_t(value_type const &v)
Definition: optional.hpp:757
#define optional_CPP11_100
Definition: optional.hpp:307
#define optional_OPTIONAL_NONSTD
Definition: optional.hpp:26
#define optional_CPP11_140
Definition: optional.hpp:310
#define optional_refref_qual
Definition: optional.hpp:405
optional_constexpr bool operator<=(optional< T > const &x, U const &v)
Definition: optional.hpp:1661
in_place_t in_place_index(detail::in_place_index_tag< K >=detail::in_place_index_tag< K >())
Definition: expected.hpp:164
void initialize(V const &value)
Definition: optional.hpp:1486
#define optional_STRINGIFY_(x)
Definition: optional.hpp:21
void construct_value(value_type const &v)
Definition: optional.hpp:764
optional_constexpr bool operator<=(nullopt_t, optional< T > const &) optional_noexcept
Definition: optional.hpp:1593
#define optional_STRINGIFY( x)
Definition: optional.hpp:20
void(optional::* safe_bool)() const
Definition: optional.hpp:923
#define optional_CONFIG_ALIGN_AS_FALLBACK
Definition: optional.hpp:227
#define optional_CPP11_OR_GREATER_
Definition: optional.hpp:73
optional_constexpr bool operator<=(optional< T > const &x, nullopt_t) optional_noexcept
Definition: optional.hpp:1587
#define optional_noexcept
Definition: optional.hpp:390
#define optional_COMPILER_CLANG_VERSION
Definition: optional.hpp:278
optional_constexpr bool operator<=(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:1537
detail::storage_t< value_type > contained
Definition: optional.hpp:1506
#define optional_constexpr
Definition: optional.hpp:366
#define optional_CPP11_120
Definition: optional.hpp:309
#define optional_CPP14_OR_GREATER
Definition: optional.hpp:74
#define optional_lite_PATCH
Definition: optional.hpp:16
disengaged state tag
Definition: optional.hpp:889
optional_constexpr bool operator==(optional< T > const &x, nullopt_t) optional_noexcept
Definition: optional.hpp:1551
optional_constexpr bool operator>(optional< T > const &x, nullopt_t) optional_noexcept
Definition: optional.hpp:1599
#define optional_HAVE_STD_OPTIONAL
Definition: optional.hpp:91
#define optional_HAVE(FEATURE)
Definition: optional.hpp:291
#define optional_CPP11_OR_GREATER
Definition: optional.hpp:72
value_type & value() optional_ref_qual
Definition: optional.hpp:821
optional_constexpr14 optional(optional const &other)
Definition: optional.hpp:952
optional_constexpr bool operator<(nullopt_t, optional< T > const &x) optional_noexcept
Definition: optional.hpp:1581
optional_constexpr bool operator>(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:1531
optional_constexpr bool operator<(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:1525
#define optional_constexpr14
Definition: optional.hpp:378
optional_constexpr bool operator>(nullopt_t, optional< T > const &) optional_noexcept
Definition: optional.hpp:1605
#define optional_CONFIG_NO_EXCEPTIONS
Definition: optional.hpp:56
optional_constexpr bool operator!=(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:1519
optional_nodiscard value_type const * value_ptr() const
Definition: optional.hpp:806
#define optional_CPP17_000
Definition: optional.hpp:314
#define optional_CPLUSPLUS
Definition: optional.hpp:67
optional_constexpr bool operator<(optional< T > const &, nullopt_t) optional_noexcept
Definition: optional.hpp:1575
optional_constexpr bool operator<(optional< T > const &x, U const &v)
Definition: optional.hpp:1649
optional_constexpr bool operator>=(U const &v, optional< T > const &x)
Definition: optional.hpp:1691
optional_nodiscard value_type const & value() const optional_ref_qual
Definition: optional.hpp:816
optional_constexpr optional(nullopt_t) optional_noexcept
Definition: optional.hpp:938
optional_constexpr optional() optional_noexcept
Definition: optional.hpp:931
#define optional_COMPILER_VERSION(major, minor, patch)
Definition: optional.hpp:267
constexpr result_type operator()(argument_type const &arg) const
Definition: expected.hpp:2440
#define optional_ref_qual
Definition: optional.hpp:404
optional_constexpr bool operator>=(optional< T > const &, nullopt_t) optional_noexcept
Definition: optional.hpp:1611
optional_constexpr bool operator>=(optional< T > const &x, U const &v)
Definition: optional.hpp:1685
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: expected.hpp:158
#define optional_OPTIONAL_DEFAULT
Definition: optional.hpp:25
#define optional_lite_MINOR
Definition: optional.hpp:15
optional_constexpr bool operator>=(nullopt_t, optional< T > const &x) optional_noexcept
Definition: optional.hpp:1617
bool_constant< true > true_type
Definition: optional.hpp:459
#define optional_CONFIG_MAX_ALIGN_HACK
Definition: optional.hpp:219
#define optional_CPP17_OR_GREATER
Definition: optional.hpp:75
#define optional_lite_MAJOR
Definition: optional.hpp:14
#define optional_is_default
Definition: optional.hpp:372
#define optional_OPTIONAL_STD
Definition: optional.hpp:27
#define optional_COMPILER_MSVC_VERSION
Definition: optional.hpp:264
#define optional_CPP14_000
Definition: optional.hpp:313
std11::conditional< N==sizeof(typename List::head), typename List::head, typename type_of_size< typename List::tail, N >::type >::type type
Definition: optional.hpp:699
#define nonstd_lite_in_place( T)
Definition: expected.hpp:175
optional_constexpr bool operator>=(optional< T > const &x, optional< U > const &y)
Definition: optional.hpp:1543
optional_constexpr bool operator!=(optional< T > const &x, U const &v)
Definition: optional.hpp:1637
optional_constexpr bool operator>(U const &v, optional< T > const &x)
Definition: optional.hpp:1679
optional_constexpr bool operator!=(U const &v, optional< T > const &x)
Definition: optional.hpp:1643
optional_constexpr bool operator==(nullopt_t, optional< T > const &x) optional_noexcept
Definition: optional.hpp:1557
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: expected.hpp:146
optional_constexpr nullopt_t(init) optional_noexcept
Definition: optional.hpp:892