File indexing completed on 2025-09-18 08:53:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
0018 #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
0019
0020 #include <new>
0021 #ifndef BOOST_NO_IOSTREAM
0022 #include <iosfwd>
0023 #endif
0024
0025 #include <boost/assert.hpp>
0026 #include <boost/core/addressof.hpp>
0027 #include <boost/core/enable_if.hpp>
0028 #include <boost/core/invoke_swap.hpp>
0029 #include <boost/core/launder.hpp>
0030 #include <boost/optional/bad_optional_access.hpp>
0031 #include <boost/throw_exception.hpp>
0032 #include <boost/type_traits/alignment_of.hpp>
0033 #include <boost/type_traits/conditional.hpp>
0034 #include <boost/type_traits/conjunction.hpp>
0035 #include <boost/type_traits/disjunction.hpp>
0036 #include <boost/type_traits/has_nothrow_constructor.hpp>
0037 #include <boost/type_traits/type_with_alignment.hpp>
0038 #include <boost/type_traits/remove_const.hpp>
0039 #include <boost/type_traits/remove_reference.hpp>
0040 #include <boost/type_traits/decay.hpp>
0041 #include <boost/type_traits/is_assignable.hpp>
0042 #include <boost/type_traits/is_base_of.hpp>
0043 #include <boost/type_traits/is_const.hpp>
0044 #include <boost/type_traits/is_constructible.hpp>
0045 #include <boost/type_traits/is_convertible.hpp>
0046 #include <boost/type_traits/is_lvalue_reference.hpp>
0047 #include <boost/type_traits/is_nothrow_move_assignable.hpp>
0048 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0049 #include <boost/type_traits/is_rvalue_reference.hpp>
0050 #include <boost/type_traits/is_same.hpp>
0051 #include <boost/type_traits/is_volatile.hpp>
0052 #include <boost/type_traits/is_scalar.hpp>
0053 #include <boost/none.hpp>
0054
0055 #include <boost/optional/optional_fwd.hpp>
0056 #include <boost/optional/detail/optional_config.hpp>
0057 #include <boost/optional/detail/optional_factory_support.hpp>
0058 #include <boost/optional/detail/optional_aligned_storage.hpp>
0059 #include <boost/optional/detail/optional_hash.hpp>
0060 #include <boost/optional/detail/optional_utility.hpp>
0061
0062 namespace boost { namespace optional_detail {
0063
0064 template <typename T>
0065 struct optional_value_type
0066 {
0067 };
0068
0069 template <typename U>
0070 struct optional_value_type< ::boost::optional<U> >
0071 {
0072 typedef U type;
0073 };
0074
0075 template <typename T>
0076 T declval();
0077
0078
0079
0080
0081 template <typename F, typename Ref, typename Rslt = decltype(declval<F>()(declval<Ref>()))>
0082 struct result_of
0083 {
0084 typedef Rslt type;
0085 };
0086
0087 template <typename F, typename Ref, typename Rslt = typename optional_value_type<typename result_of<F, Ref>::type>::type>
0088 struct result_value_type
0089 {
0090 typedef Rslt type;
0091 };
0092
0093
0094
0095 }}
0096
0097 namespace boost {
0098
0099 namespace optional_ns {
0100
0101
0102 struct in_place_init_t
0103 {
0104 struct init_tag{};
0105 BOOST_CONSTEXPR explicit in_place_init_t(init_tag){}
0106 };
0107 BOOST_INLINE_CONSTEXPR in_place_init_t in_place_init ((in_place_init_t::init_tag()));
0108
0109
0110 struct in_place_init_if_t
0111 {
0112 struct init_tag{};
0113 BOOST_CONSTEXPR explicit in_place_init_if_t(init_tag){}
0114 };
0115 BOOST_INLINE_CONSTEXPR in_place_init_if_t in_place_init_if ((in_place_init_if_t::init_tag()));
0116
0117 }
0118
0119 using optional_ns::in_place_init_t;
0120 using optional_ns::in_place_init;
0121 using optional_ns::in_place_init_if_t;
0122 using optional_ns::in_place_init_if;
0123
0124 namespace optional_detail {
0125
0126 struct init_value_tag {};
0127
0128 struct optional_tag {};
0129
0130
0131 template<class T>
0132 class optional_base : public optional_tag
0133 {
0134 private :
0135
0136 typedef aligned_storage<T> storage_type ;
0137 typedef optional_base<T> this_type ;
0138
0139 protected :
0140
0141 typedef T value_type ;
0142 typedef typename boost::remove_const<T>::type unqualified_value_type;
0143
0144 protected:
0145 typedef T & reference_type ;
0146 typedef T const& reference_const_type ;
0147 typedef T && rval_reference_type ;
0148 typedef T && reference_type_of_temporary_wrapper ;
0149 typedef T * pointer_type ;
0150 typedef T const* pointer_const_type ;
0151 typedef T const& argument_type ;
0152
0153
0154
0155 optional_base()
0156 :
0157 m_initialized(false) {}
0158
0159
0160
0161 optional_base ( none_t )
0162 :
0163 m_initialized(false) {}
0164
0165
0166
0167 optional_base ( init_value_tag, argument_type val )
0168 :
0169 m_initialized(false)
0170 {
0171 construct(val);
0172 }
0173
0174
0175
0176 optional_base ( init_value_tag, rval_reference_type val )
0177 :
0178 m_initialized(false)
0179 {
0180 construct( optional_detail::move(val) );
0181 }
0182
0183
0184
0185 optional_base ( bool cond, argument_type val )
0186 :
0187 m_initialized(false)
0188 {
0189 if ( cond )
0190 construct(val);
0191 }
0192
0193
0194
0195 optional_base ( bool cond, rval_reference_type val )
0196 :
0197 m_initialized(false)
0198 {
0199 if ( cond )
0200 construct(optional_detail::move(val));
0201 }
0202
0203
0204
0205 optional_base ( optional_base const& rhs )
0206 :
0207 m_initialized(false)
0208 {
0209 if ( rhs.is_initialized() )
0210 construct(rhs.get_impl());
0211 }
0212
0213
0214
0215 optional_base ( optional_base&& rhs )
0216 BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
0217 :
0218 m_initialized(false)
0219 {
0220 if ( rhs.is_initialized() )
0221 construct( optional_detail::move(rhs.get_impl()) );
0222 }
0223
0224
0225 template<class Expr, class PtrExpr>
0226 explicit optional_base ( Expr&& expr, PtrExpr const* tag )
0227 :
0228 m_initialized(false)
0229 {
0230 construct(optional_detail::forward<Expr>(expr),tag);
0231 }
0232
0233 optional_base& operator= ( optional_base const& rhs )
0234 {
0235 this->assign(rhs);
0236 return *this;
0237 }
0238
0239 optional_base& operator= ( optional_base && rhs )
0240 BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
0241 {
0242 this->assign(static_cast<optional_base&&>(rhs));
0243 return *this;
0244 }
0245
0246
0247 ~optional_base() { destroy() ; }
0248
0249
0250 void assign ( optional_base const& rhs )
0251 {
0252 if (is_initialized())
0253 {
0254 if ( rhs.is_initialized() )
0255 assign_value(rhs.get_impl());
0256 else destroy();
0257 }
0258 else
0259 {
0260 if ( rhs.is_initialized() )
0261 construct(rhs.get_impl());
0262 }
0263 }
0264
0265
0266 void assign ( optional_base&& rhs )
0267 {
0268 if (is_initialized())
0269 {
0270 if ( rhs.is_initialized() )
0271 assign_value( optional_detail::move(rhs.get_impl()) );
0272 else destroy();
0273 }
0274 else
0275 {
0276 if ( rhs.is_initialized() )
0277 construct(optional_detail::move(rhs.get_impl()));
0278 }
0279 }
0280
0281
0282 template<class U>
0283 void assign ( optional<U> const& rhs )
0284 {
0285 if (is_initialized())
0286 {
0287 if ( rhs.is_initialized() )
0288 #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
0289 assign_value( rhs.get() );
0290 #else
0291 assign_value( static_cast<value_type>(rhs.get()) );
0292 #endif
0293
0294 else destroy();
0295 }
0296 else
0297 {
0298 if ( rhs.is_initialized() )
0299 #ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
0300 construct(rhs.get());
0301 #else
0302 construct(static_cast<value_type>(rhs.get()));
0303 #endif
0304 }
0305 }
0306
0307
0308 template<class U>
0309 void assign ( optional<U>&& rhs )
0310 {
0311 typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
0312 if (is_initialized())
0313 {
0314 if ( rhs.is_initialized() )
0315 assign_value( static_cast<ref_type>(rhs.get()) );
0316 else destroy();
0317 }
0318 else
0319 {
0320 if ( rhs.is_initialized() )
0321 construct(static_cast<ref_type>(rhs.get()));
0322 }
0323 }
0324
0325
0326 void assign ( argument_type val )
0327 {
0328 if (is_initialized())
0329 assign_value(val);
0330 else construct(val);
0331 }
0332
0333
0334 void assign ( rval_reference_type val )
0335 {
0336 if (is_initialized())
0337 assign_value( optional_detail::move(val) );
0338 else construct( optional_detail::move(val) );
0339 }
0340
0341
0342
0343 void assign ( none_t ) BOOST_NOEXCEPT { destroy(); }
0344
0345 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0346
0347 template<class Expr, class ExprPtr>
0348 void assign_expr ( Expr&& expr, ExprPtr const* tag )
0349 {
0350 if (is_initialized())
0351 assign_expr_to_initialized(optional_detail::forward<Expr>(expr),tag);
0352 else construct(optional_detail::forward<Expr>(expr),tag);
0353 }
0354
0355 #endif
0356
0357 public :
0358
0359
0360
0361 void reset() BOOST_NOEXCEPT { destroy(); }
0362
0363
0364 void reset ( argument_type val ) { assign(val); }
0365
0366
0367
0368
0369 pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
0370 pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0 ; }
0371
0372 bool is_initialized() const BOOST_NOEXCEPT { return m_initialized ; }
0373
0374 protected :
0375
0376 void construct ( argument_type val )
0377 {
0378 ::new (m_storage.address()) unqualified_value_type(val) ;
0379 m_initialized = true ;
0380 }
0381
0382 void construct ( rval_reference_type val )
0383 {
0384 ::new (m_storage.address()) unqualified_value_type( optional_detail::move(val) ) ;
0385 m_initialized = true ;
0386 }
0387
0388
0389
0390
0391 template<class... Args>
0392 void construct ( in_place_init_t, Args&&... args )
0393 {
0394 ::new (m_storage.address()) unqualified_value_type( optional_detail::forward<Args>(args)... ) ;
0395 m_initialized = true ;
0396 }
0397
0398 template<class... Args>
0399 void emplace_assign ( Args&&... args )
0400 {
0401 destroy();
0402 construct(in_place_init, optional_detail::forward<Args>(args)...);
0403 }
0404
0405 template<class... Args>
0406 explicit optional_base ( in_place_init_t, Args&&... args )
0407 :
0408 m_initialized(false)
0409 {
0410 construct(in_place_init, optional_detail::forward<Args>(args)...);
0411 }
0412
0413 template<class... Args>
0414 explicit optional_base ( in_place_init_if_t, bool cond, Args&&... args )
0415 :
0416 m_initialized(false)
0417 {
0418 if ( cond )
0419 construct(in_place_init, optional_detail::forward<Args>(args)...);
0420 }
0421
0422 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0423
0424
0425 template<class Expr>
0426 void construct ( Expr&& factory, in_place_factory_base const* )
0427 {
0428 boost_optional_detail::construct<value_type>(factory, m_storage.address());
0429 m_initialized = true ;
0430 }
0431
0432
0433 template<class Expr>
0434 void construct ( Expr&& factory, typed_in_place_factory_base const* )
0435 {
0436 factory.apply(m_storage.address()) ;
0437 m_initialized = true ;
0438 }
0439
0440 template<class Expr>
0441 void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
0442 {
0443 destroy();
0444 construct(factory,tag);
0445 }
0446
0447
0448 template<class Expr>
0449 void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
0450 {
0451 destroy();
0452 construct(factory,tag);
0453 }
0454
0455 #endif
0456
0457
0458
0459
0460
0461 template<class Expr>
0462 void construct ( Expr&& expr, void const* )
0463 {
0464 new (m_storage.address()) unqualified_value_type(optional_detail::forward<Expr>(expr)) ;
0465 m_initialized = true ;
0466 }
0467
0468
0469
0470
0471
0472 template<class Expr>
0473 void assign_expr_to_initialized ( Expr&& expr, void const* )
0474 {
0475 assign_value( optional_detail::forward<Expr>(expr) );
0476 }
0477
0478 #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 template<class Expr>
0494 void construct ( Expr&& expr, optional_tag const* )
0495 {
0496 if ( expr.is_initialized() )
0497 {
0498
0499
0500 new (m_storage.address()) unqualified_value_type(optional_detail::move(expr.get())) ;
0501 m_initialized = true ;
0502 }
0503 }
0504 #endif
0505
0506 void assign_value ( argument_type val ) { get_impl() = val; }
0507 void assign_value ( rval_reference_type val ) { get_impl() = static_cast<rval_reference_type>(val); }
0508
0509 void destroy()
0510 {
0511 if ( m_initialized )
0512 destroy_impl() ;
0513 }
0514
0515 reference_const_type get_impl() const { return m_storage.ref() ; }
0516 reference_type get_impl() { return m_storage.ref() ; }
0517
0518 pointer_const_type get_ptr_impl() const { return m_storage.ptr_ref(); }
0519 pointer_type get_ptr_impl() { return m_storage.ptr_ref(); }
0520
0521 private :
0522
0523 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))
0524 void destroy_impl ( ) { m_storage.ptr_ref()->~T() ; m_initialized = false ; }
0525 #else
0526 void destroy_impl ( ) { m_storage.ref().T::~T() ; m_initialized = false ; }
0527 #endif
0528
0529 bool m_initialized ;
0530 storage_type m_storage ;
0531 } ;
0532
0533 #include <boost/optional/detail/optional_trivially_copyable_base.hpp>
0534
0535
0536 template <typename U>
0537 struct is_optional_or_tag
0538 : boost::conditional< boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>::value
0539 || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, none_t>::value
0540 || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_t>::value
0541 || boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<U>::type, in_place_init_if_t>::value,
0542 boost::true_type, boost::false_type>::type
0543 {};
0544
0545 template <typename T, typename U>
0546 struct has_dedicated_constructor
0547 : boost::disjunction<is_optional_or_tag<U>, boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<U>::type> >
0548 {};
0549
0550 template <typename U>
0551 struct is_in_place_factory
0552 : boost::disjunction< boost::is_base_of<boost::in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type>,
0553 boost::is_base_of<boost::typed_in_place_factory_base, BOOST_DEDUCED_TYPENAME boost::decay<U>::type> >
0554 {};
0555
0556 #if !defined(BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT)
0557
0558 template <typename T, typename U>
0559 struct is_factory_or_constructible_to_T
0560 : boost::disjunction< is_in_place_factory<U>, boost::is_constructible<T, U&&> >
0561 {};
0562
0563 template <typename T, typename U>
0564 struct is_optional_constructible : boost::is_constructible<T, U>
0565 {};
0566
0567 #else
0568
0569 template <typename, typename>
0570 struct is_factory_or_constructible_to_T : boost::true_type
0571 {};
0572
0573 template <typename T, typename U>
0574 struct is_optional_constructible : boost::true_type
0575 {};
0576
0577 #endif
0578
0579 #if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
0580
0581
0582
0583
0584
0585 template <typename T, typename U>
0586 struct is_opt_assignable
0587 : boost::conjunction<boost::is_convertible<U&&, T>, boost::is_assignable<T&, U&&> >
0588 {};
0589
0590 #else
0591
0592 template <typename T, typename U>
0593 struct is_opt_assignable : boost::is_convertible<U, T>
0594 {};
0595
0596 #endif
0597
0598 template <typename T, typename U>
0599 struct is_factory_or_opt_assignable_to_T
0600 : boost::disjunction< is_in_place_factory<U>, is_opt_assignable<T, U> >
0601 {};
0602
0603 template <typename T, typename U, bool = has_dedicated_constructor<T, U>::value>
0604 struct is_optional_val_init_candidate
0605 : boost::false_type
0606 {};
0607
0608 template <typename T, typename U>
0609 struct is_optional_val_init_candidate<T, U, false>
0610 : is_factory_or_constructible_to_T<T, U>
0611 {};
0612
0613 template <typename T, typename U, bool = has_dedicated_constructor<T, U>::value>
0614 struct is_optional_val_assign_candidate
0615 : boost::false_type
0616 {};
0617
0618 template <typename T, typename U>
0619 struct is_optional_val_assign_candidate<T, U, false>
0620 : is_factory_or_opt_assignable_to_T<T, U>
0621 {};
0622
0623 }
0624
0625 namespace optional_config {
0626
0627 template <typename T>
0628 struct optional_uses_direct_storage_for
0629 : boost::conditional<(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
0630 , boost::true_type, boost::false_type>::type
0631 {};
0632
0633 }
0634
0635
0636 #ifndef BOOST_OPTIONAL_DETAIL_NO_DIRECT_STORAGE_SPEC
0637 # define BOOST_OPTIONAL_BASE_TYPE(T) boost::conditional< optional_config::optional_uses_direct_storage_for<T>::value, \
0638 optional_detail::tc_optional_base<T>, \
0639 optional_detail::optional_base<T> \
0640 >::type
0641 #else
0642 # define BOOST_OPTIONAL_BASE_TYPE(T) optional_detail::optional_base<T>
0643 #endif
0644
0645 template<class T>
0646 class optional
0647 : public BOOST_OPTIONAL_BASE_TYPE(T)
0648 {
0649 typedef typename BOOST_OPTIONAL_BASE_TYPE(T) base ;
0650
0651 public :
0652
0653 typedef optional<T> this_type ;
0654
0655 typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
0656 typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
0657 typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
0658 typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ;
0659 typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
0660 typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
0661 typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
0662 typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
0663
0664
0665
0666 optional() BOOST_NOEXCEPT : base() {}
0667
0668
0669
0670 optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
0671
0672
0673
0674 optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
0675
0676
0677
0678 optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), optional_detail::forward<T>(val))
0679 {}
0680
0681
0682
0683 optional ( bool cond, argument_type val ) : base(cond,val) {}
0684
0685
0686
0687 optional ( bool cond, rval_reference_type val ) : base( cond, optional_detail::forward<T>(val) )
0688 {}
0689
0690
0691
0692
0693
0694
0695 template<class U>
0696 explicit optional ( optional<U> const& rhs
0697 #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
0698 ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U const&>, bool>::type = true
0699 #endif
0700 )
0701 :
0702 base()
0703 {
0704 if ( rhs.is_initialized() )
0705 this->construct(rhs.get());
0706 }
0707
0708
0709
0710
0711 template<class U>
0712 explicit optional ( optional<U> && rhs
0713 #ifndef BOOST_OPTIONAL_DETAIL_NO_SFINAE_FRIENDLY_CONSTRUCTORS
0714 ,BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_constructible<T, U>, bool>::type = true
0715 #endif
0716 )
0717 :
0718 base()
0719 {
0720 if ( rhs.is_initialized() )
0721 this->construct( optional_detail::move(rhs.get()) );
0722 }
0723
0724 #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736 template<class Expr>
0737 explicit optional ( Expr&& expr,
0738 BOOST_DEDUCED_TYPENAME boost::enable_if< optional_detail::is_optional_val_init_candidate<T, Expr>, bool>::type = true
0739 )
0740 : base(optional_detail::forward<Expr>(expr),boost::addressof(expr))
0741 {}
0742
0743 #endif
0744
0745
0746
0747 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
0748 optional ( optional const& ) = default;
0749 #else
0750 optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
0751 #endif
0752
0753
0754
0755 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
0756 optional ( optional && ) = default;
0757 #else
0758 optional ( optional && rhs )
0759 BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
0760 : base( optional_detail::move(rhs) )
0761 {}
0762 #endif
0763
0764
0765 #if BOOST_WORKAROUND(_MSC_VER, <= 1600)
0766
0767 ~optional() {}
0768 #endif
0769
0770
0771 #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
0772
0773
0774
0775 template<class Expr>
0776 BOOST_DEDUCED_TYPENAME boost::enable_if<optional_detail::is_optional_val_assign_candidate<T, Expr>, optional&>::type
0777 operator= ( Expr&& expr )
0778 {
0779 this->assign_expr(optional_detail::forward<Expr>(expr),boost::addressof(expr));
0780 return *this ;
0781 }
0782
0783 #endif
0784
0785
0786
0787
0788 template<class U>
0789 optional& operator= ( optional<U> const& rhs )
0790 {
0791 this->assign(rhs);
0792 return *this ;
0793 }
0794
0795
0796
0797
0798 template<class U>
0799 optional& operator= ( optional<U> && rhs )
0800 {
0801 this->assign(optional_detail::move(rhs));
0802 return *this ;
0803 }
0804
0805
0806
0807
0808 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
0809 optional& operator= ( optional const& rhs ) = default;
0810 #else
0811 optional& operator= ( optional const& rhs )
0812 {
0813 this->assign( static_cast<base const&>(rhs) ) ;
0814 return *this ;
0815 }
0816 #endif
0817
0818
0819 #ifndef BOOST_OPTIONAL_DETAIL_NO_DEFAULTED_MOVE_FUNCTIONS
0820 optional& operator= ( optional && ) = default;
0821 #else
0822 optional& operator= ( optional && rhs )
0823 BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
0824 {
0825 this->assign( static_cast<base &&>(rhs) ) ;
0826 return *this ;
0827 }
0828 #endif
0829
0830 #ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
0831
0832
0833 template <typename T_>
0834 BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_same<T, BOOST_DEDUCED_TYPENAME boost::decay<T_>::type>, optional&>::type
0835 operator= ( T_&& val )
0836 {
0837 this->assign( optional_detail::forward<T_>(val) ) ;
0838 return *this ;
0839 }
0840
0841 #else
0842
0843
0844
0845 optional& operator= ( argument_type val )
0846 {
0847 this->assign( val ) ;
0848 return *this ;
0849 }
0850
0851
0852 optional& operator= ( rval_reference_type val )
0853 {
0854 this->assign( optional_detail::move(val) ) ;
0855 return *this ;
0856 }
0857
0858 #endif
0859
0860
0861
0862
0863 optional& operator= ( none_t none_ ) BOOST_NOEXCEPT
0864 {
0865 this->assign( none_ ) ;
0866 return *this ;
0867 }
0868
0869
0870
0871 template<class... Args>
0872 void emplace ( Args&&... args )
0873 {
0874 this->emplace_assign( optional_detail::forward<Args>(args)... );
0875 }
0876
0877 template<class... Args>
0878 explicit optional ( in_place_init_t, Args&&... args )
0879 : base( in_place_init, optional_detail::forward<Args>(args)... )
0880 {}
0881
0882 template<class... Args>
0883 explicit optional ( in_place_init_if_t, bool cond, Args&&... args )
0884 : base( in_place_init_if, cond, optional_detail::forward<Args>(args)... )
0885 {}
0886
0887 void swap( optional & arg )
0888 BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
0889 {
0890
0891 boost::core::invoke_swap(*this, arg);
0892 }
0893
0894
0895
0896
0897
0898 reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
0899 reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
0900
0901
0902 reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
0903 reference_type get_value_or ( reference_type v ) { return this->is_initialized() ? get() : v ; }
0904
0905
0906
0907
0908 pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
0909 pointer_type operator->() { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
0910
0911
0912
0913
0914 reference_const_type operator *() BOOST_OPTIONAL_CONST_REF_QUAL { return this->get() ; }
0915 reference_type operator *() BOOST_OPTIONAL_REF_QUAL { return this->get() ; }
0916
0917 #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
0918 reference_type_of_temporary_wrapper operator *() && { return optional_detail::move(this->get()) ; }
0919 #endif
0920
0921 reference_const_type value() BOOST_OPTIONAL_CONST_REF_QUAL
0922 {
0923 if (this->is_initialized())
0924 return this->get() ;
0925 else
0926 throw_exception(bad_optional_access());
0927 }
0928
0929 reference_type value() BOOST_OPTIONAL_REF_QUAL
0930 {
0931 if (this->is_initialized())
0932 return this->get() ;
0933 else
0934 throw_exception(bad_optional_access());
0935 }
0936
0937 template <class U>
0938 value_type value_or ( U&& v ) BOOST_OPTIONAL_CONST_REF_QUAL
0939 {
0940 if (this->is_initialized())
0941 return get();
0942 else
0943 return optional_detail::forward<U>(v);
0944 }
0945
0946 template <typename F>
0947 value_type value_or_eval ( F f ) BOOST_OPTIONAL_CONST_REF_QUAL
0948 {
0949 if (this->is_initialized())
0950 return get();
0951 else
0952 return f();
0953 }
0954
0955 #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
0956 reference_type_of_temporary_wrapper value() &&
0957 {
0958 if (this->is_initialized())
0959 return optional_detail::move(this->get()) ;
0960 else
0961 throw_exception(bad_optional_access());
0962 }
0963
0964 template <class U>
0965 value_type value_or ( U&& v ) &&
0966 {
0967 if (this->is_initialized())
0968 return optional_detail::move(get());
0969 else
0970 return optional_detail::forward<U>(v);
0971 }
0972
0973 template <typename F>
0974 value_type value_or_eval ( F f ) &&
0975 {
0976 if (this->is_initialized())
0977 return optional_detail::move(get());
0978 else
0979 return f();
0980 }
0981 #endif
0982
0983
0984
0985 template <typename F>
0986 optional<typename optional_detail::result_of<F, reference_type>::type> map(F f) BOOST_OPTIONAL_REF_QUAL
0987 {
0988 if (this->has_value())
0989 return f(get());
0990 else
0991 return none;
0992 }
0993
0994 template <typename F>
0995 optional<typename optional_detail::result_of<F, reference_const_type>::type> map(F f) BOOST_OPTIONAL_CONST_REF_QUAL
0996 {
0997 if (this->has_value())
0998 return f(get());
0999 else
1000 return none;
1001 }
1002
1003 #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
1004 template <typename F>
1005 optional<typename optional_detail::result_of<F, reference_type_of_temporary_wrapper>::type> map(F f) &&
1006 {
1007 if (this->has_value())
1008 return f(optional_detail::move(this->get()));
1009 else
1010 return none;
1011 }
1012 #endif
1013
1014 template <typename F>
1015 optional<typename optional_detail::result_value_type<F, reference_type>::type>
1016 flat_map(F f) BOOST_OPTIONAL_REF_QUAL
1017 {
1018 if (this->has_value())
1019 return f(get());
1020 else
1021 return none;
1022 }
1023
1024 template <typename F>
1025 optional<typename optional_detail::result_value_type<F, reference_const_type>::type>
1026 flat_map(F f) BOOST_OPTIONAL_CONST_REF_QUAL
1027 {
1028 if (this->has_value())
1029 return f(get());
1030 else
1031 return none;
1032 }
1033
1034 #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
1035 template <typename F>
1036 optional<typename optional_detail::result_value_type<F, reference_type_of_temporary_wrapper>::type>
1037 flat_map(F f) &&
1038 {
1039 if (this->has_value())
1040 return f(optional_detail::move(get()));
1041 else
1042 return none;
1043 }
1044 #endif
1045
1046 bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; }
1047
1048 explicit operator bool() const BOOST_NOEXCEPT { return this->has_value() ; }
1049 } ;
1050
1051
1052 template<class T>
1053 class optional<T&&>
1054 {
1055 static_assert(sizeof(T) == 0, "Optional rvalue references are illegal.");
1056 } ;
1057
1058 }
1059
1060 #ifndef BOOST_OPTIONAL_CONFIG_DONT_SPECIALIZE_OPTIONAL_REFS
1061 # include <boost/optional/detail/optional_reference_spec.hpp>
1062 #endif
1063
1064 namespace boost {
1065
1066
1067 template<class T>
1068 inline
1069 optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( T && v )
1070 {
1071 return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(optional_detail::forward<T>(v));
1072 }
1073
1074
1075 template<class T>
1076 inline
1077 optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type> make_optional ( bool cond, T && v )
1078 {
1079 return optional<BOOST_DEDUCED_TYPENAME boost::decay<T>::type>(cond,optional_detail::forward<T>(v));
1080 }
1081
1082
1083
1084
1085 template<class T>
1086 inline
1087 BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1088 get ( optional<T> const& opt )
1089 {
1090 return opt.get() ;
1091 }
1092
1093 template<class T>
1094 inline
1095 BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1096 get ( optional<T>& opt )
1097 {
1098 return opt.get() ;
1099 }
1100
1101
1102
1103 template<class T>
1104 inline
1105 BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1106 get ( optional<T> const* opt )
1107 {
1108 return opt->get_ptr() ;
1109 }
1110
1111 template<class T>
1112 inline
1113 BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1114 get ( optional<T>* opt )
1115 {
1116 return opt->get_ptr() ;
1117 }
1118
1119
1120
1121 template<class T>
1122 inline
1123 BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
1124 get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
1125 {
1126 return opt.get_value_or(v) ;
1127 }
1128
1129 template<class T>
1130 inline
1131 BOOST_DEDUCED_TYPENAME optional<T>::reference_type
1132 get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
1133 {
1134 return opt.get_value_or(v) ;
1135 }
1136
1137
1138
1139 template<class T>
1140 inline
1141 BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
1142 get_pointer ( optional<T> const& opt )
1143 {
1144 return opt.get_ptr() ;
1145 }
1146
1147 template<class T>
1148 inline
1149 BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
1150 get_pointer ( optional<T>& opt )
1151 {
1152 return opt.get_ptr() ;
1153 }
1154
1155 }
1156
1157 #ifndef BOOST_NO_IOSTREAM
1158 namespace boost {
1159
1160
1161 template<class CharType, class CharTrait>
1162 std::basic_ostream<CharType, CharTrait>&
1163 operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optional_tag const&)
1164 {
1165 static_assert(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
1166 return os;
1167 }
1168
1169 }
1170 #endif
1171
1172 #include <boost/optional/detail/optional_relops.hpp>
1173 #include <boost/optional/detail/optional_swap.hpp>
1174
1175 #endif