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