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