optional.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016 Martin Moene
3 //
4 // https://github.com/martinmoene/optional-lite
5 //
6 // This code is licensed under the MIT License (MIT).
7 //
8 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
13 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
14 // THE SOFTWARE.
15 
16 #pragma once
17 
18 #ifndef NONSTD_OPTIONAL_LITE_HPP
19 #define NONSTD_OPTIONAL_LITE_HPP
20 
21 #include <cassert>
22 #include <stdexcept>
23 #include <utility>
24 
25 #define optional_lite_VERSION "2.0.0"
26 
27 // variant-lite alignment configuration:
28 
29 #ifndef optional_CONFIG_MAX_ALIGN_HACK
30 # define optional_CONFIG_MAX_ALIGN_HACK 0
31 #endif
32 
33 #ifndef optional_CONFIG_ALIGN_AS
34 // no default, used in #if defined()
35 #endif
36 
37 #ifndef optional_CONFIG_ALIGN_AS_FALLBACK
38 # define optional_CONFIG_ALIGN_AS_FALLBACK double
39 #endif
40 
41 // Compiler detection (C++17 is speculative):
42 
43 #define optional_CPP11_OR_GREATER ( __cplusplus >= 201103L )
44 #define optional_CPP14_OR_GREATER ( __cplusplus >= 201402L )
45 
46 // half-open range [lo..hi):
47 #define optional_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
48 
49 #if defined(_MSC_VER) && !defined(__clang__)
50 # define optional_COMPILER_MSVC_VERSION (_MSC_VER / 100 - 5 - (_MSC_VER < 1900))
51 #else
52 # define optional_COMPILER_MSVC_VERSION 0
53 #endif
54 
55 #if defined __GNUC__
56 # define optional_COMPILER_GNUC_VERSION __GNUC__
57 #else
58 # define optional_COMPILER_GNUC_VERSION 0
59 #endif
60 
61 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 7, 14 )
62 # pragma warning( push )
63 # pragma warning( disable: 4345 ) // initialization behavior changed
64 #endif
65 
66 #if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 7, 15 )
67 # pragma warning( push )
68 # pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const'
69 #endif
70 
71 // Presence of C++11 language features:
72 
73 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 10
74 # define optional_HAVE_AUTO 1
75 # define optional_HAVE_NULLPTR 1
76 # define optional_HAVE_STATIC_ASSERT 1
77 #endif
78 
79 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 12
80 # define optional_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG 1
81 # define optional_HAVE_INITIALIZER_LIST 1
82 #endif
83 
84 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 14
85 # define optional_HAVE_ALIAS_TEMPLATE 1
86 # define optional_HAVE_CONSTEXPR_11 1
87 # define optional_HAVE_ENUM_CLASS 1
88 # define optional_HAVE_EXPLICIT_CONVERSION 1
89 # define optional_HAVE_IS_DEFAULT 1
90 # define optional_HAVE_IS_DELETE 1
91 # define optional_HAVE_NOEXCEPT 1
92 # define optional_HAVE_REF_QUALIFIER 1
93 #endif
94 
95 // Presence of C++14 language features:
96 
97 #if optional_CPP14_OR_GREATER
98 # define optional_HAVE_CONSTEXPR_14 1
99 #endif
100 
101 // Presence of C++ library features:
102 
103 #if optional_COMPILER_GNUC_VERSION
104 # define optional_HAVE_TR1_TYPE_TRAITS 1
105 # define optional_HAVE_TR1_ADD_POINTER 1
106 #endif
107 
108 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 9
109 # define optional_HAVE_TYPE_TRAITS 1
110 # define optional_HAVE_STD_ADD_POINTER 1
111 #endif
112 
113 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 11
114 # define optional_HAVE_ARRAY 1
115 #endif
116 
117 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 12
118 # define optional_HAVE_CONDITIONAL 1
119 #endif
120 
121 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 14 || (optional_COMPILER_MSVC_VERSION >= 9 && _HAS_CPP0X)
122 # define optional_HAVE_CONTAINER_DATA_METHOD 1
123 #endif
124 
125 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 12
126 # define optional_HAVE_REMOVE_CV 1
127 #endif
128 
129 #if optional_CPP11_OR_GREATER || optional_COMPILER_MSVC_VERSION >= 14
130 # define optional_HAVE_SIZED_TYPES 1
131 #endif
132 
133 // For the rest, consider VC14 as C++11 for variant-lite:
134 
135 #if optional_COMPILER_MSVC_VERSION >= 14
136 # undef optional_CPP11_OR_GREATER
137 # define optional_CPP11_OR_GREATER 1
138 #endif
139 
140 // C++ feature usage:
141 
142 #if optional_HAVE_CONSTEXPR_11
143 # define optional_constexpr constexpr
144 #else
145 # define optional_constexpr /*constexpr*/
146 #endif
147 
148 #if optional_HAVE_CONSTEXPR_14
149 # define optional_constexpr14 constexpr
150 #else
151 # define optional_constexpr14 /*constexpr*/
152 #endif
153 
154 #if optional_HAVE_NOEXCEPT
155 # define optional_noexcept noexcept
156 #else
157 # define optional_noexcept /*noexcept*/
158 #endif
159 
160 #if optional_HAVE_NULLPTR
161 # define optional_nullptr nullptr
162 #else
163 # define optional_nullptr NULL
164 #endif
165 
166 #if optional_HAVE_REF_QUALIFIER
167 # define optional_ref_qual &
168 # define optional_refref_qual &&
169 #else
170 # define optional_ref_qual /*&*/
171 # define optional_refref_qual /*&&*/
172 #endif
173 
174 // additional includes:
175 
176 #if optional_HAVE_INITIALIZER_LIST
177 # include <initializer_list>
178 #endif
179 
180 #if optional_HAVE_TYPE_TRAITS
181 # include <type_traits>
182 #elif optional_HAVE_TR1_TYPE_TRAITS
183 # include <tr1/type_traits>
184 #endif
185 
186 //
187 // in_place: code duplicated in any-lite, optional-lite, variant-lite:
188 //
189 
190 #if ! nonstd_lite_HAVE_IN_PLACE_TYPES
191 
192 namespace nonstd {
193 
194 namespace detail {
195 
196 template< class T >
197 struct in_place_type_tag {};
198 
199 template< std::size_t I >
200 struct in_place_index_tag {};
201 
202 } // namespace detail
203 
204 struct in_place_t {};
205 
206 template< class T >
207 inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
208 {
209  return in_place_t();
210 }
211 
212 template< std::size_t I >
213 inline in_place_t in_place( detail::in_place_index_tag<I> = detail::in_place_index_tag<I>() )
214 {
215  return in_place_t();
216 }
217 
218 // mimic templated typedef:
219 
220 #define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T> )
221 #define nonstd_lite_in_place_index_t(T) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<I> )
222 
223 #define nonstd_lite_HAVE_IN_PLACE_TYPES 1
224 
225 } // namespace nonstd
226 
227 #endif // nonstd_lite_HAVE_IN_PLACE_TYPES
228 
229 //
230 // optional:
231 //
232 
233 namespace nonstd { namespace optional_lite {
234 
236 
237 template< typename T >
238 class optional;
239 
240 namespace detail {
241 
242 // C++11 emulation:
243 
244 #if variant_HAVE_CONDITIONAL
245 
246 using std::conditional;
247 
248 #else
249 
250 template< bool Cond, class Then, class Else >
251 struct conditional;
252 
253 template< class Then, class Else >
254 struct conditional< true , Then, Else > { typedef Then type; };
255 
256 template< class Then, class Else >
257 struct conditional< false, Then, Else > { typedef Else type; };
258 
259 #endif // variant_HAVE_CONDITIONAL
260 
261 struct nulltype{};
262 
263 template< typename Head, typename Tail >
264 struct typelist
265 {
266  typedef Head head;
267  typedef Tail tail;
268 };
269 
270 #if optional_CONFIG_MAX_ALIGN_HACK
271 
272 // Max align, use most restricted type for alignment:
273 
274 #define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ )
275 #define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line )
276 #define optional_UNIQUE3( name, line ) name ## line
277 
278 #define optional_ALIGN_TYPE( type ) \
279  type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st )
280 
281 template< typename T >
282 struct struct_t { T _; };
283 
284 union max_align_t
285 {
286  optional_ALIGN_TYPE( char );
287  optional_ALIGN_TYPE( short int );
288  optional_ALIGN_TYPE( int );
289  optional_ALIGN_TYPE( long int );
290  optional_ALIGN_TYPE( float );
291  optional_ALIGN_TYPE( double );
292  optional_ALIGN_TYPE( long double );
293  optional_ALIGN_TYPE( char * );
294  optional_ALIGN_TYPE( short int * );
295  optional_ALIGN_TYPE( int * );
296  optional_ALIGN_TYPE( long int * );
297  optional_ALIGN_TYPE( float * );
298  optional_ALIGN_TYPE( double * );
299  optional_ALIGN_TYPE( long double * );
300  optional_ALIGN_TYPE( void * );
301 
302 #ifdef HAVE_LONG_LONG
303  optional_ALIGN_TYPE( long long );
304 #endif
305 
306  struct Unknown;
307 
308  Unknown ( * optional_UNIQUE(_) )( Unknown );
309  Unknown * Unknown::* optional_UNIQUE(_);
310  Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown );
311 
312  struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_);
313  struct_t< Unknown * Unknown::* > optional_UNIQUE(_);
315 };
316 
317 #undef optional_UNIQUE
318 #undef optional_UNIQUE2
319 #undef optional_UNIQUE3
320 
321 #undef optional_ALIGN_TYPE
322 
323 #elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK
324 
325 // Use user-specified type for alignment:
326 
327 #define optional_ALIGN_AS( unused ) \
328  optional_CONFIG_ALIGN_AS
329 
330 #else // optional_CONFIG_MAX_ALIGN_HACK
331 
332 // Determine POD type to use for alignment:
333 
334 #define optional_ALIGN_AS( to_align ) \
335  typename type_of_size< alignment_types, alignment_of< to_align >::value >::type
336 
337 template <typename T>
339 
340 template <typename T>
342 {
343  char c;
344  T t;
346 };
347 
348 template <unsigned A, unsigned S>
350 {
351  enum { value = A < S ? A : S };
352 };
353 
354 template< typename T >
355 struct alignment_of
356 {
358  sizeof( alignment_of_hack<T> ) - sizeof(T), sizeof(T) >::value, };
359 };
360 
361 template< typename List, size_t N >
363 {
364  typedef typename conditional<
365  N == sizeof( typename List::head ),
366  typename List::head,
368 };
369 
370 template< size_t N >
371 struct type_of_size< nulltype, N >
372 {
374 };
375 
376 template< typename T>
377 struct struct_t { T _; };
378 
379 #define optional_ALIGN_TYPE( type ) \
380  typelist< type , typelist< struct_t< type >
381 
382 struct Unknown;
383 
384 typedef
385  optional_ALIGN_TYPE( char ),
386  optional_ALIGN_TYPE( short ),
387  optional_ALIGN_TYPE( int ),
388  optional_ALIGN_TYPE( long ),
389  optional_ALIGN_TYPE( float ),
390  optional_ALIGN_TYPE( double ),
391  optional_ALIGN_TYPE( long double ),
392 
393  optional_ALIGN_TYPE( char *),
394  optional_ALIGN_TYPE( short * ),
395  optional_ALIGN_TYPE( int * ),
396  optional_ALIGN_TYPE( long * ),
397  optional_ALIGN_TYPE( float * ),
398  optional_ALIGN_TYPE( double * ),
399  optional_ALIGN_TYPE( long double * ),
400 
401  optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ),
402  optional_ALIGN_TYPE( Unknown * Unknown::* ),
403  optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ),
404 
405  nulltype
406  > > > > > > > > > > > > > >
407  > > > > > > > > > > > > > >
408  > > > > > >
410 
411 #undef optional_ALIGN_TYPE
412 
413 #endif // optional_CONFIG_MAX_ALIGN_HACK
414 
416 
417 template< typename T >
419 {
420 private:
421  friend class optional<T>;
422 
423  typedef T value_type;
424 
426 
427  storage_t( value_type const & v )
428  {
429  construct_value( v );
430  }
431 
432  void construct_value( value_type const & v )
433  {
434  ::new( value_ptr() ) value_type( v );
435  }
436 
437 #if optional_CPP11_OR_GREATER
438 
439  storage_t( value_type && v )
440  {
441  construct_value( std::move( v ) );
442  }
443 
444  void construct_value( value_type && v )
445  {
446  ::new( value_ptr() ) value_type( std::move( v ) );
447  }
448 
449 #endif
450 
452  {
453  value_ptr()->~T();
454  }
455 
456  value_type const * value_ptr() const
457  {
458  return as<value_type>();
459  }
460 
461  value_type * value_ptr()
462  {
463  return as<value_type>();
464  }
465 
466  value_type const & value() const optional_ref_qual
467  {
468  return * value_ptr();
469  }
470 
471  value_type & value() optional_ref_qual
472  {
473  return * value_ptr();
474  }
475 
476 #if optional_CPP11_OR_GREATER
477 
478  value_type const && value() const optional_refref_qual
479  {
480  return * value_ptr();
481  }
482 
483  value_type && value() optional_refref_qual
484  {
485  return * value_ptr();
486  }
487 
488 #endif
489 
490 #if optional_CPP11_OR_GREATER
491 
494 
495 #elif optional_CONFIG_MAX_ALIGN_HACK
496 
497  typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t;
498 
499  max_align_t hack;
500  aligned_storage_t data;
501 
502 #else
503  typedef optional_ALIGN_AS(value_type) align_as_type;
504 
505  typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t;
506  aligned_storage_t data;
507 
508 # undef optional_ALIGN_AS
509 
510 #endif // optional_CONFIG_MAX_ALIGN_HACK
511 
513  {
514  return &data;
515  }
516 
517  void const * ptr() const optional_noexcept
518  {
519  return &data;
520  }
521 
522  template <typename U>
523  U * as()
524  {
525  return reinterpret_cast<U*>( ptr() );
526  }
527 
528  template <typename U>
529  U const * as() const
530  {
531  return reinterpret_cast<U const *>( ptr() );
532  }
533 };
534 
535 } // namespace detail
536 
538 
539 struct nullopt_t
540 {
541  struct init{};
543 };
544 
545 #if optional_HAVE_CONSTEXPR_11
546 constexpr nullopt_t nullopt{ nullopt_t::init{} };
547 #else
548 // extra parenthesis to prevent the most vexing parse:
549 const nullopt_t nullopt(( nullopt_t::init() ));
550 #endif
551 
553 
554 class bad_optional_access : public std::logic_error
555 {
556 public:
558  : logic_error( "bad optional access" ) {}
559 };
560 
562 
563 template< typename T>
564 class optional
565 {
566 private:
567  typedef void (optional::*safe_bool)() const;
568 
569 public:
570  typedef T value_type;
571 
573  : has_value_( false )
574  , contained()
575  {}
576 
578  : has_value_( false )
579  , contained()
580  {}
581 
582  optional( optional const & rhs )
583  : has_value_( rhs.has_value() )
584  {
585  if ( rhs.has_value() )
586  contained.construct_value( rhs.contained.value() );
587  }
588 
589 #if optional_CPP11_OR_GREATER
590  optional_constexpr14 optional( optional && rhs ) noexcept( std::is_nothrow_move_constructible<T>::value )
591  : has_value_( rhs.has_value() )
592  {
593  if ( rhs.has_value() )
594  contained.construct_value( std::move( rhs.contained.value() ) );
595  }
596 #endif
597 
598  optional_constexpr optional( value_type const & value )
599  : has_value_( true )
600  , contained( value )
601  {}
602 
603 #if optional_CPP11_OR_GREATER
604 
605  optional_constexpr optional( value_type && value )
606  : has_value_( true )
607  , contained( std::move( value ) )
608  {}
609 
610  template< class... Args >
611  optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), Args&&... args )
612  : has_value_( true )
613  , contained( T( std::forward<Args>(args)...) )
614  {}
615 
616  template< class U, class... Args >
617  optional_constexpr explicit optional( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
618  : has_value_( true )
619  , contained( T( il, std::forward<Args>(args)...) )
620  {}
621 
622 #endif // optional_CPP11_OR_GREATER
623 
625  {
626  if ( has_value() )
627  contained.destruct_value();
628  }
629 
630  // assignment
631 
633  {
634  reset();
635  return *this;
636  }
637 
638  optional & operator=( optional const & rhs )
639 #if optional_CPP11_OR_GREATER
640  noexcept( std::is_nothrow_move_assignable<T>::value && std::is_nothrow_move_constructible<T>::value )
641 #endif
642  {
643  if ( has_value() == true && rhs.has_value() == false ) reset();
644  else if ( has_value() == false && rhs.has_value() == true ) initialize( *rhs );
645  else if ( has_value() == true && rhs.has_value() == true ) contained.value() = *rhs;
646  return *this;
647  }
648 
649 #if optional_CPP11_OR_GREATER
650 
651  optional & operator=( optional && rhs ) noexcept
652  {
653  if ( has_value() == true && rhs.has_value() == false ) reset();
654  else if ( has_value() == false && rhs.has_value() == true ) initialize( std::move( *rhs ) );
655  else if ( has_value() == true && rhs.has_value() == true ) contained.value() = std::move( *rhs );
656  return *this;
657  }
658 
659  template< class U,
661  optional & operator=( U && v )
662  {
663  if ( has_value() ) contained.value() = std::forward<U>( v );
664  else initialize( T( std::forward<U>( v ) ) );
665  return *this;
666  }
667 
668  template< class... Args >
669  void emplace( Args&&... args )
670  {
671  *this = nullopt;
672  initialize( T( std::forward<Args>(args)...) );
673  }
674 
675  template< class U, class... Args >
676  void emplace( std::initializer_list<U> il, Args&&... args )
677  {
678  *this = nullopt;
679  initialize( T( il, std::forward<Args>(args)...) );
680  }
681 
682 #endif // optional_CPP11_OR_GREATER
683 
684  // swap
685 
686  void swap( optional & rhs )
687 #if optional_CPP11_OR_GREATER
688  noexcept( std::is_nothrow_move_constructible<T>::value && noexcept( std::swap( std::declval<T&>(), std::declval<T&>() ) ) )
689 #endif
690  {
691  using std::swap;
692  if ( has_value() == true && rhs.has_value() == true ) { swap( **this, *rhs ); }
693  else if ( has_value() == false && rhs.has_value() == true ) { initialize( *rhs ); rhs.reset(); }
694  else if ( has_value() == true && rhs.has_value() == false ) { rhs.initialize( **this ); reset(); }
695  }
696 
697  // observers
698 
699  optional_constexpr value_type const * operator ->() const
700  {
701  return assert( has_value() ),
702  contained.value_ptr();
703  }
704 
705  optional_constexpr14 value_type * operator ->()
706  {
707  return assert( has_value() ),
708  contained.value_ptr();
709  }
710 
711  optional_constexpr value_type const & operator *() const optional_ref_qual
712  {
713  return assert( has_value() ),
714  contained.value();
715  }
716 
717  optional_constexpr14 value_type & operator *() optional_ref_qual
718  {
719  return assert( has_value() ),
720  contained.value();
721  }
722 
723 #if optional_CPP11_OR_GREATER
724 
725  optional_constexpr value_type const && operator *() const optional_refref_qual
726  {
727  return std::move( contained.value() );
728  }
729 
730  optional_constexpr14 value_type && operator *() optional_refref_qual
731  {
732  assert( has_value() );
733  return std::move( contained.value() );
734  }
735 
736 #endif
737 
738 #if optional_CPP11_OR_GREATER
739  optional_constexpr explicit operator bool() const optional_noexcept
740  {
741  return has_value();
742  }
743 #else
744  optional_constexpr operator safe_bool() const optional_noexcept
745  {
746  return has_value() ? &optional::this_type_does_not_support_comparisons : 0;
747  }
748 #endif
749 
751  {
752  return has_value_;
753  }
754 
755  optional_constexpr14 value_type const & value() const optional_ref_qual
756  {
757  if ( ! has_value() )
758  throw bad_optional_access();
759 
760  return contained.value();
761  }
762 
764  {
765  if ( ! has_value() )
766  throw bad_optional_access();
767 
768  return contained.value();
769  }
770 
771 #if optional_HAVE_REF_QUALIFIER
772 
773  optional_constexpr14 value_type const && value() const optional_refref_qual
774  {
775  if ( ! has_value() )
776  throw bad_optional_access();
777 
778  return std::move( contained.value() );
779  }
780 
782  {
783  if ( ! has_value() )
784  throw bad_optional_access();
785 
786  return std::move( contained.value() );
787  }
788 
789 #endif
790 
791 #if optional_CPP11_OR_GREATER
792 
793  template< class U >
794  optional_constexpr value_type value_or( U && v ) const optional_ref_qual
795  {
796  return has_value() ? contained.value() : static_cast<T>(std::forward<U>( v ) );
797  }
798 
799  template< class U >
800  optional_constexpr value_type value_or( U && v ) const optional_refref_qual
801  {
802  return has_value() ? std::move( contained.value() ) : static_cast<T>(std::forward<U>( v ) );
803  }
804 
805 #else
806 
807  template< class U >
808  optional_constexpr value_type value_or( U const & v ) const
809  {
810  return has_value() ? contained.value() : static_cast<value_type>( v );
811  }
812 
813 #endif // optional_CPP11_OR_GREATER
814 
815  // modifiers
816 
818  {
819  if ( has_value() )
820  contained.destruct_value();
821 
822  has_value_ = false;
823  }
824 
825 private:
827 
828  template< typename V >
829  void initialize( V const & value )
830  {
831  assert( ! has_value() );
832  contained.construct_value( value );
833  has_value_ = true;
834  }
835 
836 #if optional_CPP11_OR_GREATER
837  template< typename V >
838  void initialize( V && value )
839  {
840  assert( ! has_value() );
841  contained.construct_value( std::move( value ) );
842  has_value_ = true;
843  }
844 #endif
845 
846 private:
849 
850 };
851 
852 // Relational operators
853 
854 template< typename T > bool operator==( optional<T> const & x, optional<T> const & y )
855 {
856  return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
857 }
858 
859 template< typename T > bool operator!=( optional<T> const & x, optional<T> const & y )
860 {
861  return !(x == y);
862 }
863 
864 template< typename T > bool operator<( optional<T> const & x, optional<T> const & y )
865 {
866  return (!y) ? false : (!x) ? true : *x < *y;
867 }
868 
869 template< typename T > bool operator>( optional<T> const & x, optional<T> const & y )
870 {
871  return (y < x);
872 }
873 
874 template< typename T > bool operator<=( optional<T> const & x, optional<T> const & y )
875 {
876  return !(y < x);
877 }
878 
879 template< typename T > bool operator>=( optional<T> const & x, optional<T> const & y )
880 {
881  return !(x < y);
882 }
883 
884 // Comparison with nullopt
885 
886 template< typename T > bool operator==( optional<T> const & x, nullopt_t ) optional_noexcept
887 {
888  return (!x);
889 }
890 
891 template< typename T > bool operator==( nullopt_t, optional<T> const & x ) optional_noexcept
892 {
893  return (!x);
894 }
895 
896 template< typename T > bool operator!=( optional<T> const & x, nullopt_t ) optional_noexcept
897 {
898  return bool(x);
899 }
900 
901 template< typename T > bool operator!=( nullopt_t, optional<T> const & x ) optional_noexcept
902 {
903  return bool(x);
904 }
905 
906 template< typename T > bool operator<( optional<T> const &, nullopt_t ) optional_noexcept
907 {
908  return false;
909 }
910 
911 template< typename T > bool operator<( nullopt_t, optional<T> const & x ) optional_noexcept
912 {
913  return bool(x);
914 }
915 
916 template< typename T > bool operator<=( optional<T> const & x, nullopt_t ) optional_noexcept
917 {
918  return (!x);
919 }
920 
921 template< typename T > bool operator<=( nullopt_t, optional<T> const & ) optional_noexcept
922 {
923  return true;
924 }
925 
926 template< typename T > bool operator>( optional<T> const & x, nullopt_t ) optional_noexcept
927 {
928  return bool(x);
929 }
930 
931 template< typename T > bool operator>( nullopt_t, optional<T> const & ) optional_noexcept
932 {
933  return false;
934 }
935 
936 template< typename T > bool operator>=( optional<T> const &, nullopt_t )
937 {
938  return true;
939 }
940 
941 template< typename T > bool operator>=( nullopt_t, optional<T> const & x )
942 {
943  return (!x);
944 }
945 
946 // Comparison with T
947 
948 template< typename T > bool operator==( optional<T> const & x, const T& v )
949 {
950  return bool(x) ? *x == v : false;
951 }
952 
953 template< typename T > bool operator==( T const & v, optional<T> const & x )
954 {
955  return bool(x) ? v == *x : false;
956 }
957 
958 template< typename T > bool operator!=( optional<T> const & x, const T& v )
959 {
960  return bool(x) ? *x != v : true;
961 }
962 
963 template< typename T > bool operator!=( T const & v, optional<T> const & x )
964 {
965  return bool(x) ? v != *x : true;
966 }
967 
968 template< typename T > bool operator<( optional<T> const & x, const T& v )
969 {
970  return bool(x) ? *x < v : true;
971 }
972 
973 template< typename T > bool operator<( T const & v, optional<T> const & x )
974 {
975  return bool(x) ? v < *x : false;
976 }
977 
978 template< typename T > bool operator<=( optional<T> const & x, const T& v )
979 {
980  return bool(x) ? *x <= v : true;
981 }
982 
983 template< typename T > bool operator<=( T const & v, optional<T> const & x )
984 {
985  return bool(x) ? v <= *x : false;
986 }
987 
988 template< typename T > bool operator>( optional<T> const & x, const T& v )
989 {
990  return bool(x) ? *x > v : false;
991 }
992 
993 template< typename T > bool operator>( T const & v, optional<T> const & x )
994 {
995  return bool(x) ? v > *x : true;
996 }
997 
998 template< typename T > bool operator>=( optional<T> const & x, const T& v )
999 {
1000  return bool(x) ? *x >= v : false;
1001 }
1002 
1003 template< typename T > bool operator>=( T const & v, optional<T> const & x )
1004 {
1005  return bool(x) ? v >= *x : true;
1006 }
1007 
1008 // Specialized algorithms
1009 
1010 template< typename T >
1011 void swap( optional<T> & x, optional<T> & y )
1012 #if optional_CPP11_OR_GREATER
1013  noexcept( noexcept( x.swap(y) ) )
1014 #endif
1015 {
1016  x.swap( y );
1017 }
1018 
1019 #if optional_CPP11_OR_GREATER
1020 
1021 template< class T >
1023 {
1024  return optional< typename std::decay<T>::type >( std::forward<T>( v ) );
1025 }
1026 
1027 template< class T, class...Args >
1029 {
1030  return optional<T>( in_place, std::forward<Args>(args)...);
1031 }
1032 
1033 template< class T, class U, class... Args >
1034 optional_constexpr optional<T> make_optional( std::initializer_list<U> il, Args&&... args )
1035 {
1036  return optional<T>( in_place, il, std::forward<Args>(args)...);
1037 }
1038 
1039 #else
1040 
1041 template< typename T >
1043 {
1044  return optional<T>( v );
1045 }
1046 
1047 #endif // optional_CPP11_OR_GREATER
1048 
1049 } // namespace optional
1050 
1051 using namespace optional_lite;
1052 
1053 } // namespace nonstd
1054 
1055 #if optional_CPP11_OR_GREATER
1056 
1057 // specialize the std::hash algorithm:
1058 
1059 namespace std {
1060 
1061 template< class T >
1062 class hash< nonstd::optional<T> >
1063 {
1064 public:
1065  std::size_t operator()( nonstd::optional<T> const & v ) const optional_noexcept
1066  {
1067  return bool( v ) ? hash<T>()( *v ) : 0;
1068  }
1069 };
1070 
1071 } //namespace std
1072 
1073 #endif // optional_CPP11_OR_GREATER
1074 
1075 #endif // NONSTD_OPTIONAL_LITE_HPP
int v
bool operator>=(T const &v, optional< T > const &x)
Definition: optional.hpp:1003
conditional< N==sizeof(typename List::head), typename List::head, typename type_of_size< typename List::tail, N >::type >::type type
Definition: optional.hpp:367
void swap(optional &rhs)
Definition: optional.hpp:686
#define optional_noexcept
Definition: optional.hpp:157
#define optional_ref_qual
Definition: optional.hpp:170
typename std::aligned_storage< Len, Align >::type aligned_storage_t
ROSCONSOLE_DECL void initialize()
void swap(optional< T > &x, optional< T > &y)
Definition: optional.hpp:1011
bool())
optional_constexpr14 value_type & value() optional_ref_qual
Definition: optional.hpp:763
bool operator==(T const &v, optional< T > const &x)
Definition: optional.hpp:953
void this_type_does_not_support_comparisons() const
Definition: optional.hpp:826
optional_constexpr14 value_type const & value() const optional_ref_qual
Definition: optional.hpp:755
Unknown
void reset() optional_noexcept
Definition: optional.hpp:817
optional< T > make_optional(T const &v)
Definition: optional.hpp:1042
bool operator>(T const &v, optional< T > const &x)
Definition: optional.hpp:993
TFSIMD_FORCE_INLINE const tfScalar & y() const
optional_constexpr nullopt_t(init)
Definition: optional.hpp:542
void const * ptr() const optional_noexcept
Definition: optional.hpp:517
optional & operator=(nullopt_t) optional_noexcept
Definition: optional.hpp:632
optional_constexpr optional(value_type const &value)
Definition: optional.hpp:598
void initialize(V const &value)
Definition: optional.hpp:829
void construct_value(value_type const &v)
Definition: optional.hpp:432
optional(optional const &rhs)
Definition: optional.hpp:582
#define nonstd_lite_in_place_type_t(T)
Definition: optional.hpp:220
value_type const * value_ptr() const
Definition: optional.hpp:456
detail::storage_t< value_type > contained
Definition: optional.hpp:848
disengaged state tag
Definition: optional.hpp:539
T value
#define optional_CONFIG_ALIGN_AS_FALLBACK
Definition: optional.hpp:38
value_type & value() optional_ref_qual
Definition: optional.hpp:471
char * ptr
#define optional_refref_qual
Definition: optional.hpp:171
optional_constexpr value_type value_or(U const &v) const
Definition: optional.hpp:808
hash_default_hash< typename T::first_type > hash
Definition: any.hpp:144
TFSIMD_FORCE_INLINE const tfScalar & x() const
value_type const & value() const optional_ref_qual
Definition: optional.hpp:466
void * ptr() optional_noexcept
Definition: optional.hpp:512
optional_constexpr optional(nullopt_t) optional_noexcept
Definition: optional.hpp:577
optional_constexpr optional() optional_noexcept
Definition: optional.hpp:572
#define optional_ALIGN_TYPE(type)
Definition: optional.hpp:379
#define optional_constexpr14
Definition: optional.hpp:151
optional & operator=(optional const &rhs)
Definition: optional.hpp:638
bool operator!=(T const &v, optional< T > const &x)
Definition: optional.hpp:963
empty_struct data[sizeof(T)/sizeof(empty_struct)]
C++03 constructed union to hold value.
Definition: optional.hpp:418
#define optional_ALIGN_AS(to_align)
Definition: optional.hpp:334
const nullopt_t nullopt((nullopt_t::init()))
#define optional_constexpr
Definition: optional.hpp:145
in_place_t in_place(detail::in_place_type_tag< T >=detail::in_place_type_tag< T >())
Definition: any.hpp:159
optional_constexpr bool has_value() const optional_noexcept
Definition: optional.hpp:750


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17