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_VERSION "3.1.0"
15 
16 // C++ language version detection (C++20 is speculative):
17 // Note: VC14.0/1900 (VS2015) lacks too much from C++14.
18 
19 #ifndef optional_CPLUSPLUS
20 # ifdef _MSVC_LANG
21 # define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
22 # else
23 # define optional_CPLUSPLUS __cplusplus
24 # endif
25 #endif
26 
27 #define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L )
28 #define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L )
29 #define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
30 #define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
31 #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
32 
33 // C++ language version (represent 98 as 3):
34 
35 #define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) )
36 
37 // use C++17 std::optional if available:
38 
39 #if defined( __has_include )
40 # define optional_HAS_INCLUDE( arg ) __has_include( arg )
41 #else
42 # define optional_HAS_INCLUDE( arg ) 0
43 #endif
44 
45 #define optional_HAVE_STD_OPTIONAL ( optional_CPP17_OR_GREATER && optional_HAS_INCLUDE( <optional> ) )
46 
47 #if optional_HAVE_STD_OPTIONAL
48 
49 #include <optional>
50 
51 namespace nonstd {
52 
53  using std::optional;
54  using std::bad_optional_access;
55  using std::hash;
56 
57  using std::nullopt;
58  using std::nullopt_t;
59  using std::in_place;
60  using std::in_place_type;
61  using std::in_place_index;
62  using std::in_place_t;
63  using std::in_place_type_t;
64  using std::in_place_index_t;
65 
66  using std::operator==;
67  using std::operator!=;
68  using std::operator<;
69  using std::operator<=;
70  using std::operator>;
71  using std::operator>=;
72  using std::make_optional;
73  using std::swap;
74 }
75 
76 #else // C++17 std::optional
77 
78 #include <cassert>
79 #include <stdexcept>
80 #include <utility>
81 
82 // optional-lite alignment configuration:
83 
84 #ifndef optional_CONFIG_MAX_ALIGN_HACK
85 # define optional_CONFIG_MAX_ALIGN_HACK 0
86 #endif
87 
88 #ifndef optional_CONFIG_ALIGN_AS
89 // no default, used in #if defined()
90 #endif
91 
92 #ifndef optional_CONFIG_ALIGN_AS_FALLBACK
93 # define optional_CONFIG_ALIGN_AS_FALLBACK double
94 #endif
95 
96 // Compiler warning suppression:
97 
98 #ifdef __clang__
99 # pragma clang diagnostic push
100 # pragma clang diagnostic ignored "-Wundef"
101 #elif defined __GNUC__
102 # pragma GCC diagnostic push
103 # pragma GCC diagnostic ignored "-Wundef"
104 #endif
105 
106 // half-open range [lo..hi):
107 #define optional_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
108 
109 #if defined(_MSC_VER) && !defined(__clang__)
110 # define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900)) )
111 #else
112 # define optional_COMPILER_MSVC_VERSION 0
113 #endif
114 
115 #define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * major + minor ) + patch )
116 
117 #if defined __GNUC__
118 # define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
119 #else
120 # define optional_COMPILER_GNUC_VERSION 0
121 #endif
122 
123 #if defined __clang__
124 # define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
125 #else
126 # define optional_COMPILER_CLANG_VERSION 0
127 #endif
128 
129 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 )
130 # pragma warning( push )
131 # pragma warning( disable: 4345 ) // initialization behavior changed
132 #endif
133 
134 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 )
135 # pragma warning( push )
136 # pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
137 #endif
138 
139 // Presence of language and library features:
140 
141 #define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE )
142 
143 // Presence of C++11 language features:
144 
145 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 100
146 # define optional_HAVE_AUTO 1
147 # define optional_HAVE_NULLPTR 1
148 # define optional_HAVE_STATIC_ASSERT 1
149 #endif
150 
151 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
152 # define optional_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1
153 # define optional_HAVE_INITIALIZER_LIST 1
154 #endif
155 
156 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140
157 # define optional_HAVE_ALIAS_TEMPLATE 1
158 # define optional_HAVE_CONSTEXPR_11 1
159 # define optional_HAVE_ENUM_CLASS 1
160 # define optional_HAVE_EXPLICIT_CONVERSION 1
161 # define optional_HAVE_IS_DEFAULT 1
162 # define optional_HAVE_IS_DELETE 1
163 # define optional_HAVE_NOEXCEPT 1
164 # define optional_HAVE_REF_QUALIFIER 1
165 #endif
166 
167 // Presence of C++14 language features:
168 
169 #if optional_CPP14_OR_GREATER
170 # define optional_HAVE_CONSTEXPR_14 1
171 #endif
172 
173 // Presence of C++17 language features:
174 
175 #if optional_CPP17_OR_GREATER
176 # define optional_HAVE_ENUM_CLASS_CONSTRUCTION_FROM_UNDERLYING_TYPE 1
177 #endif
178 
179 // Presence of C++ library features:
180 
181 #if optional_COMPILER_GNUC_VERSION
182 # define optional_HAVE_TR1_TYPE_TRAITS 1
183 # define optional_HAVE_TR1_ADD_POINTER 1
184 #endif
185 
186 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 90
187 # define optional_HAVE_TYPE_TRAITS 1
188 # define optional_HAVE_STD_ADD_POINTER 1
189 #endif
190 
191 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 110
192 # define optional_HAVE_ARRAY 1
193 #endif
194 
195 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
196 # define optional_HAVE_CONDITIONAL 1
197 #endif
198 
199 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140 || (optional_COMPILER_MSVC_VERSION >= 90 && _HAS_CPP0X)
200 # define optional_HAVE_CONTAINER_DATA_METHOD 1
201 #endif
202 
203 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 120
204 # define optional_HAVE_REMOVE_CV 1
205 #endif
206 
207 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 140
208 # define optional_HAVE_SIZED_TYPES 1
209 #endif
210 
211 // For the rest, consider VC14 as C++11 for optional-lite:
212 
213 #if optional_COMPILER_MSVC_VERSION >= 140
214 # undef optional_CPP11_OR_GREATER
215 # define optional_CPP11_OR_GREATER 1
216 #endif
217 
218 // C++ feature usage:
219 
220 #if optional_HAVE( CONSTEXPR_11 )
221 # define optional_constexpr constexpr
222 #else
223 # define optional_constexpr /*constexpr*/
224 #endif
225 
226 #if optional_HAVE( CONSTEXPR_14 )
227 # define optional_constexpr14 constexpr
228 #else
229 # define optional_constexpr14 /*constexpr*/
230 #endif
231 
232 #if optional_HAVE( NOEXCEPT )
233 # define optional_noexcept noexcept
234 #else
235 # define optional_noexcept /*noexcept*/
236 #endif
237 
238 #if optional_HAVE( NULLPTR )
239 # define optional_nullptr nullptr
240 #else
241 # define optional_nullptr NULL
242 #endif
243 
244 #if optional_HAVE( REF_QUALIFIER )
245 # define optional_ref_qual &
246 # define optional_refref_qual &&
247 #else
248 # define optional_ref_qual /*&*/
249 # define optional_refref_qual /*&&*/
250 #endif
251 
252 // additional includes:
253 
254 #if optional_CPP11_OR_GREATER
255 # include <functional>
256 #endif
257 
258 #if optional_HAVE( INITIALIZER_LIST )
259 # include <initializer_list>
260 #endif
261 
262 #if optional_HAVE( TYPE_TRAITS )
263 # include <type_traits>
264 #elif optional_HAVE( TR1_TYPE_TRAITS )
265 # include <tr1/type_traits>
266 #endif
267 
268 // type traits needed:
269 
270 namespace BT { namespace optional_lite { namespace detail {
271 
272 #if optional_HAVE( CONDITIONAL )
273  using std::conditional;
274 #else
275  template< bool B, typename T, typename F > struct conditional { typedef T type; };
276  template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
277 #endif // optional_HAVE_CONDITIONAL
278 
279 }}}
280 
281 //
282 // in_place: code duplicated in any-lite, optional-lite, variant-lite:
283 //
284 
285 #ifndef nonstd_lite_HAVE_IN_PLACE_TYPES
286 
287 namespace BT {
288 
289 namespace detail {
290 
291 template< class T >
293 
294 template< std::size_t I >
296 
297 } // namespace detail
298 
299 struct in_place_t {};
300 
301 template< class T >
303 {
304  return in_place_t();
305 }
306 
307 template< std::size_t I >
309 {
310  return in_place_t();
311 }
312 
313 template< class T >
315 {
316  return in_place_t();
317 }
318 
319 template< std::size_t I >
321 {
322  return in_place_t();
323 }
324 
325 // mimic templated typedef:
326 
327 #define nonstd_lite_in_place_type_t( T) BT::in_place_t(&)( BT::detail::in_place_type_tag<T> )
328 #define nonstd_lite_in_place_index_t(T) BT::in_place_t(&)( BT::detail::in_place_index_tag<I> )
329 
330 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
331 
332 } // namespace nonstd
333 
334 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
335 
336 //
337 // optional:
338 //
339 
340 namespace BT { namespace optional_lite {
341 
343 
344 template< typename T >
345 class optional;
346 
347 namespace detail {
348 
349 // C++11 emulation:
350 
351 struct nulltype{};
352 
353 template< typename Head, typename Tail >
354 struct typelist
355 {
356  typedef Head head;
357  typedef Tail tail;
358 };
359 
360 #if optional_CONFIG_MAX_ALIGN_HACK
361 
362 // Max align, use most restricted type for alignment:
363 
364 #define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
365 #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
366 #define optional_UNIQUE3( name, line ) name ## line
367 
368 #define optional_ALIGN_TYPE( type ) \
369  type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
370 
371 template< typename T >
372 struct struct_t { T _; };
373 
374 union max_align_t
375 {
376  optional_ALIGN_TYPE( char );
377  optional_ALIGN_TYPE( short int );
378  optional_ALIGN_TYPE( int );
379  optional_ALIGN_TYPE( long int );
380  optional_ALIGN_TYPE( float );
381  optional_ALIGN_TYPE( double );
382  optional_ALIGN_TYPE( long double );
383  optional_ALIGN_TYPE( char * );
384  optional_ALIGN_TYPE( short int * );
385  optional_ALIGN_TYPE( int * );
386  optional_ALIGN_TYPE( long int * );
387  optional_ALIGN_TYPE( float * );
388  optional_ALIGN_TYPE( double * );
389  optional_ALIGN_TYPE( long double * );
390  optional_ALIGN_TYPE( void * );
391 
392 #ifdef HAVE_LONG_LONG
393  optional_ALIGN_TYPE( long long );
394 #endif
395 
396  struct Unknown;
397 
398  Unknown ( * optional_UNIQUE(_) )( Unknown );
399  Unknown * Unknown::* optional_UNIQUE(_);
400  Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
401 
402  struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
403  struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
405 };
406 
407 #undef optional_UNIQUE
408 #undef optional_UNIQUE2
409 #undef optional_UNIQUE3
410 
411 #undef optional_ALIGN_TYPE
412 
413 #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
414 
415 // Use user-specified type for alignment:
416 
417 #define optional_ALIGN_AS( unused ) \
418  optional_CONFIG_ALIGN_AS
419 
420 #else // optional_CONFIG_MAX_ALIGN_HACK
421 
422 // Determine POD type to use for alignment:
423 
424 #define optional_ALIGN_AS( to_align ) \
425  typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
426 
427 template <typename T>
429 
430 template <typename T>
432 {
433  char c;
434  T t;
436 };
437 
438 template <unsigned A, unsigned S>
440 {
441  enum { value = A < S ? A : S };
442 };
443 
444 template< typename T >
445 struct alignment_of
446 {
447  enum { value = alignment_logic<
448  sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value, };
449 };
450 
451 template< typename List, size_t N >
453 {
454  typedef typename conditional<
455  N == sizeof( typename List::head ),
456  typename List::head,
458 };
459 
460 template< size_t N >
461 struct type_of_size< nulltype, N >
462 {
464 };
465 
466 template< typename T>
467 struct struct_t { T _; };
468 
469 #define optional_ALIGN_TYPE( type ) \
470  typelist< type , typelist< struct_t< type >
471 
472 struct Unknown;
473 
474 typedef
475  optional_ALIGN_TYPE( char ),
476  optional_ALIGN_TYPE( short ),
477  optional_ALIGN_TYPE( int ),
478  optional_ALIGN_TYPE( long ),
479  optional_ALIGN_TYPE( float ),
480  optional_ALIGN_TYPE( double ),
481  optional_ALIGN_TYPE( long double ),
482 
483  optional_ALIGN_TYPE( char *),
484  optional_ALIGN_TYPE( short * ),
485  optional_ALIGN_TYPE( int * ),
486  optional_ALIGN_TYPE( long * ),
487  optional_ALIGN_TYPE( float * ),
488  optional_ALIGN_TYPE( double * ),
489  optional_ALIGN_TYPE( long double * ),
490 
491  optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
492  optional_ALIGN_TYPE( Unknown * Unknown::* ),
493  optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
494 
495  nulltype
496  > > > > > > > > > > > > > >
497  > > > > > > > > > > > > > >
498  > > > > > >
500 
501 #undef optional_ALIGN_TYPE
502 
503 #endif // optional_CONFIG_MAX_ALIGN_HACK
504 
506 
507 template< typename T >
509 {
510 private:
511  friend class optional<T>;
512 
513  typedef T value_type;
514 
516 
517  storage_t( value_type const & v )
518  {
519  construct_value( v );
520  }
521 
522  void construct_value( value_type const & v )
523  {
524  ::new( value_ptr() ) value_type( v );
525  }
526 
527 #if optional_CPP11_OR_GREATER
528 
529  storage_t( value_type && v )
530  {
531  construct_value( std::move( v ) );
532  }
533 
534  void construct_value( value_type && v )
535  {
536  ::new( value_ptr() ) value_type( std::move( v ) );
537  }
538 
539  template< class... Args >
540  void emplace( Args&&... args )
541  {
542  ::new( value_ptr() ) value_type( std::forward<Args>(args)... );
543  }
544 
545  template< class U, class... Args >
546  void emplace( std::initializer_list<U> il, Args&&... args )
547  {
548  ::new( value_ptr() ) value_type( il, std::forward<Args>(args)... );
549  }
550 
551 #endif
552 
554  {
555  value_ptr()->~T();
556  }
557 
558  value_type const * value_ptr() const
559  {
560  return as<value_type>();
561  }
562 
563  value_type * value_ptr()
564  {
565  return as<value_type>();
566  }
567 
568  value_type const & value() const optional_ref_qual
569  {
570  return * value_ptr();
571  }
572 
573  value_type & value() optional_ref_qual
574  {
575  return * value_ptr();
576  }
577 
578 #if optional_CPP11_OR_GREATER
579 
580  value_type const && value() const optional_refref_qual
581  {
582  return std::move( value() );
583  }
584 
585  value_type && value() optional_refref_qual
586  {
587  return std::move( value() );
588  }
589 
590 #endif
591 
592 #if optional_CPP11_OR_GREATER
593 
594  using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type;
595  aligned_storage_t data;
596 
597 #elif optional_CONFIG_MAX_ALIGN_HACK
598 
599  typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
600 
601  max_align_t hack;
602  aligned_storage_t data;
603 
604 #else
605  typedef optional_ALIGN_AS(value_type) align_as_type;
606 
607  typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
608  aligned_storage_t data;
609 
610 # undef optional_ALIGN_AS
611 
612 #endif // optional_CONFIG_MAX_ALIGN_HACK
613 
615  {
616  return &data;
617  }
618 
619  void const * ptr() const optional_noexcept
620  {
621  return &data;
622  }
623 
624  template <typename U>
625  U * as()
626  {
627  return reinterpret_cast<U*>( ptr() );
628  }
629 
630  template <typename U>
631  U const * as() const
632  {
633  return reinterpret_cast<U const *>( ptr() );
634  }
635 };
636 
637 } // namespace detail
638 
640 
641 struct nullopt_t
642 {
643  struct init{};
645 };
646 
647 #if optional_HAVE( CONSTEXPR_11 )
648 constexpr nullopt_t nullopt{ nullopt_t::init{} };
649 #else
650 // extra parenthesis to prevent the most vexing parse:
651 const nullopt_t nullopt(( nullopt_t::init() ));
652 #endif
653 
655 
656 class bad_optional_access : public std::logic_error
657 {
658 public:
660  : logic_error( "bad optional access" ) {}
661 };
662 
664 
665 template< typename T>
666 class optional
667 {
668 private:
669  typedef void (optional::*safe_bool)() const;
670 
671 public:
672  typedef T value_type;
673 
675  : has_value_( false )
676  , contained()
677  {}
678 
680  : has_value_( false )
681  , contained()
682  {}
683 
684  optional( optional const & rhs )
685  : has_value_( rhs.has_value() )
686  {
687  if ( rhs.has_value() )
688  contained.construct_value( rhs.contained.value() );
689  }
690 
691 #if optional_CPP11_OR_GREATER
692  optional_constexpr14 optional( optional && rhs ) noexcept( std::is_nothrow_move_constructible<T>::value )
693  : has_value_( rhs.has_value() )
694  {
695  if ( rhs.has_value() )
696  contained.construct_value( std::move( rhs.contained.value() ) );
697  }
698 #endif
699 
700  optional_constexpr optional( value_type const & value )
701  : has_value_( true )
702  , contained( value )
703  {}
704 
705 #if optional_CPP11_OR_GREATER
706 
707  optional_constexpr optional( value_type && value )
708  : has_value_( true )
709  , contained( std::move( value ) )
710  {}
711 
712  template< class... Args >
713  optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), Args&&... args )
714  : has_value_( true )
715  , contained( T( std::forward<Args>(args)...) )
716  {}
717 
718  template< class U, class... Args >
719  optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
720  : has_value_( true )
721  , contained( T( il, std::forward<Args>(args)...) )
722  {}
723 
724 #endif // optional_CPP11_OR_GREATER
725 
727  {
728  if ( has_value() )
729  contained.destruct_value();
730  }
731 
732  // assignment
733 
735  {
736  reset();
737  return *this;
738  }
739 
740  optional & operator=( optional const & rhs )
741 #if optional_CPP11_OR_GREATER
742  noexcept( std::is_nothrow_move_assignable<T>::value && std::is_nothrow_move_constructible<T>::value )
743 #endif
744  {
745  if ( has_value() == true && rhs.has_value() == false ) reset();
746  else if ( has_value() == false && rhs.has_value() == true ) initialize( *rhs );
747  else if ( has_value() == true && rhs.has_value() == true ) contained.value() = *rhs;
748  return *this;
749  }
750 
751 #if optional_CPP11_OR_GREATER
752 
753  optional & operator=( optional && rhs ) noexcept
754  {
755  if ( has_value() == true && rhs.has_value() == false ) reset();
756  else if ( has_value() == false && rhs.has_value() == true ) initialize( std::move( *rhs ) );
757  else if ( has_value() == true && rhs.has_value() == true ) contained.value() = std::move( *rhs );
758  return *this;
759  }
760 
761  template< class U,
762  typename = typename std::enable_if< std::is_same< typename std::decay<U>::type, T>::value >::type >
763  optional & operator=( U && v )
764  {
765  if ( has_value() ) contained.value() = std::forward<U>( v );
766  else initialize( T( std::forward<U>( v ) ) );
767  return *this;
768  }
769 
770  template< class... Args >
771  void emplace( Args&&... args )
772  {
773  *this = nullopt;
774  contained.emplace( std::forward<Args>(args)... );
775  has_value_ = true;
776  }
777 
778 
779  template< class U, class... Args >
780  void emplace( std::initializer_list<U> il, Args&&... args )
781  {
782  *this = nullopt;
783  contained.emplace( il, std::forward<Args>(args)... );
784  has_value_ = true;
785  }
786 
787 #endif // optional_CPP11_OR_GREATER
788 
789  // swap
790 
791  void swap( optional & rhs )
792 #if optional_CPP11_OR_GREATER
793  noexcept( std::is_nothrow_move_constructible<T>::value && noexcept( std::swap( std::declval<T&>(), std::declval<T&>() ) ) )
794 #endif
795  {
796  using std::swap;
797  if ( has_value() == true && rhs.has_value() == true ) { swap( **this, *rhs ); }
798  else if ( has_value() == false && rhs.has_value() == true ) { initialize( *rhs ); rhs.reset(); }
799  else if ( has_value() == true && rhs.has_value() == false ) { rhs.initialize( **this ); reset(); }
800  }
801 
802  // observers
803 
804  optional_constexpr value_type const * operator ->() const
805  {
806  return assert( has_value() ),
807  contained.value_ptr();
808  }
809 
810  optional_constexpr14 value_type * operator ->()
811  {
812  return assert( has_value() ),
813  contained.value_ptr();
814  }
815 
816  optional_constexpr value_type const & operator *() const optional_ref_qual
817  {
818  return assert( has_value() ),
819  contained.value();
820  }
821 
822  optional_constexpr14 value_type & operator *() optional_ref_qual
823  {
824  return assert( has_value() ),
825  contained.value();
826  }
827 
828 #if optional_CPP11_OR_GREATER
829 
830  optional_constexpr value_type const && operator *() const optional_refref_qual
831  {
832  return std::move( **this );
833  }
834 
835  optional_constexpr14 value_type && operator *() optional_refref_qual
836  {
837  return std::move( **this );
838  }
839 
840 #endif
841 
842 #if optional_CPP11_OR_GREATER
843  optional_constexpr explicit operator bool() const optional_noexcept
844  {
845  return has_value();
846  }
847 #else
848  optional_constexpr operator safe_bool() const optional_noexcept
849  {
850  return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
851  }
852 #endif
853 
855  {
856  return has_value_;
857  }
858 
859  optional_constexpr14 value_type const & value() const optional_ref_qual
860  {
861  if ( ! has_value() )
862  throw bad_optional_access();
863 
864  return contained.value();
865  }
866 
868  {
869  if ( ! has_value() )
870  throw bad_optional_access();
871 
872  return contained.value();
873  }
874 
875 #if optional_HAVE( REF_QUALIFIER )
876 
877  optional_constexpr14 value_type const && value() const optional_refref_qual
878  {
879  return std::move( value() );
880  }
881 
882  optional_constexpr14 value_type && value() optional_refref_qual
883  {
884  return std::move( value() );
885  }
886 
887 #endif
888 
889 #if optional_CPP11_OR_GREATER
890 
891  template< class U >
892  optional_constexpr value_type value_or( U && v ) const optional_ref_qual
893  {
894  return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
895  }
896 
897  template< class U >
898  optional_constexpr value_type value_or( U && v ) const optional_refref_qual
899  {
900  return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
901  }
902 
903 #else
904 
905  template< class U >
906  optional_constexpr value_type value_or( U const & v ) const
907  {
908  return has_value() ? contained.value() : static_cast<value_type>( v );
909  }
910 
911 #endif // optional_CPP11_OR_GREATER
912 
913  // modifiers
914 
916  {
917  if ( has_value() )
918  contained.destruct_value();
919 
920  has_value_ = false;
921  }
922 
923 private:
925 
926  template< typename V >
927  void initialize( V const & value )
928  {
929  assert( ! has_value() );
930  contained.construct_value( value );
931  has_value_ = true;
932  }
933 
934 #if optional_CPP11_OR_GREATER
935  template< typename V >
936  void initialize( V && value )
937  {
938  assert( ! has_value() );
939  contained.construct_value( std::move( value ) );
940  has_value_ = true;
941  }
942 
943 #endif
944 
945 private:
948 
949 };
950 
951 // Relational operators
952 
953 template< typename T, typename U >
954 inline optional_constexpr bool operator==( optional<T> const & x, optional<U> const & y )
955 {
956  return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y;
957 }
958 
959 template< typename T, typename U >
960 inline optional_constexpr bool operator!=( optional<T> const & x, optional<U> const & y )
961 {
962  return !(x == y);
963 }
964 
965 template< typename T, typename U >
966 inline optional_constexpr bool operator<( optional<T> const & x, optional<U> const & y )
967 {
968  return (!y) ? false : (!x) ? true : *x < *y;
969 }
970 
971 template< typename T, typename U >
972 inline optional_constexpr bool operator>( optional<T> const & x, optional<U> const & y )
973 {
974  return (y < x);
975 }
976 
977 template< typename T, typename U >
978 inline optional_constexpr bool operator<=( optional<T> const & x, optional<U> const & y )
979 {
980  return !(y < x);
981 }
982 
983 template< typename T, typename U >
984 inline optional_constexpr bool operator>=( optional<T> const & x, optional<U> const & y )
985 {
986  return !(x < y);
987 }
988 
989 // Comparison with nullopt
990 
991 template< typename T >
993 {
994  return (!x);
995 }
996 
997 template< typename T >
999 {
1000  return (!x);
1001 }
1002 
1003 template< typename T >
1005 {
1006  return bool(x);
1007 }
1008 
1009 template< typename T >
1011 {
1012  return bool(x);
1013 }
1014 
1015 template< typename T >
1016 inline optional_constexpr bool operator<( optional<T> const &, nullopt_t ) optional_noexcept
1017 {
1018  return false;
1019 }
1020 
1021 template< typename T >
1022 inline optional_constexpr bool operator<( nullopt_t, optional<T> const & x ) optional_noexcept
1023 {
1024  return bool(x);
1025 }
1026 
1027 template< typename T >
1028 inline optional_constexpr bool operator<=( optional<T> const & x, nullopt_t ) optional_noexcept
1029 {
1030  return (!x);
1031 }
1032 
1033 template< typename T >
1034 inline optional_constexpr bool operator<=( nullopt_t, optional<T> const & ) optional_noexcept
1035 {
1036  return true;
1037 }
1038 
1039 template< typename T >
1041 {
1042  return bool(x);
1043 }
1044 
1045 template< typename T >
1047 {
1048  return false;
1049 }
1050 
1051 template< typename T >
1053 {
1054  return true;
1055 }
1056 
1057 template< typename T >
1059 {
1060  return (!x);
1061 }
1062 
1063 // Comparison with T
1064 
1065 template< typename T, typename U >
1066 inline optional_constexpr bool operator==( optional<T> const & x, U const & v )
1067 {
1068  return bool(x) ? *x == v : false;
1069 }
1070 
1071 template< typename T, typename U >
1072 inline optional_constexpr bool operator==( U const & v, optional<T> const & x )
1073 {
1074  return bool(x) ? v == *x : false;
1075 }
1076 
1077 template< typename T, typename U >
1078 inline optional_constexpr bool operator!=( optional<T> const & x, U const & v )
1079 {
1080  return bool(x) ? *x != v : true;
1081 }
1082 
1083 template< typename T, typename U >
1084 inline optional_constexpr bool operator!=( U const & v, optional<T> const & x )
1085 {
1086  return bool(x) ? v != *x : true;
1087 }
1088 
1089 template< typename T, typename U >
1090 inline optional_constexpr bool operator<( optional<T> const & x, U const & v )
1091 {
1092  return bool(x) ? *x < v : true;
1093 }
1094 
1095 template< typename T, typename U >
1096 inline optional_constexpr bool operator<( U const & v, optional<T> const & x )
1097 {
1098  return bool(x) ? v < *x : false;
1099 }
1100 
1101 template< typename T, typename U >
1102 inline optional_constexpr bool operator<=( optional<T> const & x, U const & v )
1103 {
1104  return bool(x) ? *x <= v : true;
1105 }
1106 
1107 template< typename T, typename U >
1108 inline optional_constexpr bool operator<=( U const & v, optional<T> const & x )
1109 {
1110  return bool(x) ? v <= *x : false;
1111 }
1112 
1113 template< typename T, typename U >
1114 inline optional_constexpr bool operator>( optional<T> const & x, U const & v )
1115 {
1116  return bool(x) ? *x > v : false;
1117 }
1118 
1119 template< typename T, typename U >
1120 inline optional_constexpr bool operator>( U const & v, optional<T> const & x )
1121 {
1122  return bool(x) ? v > *x : true;
1123 }
1124 
1125 template< typename T, typename U >
1126 inline optional_constexpr bool operator>=( optional<T> const & x, U const & v )
1127 {
1128  return bool(x) ? *x >= v : false;
1129 }
1130 
1131 template< typename T, typename U >
1132 inline optional_constexpr bool operator>=( U const & v, optional<T> const & x )
1133 {
1134  return bool(x) ? v >= *x : true;
1135 }
1136 
1137 // Specialized algorithms
1138 
1139 template< typename T >
1140 void swap( optional<T> & x, optional<T> & y )
1141 #if optional_CPP11_OR_GREATER
1142  noexcept( noexcept( x.swap(y) ) )
1143 #endif
1144 {
1145  x.swap( y );
1146 }
1147 
1148 #if optional_CPP11_OR_GREATER
1149 
1150 template< class T >
1152 {
1153  return optional< typename std::decay<T>::type >( std::forward<T>( v ) );
1154 }
1155 
1156 template< class T, class...Args >
1158 {
1159  return optional<T>( in_place, std::forward<Args>(args)...);
1160 }
1161 
1162 template< class T, class U, class... Args >
1163 optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
1164 {
1165  return optional<T>( in_place, il, std::forward<Args>(args)...);
1166 }
1167 
1168 #else
1169 
1170 template< typename T >
1172 {
1173  return optional<T>( v );
1174 }
1175 
1176 #endif // optional_CPP11_OR_GREATER
1177 
1178 } // namespace optional
1179 
1180 using namespace optional_lite;
1181 
1182 } // namespace nonstd
1183 
1184 #if optional_CPP11_OR_GREATER
1185 
1186 // specialize the std::hash algorithm:
1187 
1188 namespace std {
1189 
1190 template< class T >
1191 struct hash< BT::optional<T> >
1192 {
1193 public:
1194  std::size_t operator()( BT::optional<T> const & v ) const optional_noexcept
1195  {
1196  return bool( v ) ? hash<T>()( *v ) : 0;
1197  }
1198 };
1199 
1200 } //namespace std
1201 
1202 #endif // optional_CPP11_OR_GREATER
1203 
1204 #ifdef __clang__
1205 # pragma clang diagnostic pop
1206 #elif defined __GNUC__
1207 # pragma GCC diagnostic pop
1208 #endif
1209 
1210 #endif // have C++17 std::optional
1211 
1212 #endif // NONSTD_OPTIONAL_LITE_HPP
const T * data(const std::vector< T, Alloc > &v)
Definition: flatbuffers.h:709
optional_constexpr bool operator>(U const &v, optional< T > const &x)
Definition: optional.hpp:1120
void * ptr() optional_noexcept
Definition: optional.hpp:614
void const * ptr() const optional_noexcept
Definition: optional.hpp:619
void swap(optional< T > &x, optional< T > &y)
Definition: optional.hpp:1140
in_place_t in_place_type(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: optional.hpp:314
#define optional_noexcept
Definition: optional.hpp:235
#define optional_ref_qual
Definition: optional.hpp:248
optional_constexpr nullopt_t(init)
Definition: optional.hpp:644
void swap(optional &rhs)
Definition: optional.hpp:791
optional_constexpr14 value_type const & value() const optional_ref_qual
Definition: optional.hpp:859
optional & operator=(nullopt_t) optional_noexcept
Definition: optional.hpp:734
Definition: any.hpp:455
void swap(linb::any &lhs, linb::any &rhs) noexcept
Definition: any.hpp:457
C++03 constructed union to hold value.
Definition: optional.hpp:508
void this_type_does_not_support_comparisons() const
Definition: optional.hpp:924
optional< T > make_optional(T const &v)
Definition: optional.hpp:1171
conditional< N==sizeof(typename List::head), typename List::head, typename type_of_size< typename List::tail, N >::type >::type type
Definition: optional.hpp:457
optional_constexpr optional() optional_noexcept
Definition: optional.hpp:674
optional & operator=(optional const &rhs)
Definition: optional.hpp:740
value_type const & value() const optional_ref_qual
Definition: optional.hpp:568
void initialize(V const &value)
Definition: optional.hpp:927
optional(optional const &rhs)
Definition: optional.hpp:684
#define nonstd_lite_in_place_type_t(T)
Definition: optional.hpp:327
const nullopt_t nullopt((nullopt_t::init()))
optional_constexpr value_type value_or(U const &v) const
Definition: optional.hpp:906
storage_t(value_type const &v)
Definition: optional.hpp:517
in_place_t in_place(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
Definition: optional.hpp:308
#define optional_CONFIG_ALIGN_AS_FALLBACK
Definition: optional.hpp:93
#define optional_refref_qual
Definition: optional.hpp:249
optional_constexpr14 value_type & value() optional_ref_qual
Definition: optional.hpp:867
optional_constexpr bool operator==(U const &v, optional< T > const &x)
Definition: optional.hpp:1072
optional_constexpr optional(nullopt_t) optional_noexcept
Definition: optional.hpp:679
value_type & value() optional_ref_qual
Definition: optional.hpp:573
#define optional_ALIGN_TYPE(type)
Definition: optional.hpp:469
#define optional_constexpr14
Definition: optional.hpp:229
void construct_value(value_type const &v)
Definition: optional.hpp:522
optional_constexpr bool operator!=(U const &v, optional< T > const &x)
Definition: optional.hpp:1084
optional_constexpr bool has_value() const optional_noexcept
Definition: optional.hpp:854
in_place_t in_place_index(detail::in_place_index_tag< I >=detail::in_place_index_tag< I >())
Definition: optional.hpp:320
value_type const * value_ptr() const
Definition: optional.hpp:558
void reset() optional_noexcept
Definition: optional.hpp:915
optional_constexpr bool operator>=(U const &v, optional< T > const &x)
Definition: optional.hpp:1132
disengaged state tag
Definition: optional.hpp:641
detail::storage_t< value_type > contained
Definition: optional.hpp:947
#define optional_ALIGN_AS(to_align)
Definition: optional.hpp:424
optional_constexpr optional(value_type const &value)
Definition: optional.hpp:700
#define optional_constexpr
Definition: optional.hpp:223


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 04:01:53