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