File indexing completed on 2026-08-17 08:39:22
0001 #ifndef BOOST_COMPAT_MOVE_ONLY_FUNCTION_HPP_INCLUDED
0002 #define BOOST_COMPAT_MOVE_ONLY_FUNCTION_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <boost/compat/invoke.hpp>
0009 #include <boost/compat/type_traits.hpp>
0010 #include <boost/assert.hpp>
0011
0012 #include <cstddef>
0013 #include <initializer_list>
0014 #include <type_traits>
0015
0016 #include <boost/config/workaround.hpp>
0017
0018 #if BOOST_WORKAROUND(BOOST_GCC, >= 6 * 10000)
0019 # pragma GCC diagnostic push
0020 # pragma GCC diagnostic ignored "-Wnonnull-compare"
0021 # pragma GCC diagnostic ignored "-Waddress"
0022 #endif
0023
0024 namespace boost {
0025 namespace compat {
0026
0027 template<class... S>
0028 class move_only_function;
0029
0030 template< class T >
0031 struct in_place_type_t { explicit in_place_type_t() = default; };
0032
0033 namespace detail
0034 {
0035
0036 union pointers
0037 {
0038 void* pobj_;
0039 void ( *pfn_ )();
0040 };
0041
0042 struct storage
0043 {
0044
0045 struct delegate { void( storage::*pmfn_ )(); storage* pobj_; };
0046
0047 union
0048 {
0049 void* pobj_;
0050 void ( *pfn_ )();
0051 alignas(delegate) unsigned char buf_[ sizeof(delegate) ];
0052 };
0053
0054 template<class T>
0055 constexpr static bool use_sbo() noexcept
0056 {
0057 return sizeof( T ) <= sizeof( storage ) && alignof( T ) <= alignof( storage ) && std::is_nothrow_move_constructible<T>::value;
0058 }
0059
0060 void* addr() noexcept
0061 {
0062 return buf_;
0063 }
0064 };
0065
0066 template<class>
0067 struct is_polymorphic_function : std::false_type
0068 {
0069 };
0070
0071 template<class R, class ...Args>
0072 struct is_polymorphic_function<move_only_function<R( Args... )>> : std::true_type
0073 {
0074 };
0075
0076 template<class R, class ...Args>
0077 struct is_polymorphic_function<move_only_function<R( Args... ) &>> : std::true_type
0078 {
0079 };
0080
0081 template<class R, class ...Args>
0082 struct is_polymorphic_function<move_only_function<R( Args... ) &&>> : std::true_type
0083 {
0084 };
0085
0086 template<class R, class ...Args>
0087 struct is_polymorphic_function<move_only_function<R( Args... ) const>> : std::true_type
0088 {
0089 };
0090
0091 template<class R, class ...Args>
0092 struct is_polymorphic_function<move_only_function<R( Args... ) const&>> : std::true_type
0093 {
0094 };
0095
0096 template<class R, class ...Args>
0097 struct is_polymorphic_function<move_only_function<R( Args... ) const&&>> : std::true_type
0098 {
0099 };
0100
0101 #if defined(__cpp_noexcept_function_type)
0102
0103 template<class R, class ...Args>
0104 struct is_polymorphic_function<move_only_function<R( Args... ) noexcept>> : std::true_type
0105 {
0106 };
0107
0108 template<class R, class ...Args>
0109 struct is_polymorphic_function<move_only_function<R( Args... ) & noexcept>> : std::true_type
0110 {
0111 };
0112
0113 template<class R, class ...Args>
0114 struct is_polymorphic_function<move_only_function<R( Args... ) && noexcept>> : std::true_type
0115 {
0116 };
0117
0118 template<class R, class ...Args>
0119 struct is_polymorphic_function<move_only_function<R( Args... ) const noexcept>> : std::true_type
0120 {
0121 };
0122
0123 template<class R, class ...Args>
0124 struct is_polymorphic_function<move_only_function<R( Args... ) const& noexcept>> : std::true_type
0125 {
0126 };
0127
0128 template<class R, class ...Args>
0129 struct is_polymorphic_function<move_only_function<R( Args... ) const&& noexcept>> : std::true_type
0130 {
0131 };
0132
0133 #endif
0134
0135 template<class T>
0136 using is_move_only_function = is_polymorphic_function<T>;
0137
0138 template<class T>
0139 struct is_in_place_type_t : std::false_type
0140 {
0141 };
0142
0143 template<class T>
0144 struct is_in_place_type_t<in_place_type_t<T>> : std::true_type
0145 {
0146 };
0147
0148 template<class T, class ...Args>
0149 struct nothrow_init
0150 {
0151 constexpr static bool const value = ( storage::use_sbo<T>() && std::is_nothrow_constructible<T, Args...>::value ) || false;
0152 };
0153
0154 enum class ref_quals { none, lvalue, rvalue };
0155
0156 template<ref_quals RQ, bool Const, bool NoEx, class VT, class R, class ...Args>
0157 struct is_callable_from;
0158
0159 template<ref_quals RQ, bool Const, class VT, class R, class ...Args>
0160 struct is_callable_from<RQ, Const, true, VT, R, Args...>
0161 {
0162 using cv_VT = conditional_t<Const, add_const_t<VT>, VT>;
0163
0164 using cv_ref_VT = conditional_t<
0165 RQ == ref_quals::none, cv_VT,
0166 conditional_t<
0167 RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
0168 >
0169 >;
0170
0171 using inv_quals_VT = conditional_t<
0172 RQ == ref_quals::none, add_lvalue_reference_t<cv_VT>,
0173 conditional_t<
0174 RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
0175 >
0176 >;
0177
0178 constexpr static bool const value =
0179 is_nothrow_invocable_r<R, cv_ref_VT, Args...>::value &&
0180 is_nothrow_invocable_r<R, inv_quals_VT, Args...>::value;
0181 };
0182
0183 template<ref_quals RQ, bool Const, class VT, class R, class ...Args>
0184 struct is_callable_from<RQ, Const, false, VT, R, Args...>
0185 {
0186 using cv_VT = conditional_t<Const, add_const_t<VT>, VT>;
0187
0188 using cv_ref_VT = conditional_t<
0189 RQ == ref_quals::none, cv_VT,
0190 conditional_t<
0191 RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
0192 >
0193 >;
0194
0195 using inv_quals_VT = conditional_t<
0196 RQ == ref_quals::none, add_lvalue_reference_t<cv_VT>,
0197 conditional_t<
0198 RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
0199 >
0200 >;
0201
0202 constexpr static bool const value =
0203 is_invocable_r<R, cv_ref_VT, Args...>::value &&
0204 is_invocable_r<R, inv_quals_VT, Args...>::value;
0205 };
0206
0207 inline std::nullptr_t get_first_arg()
0208 {
0209 return nullptr;
0210 }
0211
0212 template<class T, class ...CArgs>
0213 T&& get_first_arg( T&& t, CArgs&& ... )
0214 {
0215 return std::forward<T>( t );
0216 }
0217
0218 template<class ...Ts>
0219 bool is_nullary_arg( Ts&&... )
0220 {
0221 return false;
0222 }
0223
0224 template<
0225 class F, class VT = decay_t<F>,
0226 enable_if_t<
0227 std::is_member_pointer<VT>::value ||
0228 is_move_only_function<VT>::value,
0229 int> = 0
0230 >
0231 bool is_nullary_arg( F&& f )
0232 {
0233 return f == nullptr;
0234 }
0235
0236 template<
0237 class F, class VT = decay_t<F>,
0238 enable_if_t<
0239 std::is_function<remove_pointer_t<VT>>::value,
0240 int> = 0
0241 >
0242 bool is_nullary_arg( F f )
0243 {
0244 return f == nullptr;
0245 }
0246
0247 template<bool NoEx, class R, class ...Args>
0248 struct mo_invoke_function_holder
0249 {
0250 static R invoke_function( storage s, Args&&... args) noexcept( NoEx )
0251 {
0252 auto f = reinterpret_cast<R(*)( Args... )>( s.pfn_ );
0253 return compat::invoke_r<R>( f, std::forward<Args>( args )... );
0254 }
0255 };
0256
0257 template<ref_quals RQ, bool Const, bool NoEx, class F, class R, class ...Args>
0258 struct mo_invoke_object_holder
0259 {
0260 static R invoke_object( storage s, Args&&... args ) noexcept( NoEx )
0261 {
0262 using T = remove_reference_t<F>;
0263 using cv_T = conditional_t<Const, add_const_t<T>, T>;
0264 using cv_ref_T = conditional_t<
0265 RQ == ref_quals::none, add_lvalue_reference_t<cv_T>,
0266 conditional_t<
0267 RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_T>, add_lvalue_reference_t<cv_T>
0268 >
0269 >;
0270 return compat::invoke_r<R>( static_cast<cv_ref_T>( *static_cast<cv_T*>( s.pobj_ ) ), std::forward<Args>( args )... );
0271 }
0272 };
0273
0274 template<ref_quals RQ, bool Const, bool NoEx, class F, class R, class ...Args>
0275 struct mo_invoke_local_holder
0276 {
0277 static R invoke_local( storage s, Args&&... args ) noexcept( NoEx )
0278 {
0279 using T = remove_reference_t<F>;
0280 using cv_T = conditional_t<Const, add_const_t<T>, T>;
0281 using cv_ref_T = conditional_t<
0282 RQ == ref_quals::none, add_lvalue_reference_t<cv_T>,
0283 conditional_t<
0284 RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_T>, add_lvalue_reference_t<cv_T>
0285 >
0286 >;
0287
0288 return compat::invoke_r<R>( static_cast<cv_ref_T>( *static_cast<cv_T*>( s.addr() ) ), std::forward<Args>( args )... );
0289 }
0290 };
0291
0292 enum class op_type { move, destroy };
0293
0294 template <ref_quals RQ, bool Const, bool NoEx, class R, class ...Args>
0295 struct move_only_function_base
0296 {
0297 move_only_function_base() = default;
0298
0299 move_only_function_base( move_only_function_base&& rhs ) noexcept
0300 {
0301 manager_ = rhs.manager_;
0302 manager_( op_type::move, s_, &rhs.s_ );
0303
0304 invoke_ = rhs.invoke_;
0305 rhs.invoke_ = nullptr;
0306 rhs.manager_ = &manage_empty;
0307 }
0308
0309 ~move_only_function_base()
0310 {
0311 destroy();
0312 }
0313
0314 void swap( move_only_function_base& rhs ) noexcept
0315 {
0316
0317
0318
0319
0320 storage s;
0321 rhs.manager_( op_type::move, s, &rhs.s_ );
0322 manager_( op_type::move, rhs.s_, &s_ );
0323 rhs.manager_( op_type::move, s_, &s );
0324
0325 std::swap( manager_, rhs.manager_ );
0326 std::swap( invoke_, rhs.invoke_ );
0327 }
0328
0329 move_only_function_base& operator=( move_only_function_base&& rhs )
0330 {
0331 destroy();
0332
0333 manager_ = rhs.manager_;
0334 manager_( op_type::move, s_, &rhs.s_ );
0335 invoke_ = rhs.invoke_;
0336
0337 rhs.invoke_ = nullptr;
0338 rhs.manager_ = &manage_empty;
0339 return *this;
0340 }
0341
0342 move_only_function_base& operator=( std::nullptr_t ) noexcept
0343 {
0344 destroy();
0345 invoke_ = nullptr;
0346 manager_ = &manage_empty;
0347 return *this;
0348 }
0349
0350 static void manage_empty( op_type, detail::storage&, detail::storage* )
0351 {
0352 }
0353
0354 static void manage_function( op_type op, detail::storage& s, detail::storage* src )
0355 {
0356 switch( op )
0357 {
0358 case op_type::move:
0359 s.pfn_ = src->pfn_;
0360 src->pfn_ = nullptr;
0361 break;
0362
0363 default:
0364 break;
0365 }
0366
0367 }
0368
0369 template<class VT>
0370 static void manage_object( op_type op, detail::storage& s, detail::storage* src )
0371 {
0372 switch( op )
0373 {
0374 case op_type::destroy:
0375 delete static_cast<VT*>( s.pobj_ );
0376 break;
0377
0378 case op_type::move:
0379 s.pobj_ = src->pobj_;
0380 src->pobj_ = nullptr;
0381 break;
0382
0383 default:
0384 break;
0385 }
0386 }
0387
0388 template<class VT>
0389 static void manage_local( op_type op, detail::storage& s, detail::storage* src )
0390 {
0391 switch( op )
0392 {
0393 case op_type::destroy:
0394 static_cast<VT*>( s.addr() )->~VT();
0395 break;
0396
0397 case op_type::move:
0398 {
0399 VT* p = static_cast<VT*>( src->addr() );
0400 new(s.addr()) VT( std::move( *p ) );
0401
0402
0403 p->~VT();
0404 break;
0405 }
0406
0407 default:
0408 break;
0409 }
0410 }
0411
0412 template <ref_quals RQ2, bool Const2, bool NoEx2, class R2, class ...Args2>
0413 void
0414 move_from_compatible_base( move_only_function_base<RQ2, Const2, NoEx2, R2, Args2...>& base )
0415 {
0416 using polymorphic_base = move_only_function_base<RQ2, Const2, NoEx2, R2, Args2...>;
0417
0418 manager_ = base.manager_;
0419
0420 manager_( op_type::move, s_, &base.s_ );
0421 invoke_ = base.invoke_;
0422
0423 base.invoke_ = nullptr;
0424 base.manager_ = &polymorphic_base::manage_empty;
0425 }
0426
0427 template<class F>
0428 void base_init( std::true_type, F&& f )
0429 {
0430 move_from_compatible_base( f );
0431 }
0432
0433 template<class ...F>
0434 void base_init( std::false_type, F&&... )
0435 {
0436 }
0437
0438 template<class VT, class ...CArgs>
0439 void init( std::false_type , CArgs&& ...args )
0440 {
0441 if( is_polymorphic_function<VT>::value )
0442 {
0443 base_init( is_polymorphic_function<VT>{}, std::forward<CArgs>( args )... );
0444 return;
0445 }
0446
0447 if( !storage::use_sbo<VT>() )
0448 {
0449 s_.pobj_ = new VT( std::forward<CArgs>( args )... );
0450 invoke_ = &mo_invoke_object_holder<RQ, Const, NoEx, VT, R, Args...>::invoke_object;
0451 manager_ = &manage_object<VT>;
0452 }
0453 else
0454 {
0455 new( s_.addr() ) VT( std::forward<CArgs>( args )... );
0456 invoke_ = &mo_invoke_local_holder<RQ, Const, NoEx, VT, R, Args...>::invoke_local;
0457 manager_ = &manage_local<VT>;
0458 }
0459 }
0460
0461 template<class VT, class ...CArgs>
0462 void init( std::true_type , CArgs ...args )
0463 {
0464 R (*pfn)( Args... ) = get_first_arg( args... );
0465 s_.pfn_ = reinterpret_cast<void(*)()>( pfn );
0466 invoke_ = &detail::mo_invoke_function_holder<NoEx, R, Args...>::invoke_function;
0467 manager_ = &manage_function;
0468 }
0469
0470 template <class VT, class ...CArgs>
0471 void init( type_identity<VT>, CArgs&& ...args )
0472 {
0473 init<VT>( std::is_function<remove_pointer_t<VT>>(), std::forward<CArgs>( args )... );
0474 }
0475
0476 void destroy()
0477 {
0478 manager_( op_type::destroy, s_, nullptr );
0479 }
0480
0481 explicit operator bool() const noexcept
0482 {
0483 return invoke_ != nullptr;
0484 }
0485
0486 detail::storage s_;
0487 #if defined(__cpp_noexcept_function_type)
0488 R ( *invoke_ )( detail::storage, Args&&... ) noexcept( NoEx ) = nullptr;
0489 #else
0490 R ( *invoke_ )( detail::storage, Args&&... ) = nullptr;
0491 #endif
0492 void ( *manager_ )( op_type, detail::storage&, detail::storage* ) = &manage_empty;
0493 };
0494
0495 }
0496
0497 template<class R, class ...Args>
0498 class move_only_function<R( Args... )> : detail::move_only_function_base<detail::ref_quals::none, false, false, R, Args...>
0499 {
0500 private:
0501
0502 template<detail::ref_quals, bool, bool, class, class ...>
0503 friend struct detail::move_only_function_base;
0504
0505 using base = detail::move_only_function_base<detail::ref_quals::none, false, false, R, Args...>;
0506
0507 public:
0508
0509 move_only_function() noexcept
0510 {
0511 }
0512
0513 move_only_function( std::nullptr_t ) noexcept
0514 : move_only_function()
0515 {
0516 }
0517
0518 template<
0519 class F,
0520 class VT = decay_t<F>,
0521 enable_if_t<
0522 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
0523 !detail::is_in_place_type_t<VT>::value &&
0524 detail::is_callable_from<detail::ref_quals::none, false, false, VT, R, Args...>::value,
0525 int> = 0
0526 >
0527 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
0528 {
0529 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
0530 base::init( type_identity<VT>{}, std::forward<F>( f ) );
0531 }
0532
0533 template<
0534 class T, class ...CArgs,
0535 enable_if_t<
0536 std::is_constructible<T, CArgs...>::value &&
0537 detail::is_callable_from<detail::ref_quals::none, false, false, T, R, Args...>::value,
0538 int> = 0
0539 >
0540 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
0541 {
0542 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0543 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
0544 }
0545
0546 template<
0547 class T, class U, class ...CArgs,
0548 enable_if_t<
0549 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
0550 detail::is_callable_from<detail::ref_quals::none, false, false, T, R, Args...>::value,
0551 int> = 0
0552 >
0553 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
0554 {
0555 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0556 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
0557 }
0558
0559 move_only_function( move_only_function const& ) = delete;
0560 move_only_function( move_only_function&& ) = default;
0561
0562 ~move_only_function() = default;
0563
0564 move_only_function& operator=( move_only_function&& rhs )
0565 {
0566 if( this != &rhs )
0567 {
0568 this->base::operator=( static_cast<base&&>( rhs ) );
0569 }
0570 return *this;
0571 }
0572
0573 move_only_function& operator=( std::nullptr_t ) noexcept
0574 {
0575 this->base::operator=( nullptr );
0576 return *this;
0577 }
0578
0579 template<class F> move_only_function& operator=( F&& f )
0580 {
0581 move_only_function( std::forward<F>( f ) ).swap( *this );
0582 return *this;
0583 }
0584
0585 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
0586 {
0587 return fn.invoke_ == nullptr;
0588 }
0589
0590 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
0591 {
0592 return !( fn == nullptr );
0593 }
0594
0595 void swap( move_only_function& rhs ) noexcept
0596 {
0597 if( this != &rhs )
0598 {
0599 this->base::swap( rhs );
0600 }
0601 }
0602
0603 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
0604 {
0605 lhs.swap( rhs );
0606 }
0607
0608 explicit operator bool() const noexcept
0609 {
0610 return static_cast<bool>( *static_cast<base const*>( this ) );
0611 }
0612
0613 R operator()( Args... args )
0614 {
0615 return this->invoke_( this->s_, std::forward<Args>( args )... );
0616 }
0617 };
0618
0619 template<class R, class ...Args>
0620 class move_only_function<R( Args... ) &> : detail::move_only_function_base<detail::ref_quals::lvalue, false, false, R, Args...>
0621 {
0622 private:
0623
0624 template<detail::ref_quals, bool, bool, class, class ...>
0625 friend struct detail::move_only_function_base;
0626
0627 using base = detail::move_only_function_base<detail::ref_quals::lvalue, false, false, R, Args...>;
0628
0629 public:
0630
0631 move_only_function() noexcept
0632 {
0633 }
0634
0635 move_only_function( std::nullptr_t ) noexcept
0636 : move_only_function()
0637 {
0638 }
0639
0640 template<
0641 class F,
0642 class VT = decay_t<F>,
0643 enable_if_t<
0644 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
0645 !detail::is_in_place_type_t<VT>::value &&
0646 detail::is_callable_from<detail::ref_quals::lvalue, false, false, VT, R, Args...>::value,
0647 int> = 0
0648 >
0649 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
0650 {
0651 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
0652 base::init( type_identity<VT>{}, std::forward<F>( f ) );
0653 }
0654
0655 template<
0656 class T, class ...CArgs,
0657 enable_if_t<
0658 std::is_constructible<T, CArgs...>::value &&
0659 detail::is_callable_from<detail::ref_quals::lvalue, false, false, T, R, Args...>::value,
0660 int> = 0
0661 >
0662 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
0663 {
0664 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0665 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
0666 }
0667
0668 template<
0669 class T, class U, class ...CArgs,
0670 enable_if_t<
0671 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
0672 detail::is_callable_from<detail::ref_quals::lvalue, false, false, T, R, Args...>::value,
0673 int> = 0
0674 >
0675 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
0676 {
0677 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0678 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
0679 }
0680
0681 move_only_function( move_only_function const& ) = delete;
0682 move_only_function( move_only_function&& ) = default;
0683
0684 ~move_only_function() = default;
0685
0686 move_only_function& operator=( move_only_function&& rhs )
0687 {
0688 if( this != &rhs )
0689 {
0690 this->base::operator=( static_cast<base&&>( rhs ) );
0691 }
0692 return *this;
0693 }
0694
0695 move_only_function& operator=( std::nullptr_t ) noexcept
0696 {
0697 this->base::operator=( nullptr );
0698 return *this;
0699 }
0700
0701 template<class F> move_only_function& operator=( F&& f )
0702 {
0703 move_only_function( std::forward<F>( f ) ).swap( *this );
0704 return *this;
0705 }
0706
0707 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
0708 {
0709 return fn.invoke_ == nullptr;
0710 }
0711
0712 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
0713 {
0714 return !( fn == nullptr );
0715 }
0716
0717 void swap( move_only_function& rhs ) noexcept
0718 {
0719 if( this != &rhs )
0720 {
0721 this->base::swap( rhs );
0722 }
0723 }
0724
0725 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
0726 {
0727 lhs.swap( rhs );
0728 }
0729
0730 explicit operator bool() const noexcept
0731 {
0732 return static_cast<bool>( *static_cast<base const*>( this ) );
0733 }
0734
0735 R operator()( Args... args ) &
0736 {
0737 return this->invoke_( this->s_, std::forward<Args>( args )... );
0738 }
0739 };
0740
0741 template<class R, class ...Args>
0742 class move_only_function<R( Args... ) &&> : detail::move_only_function_base<detail::ref_quals::rvalue, false, false, R, Args...>
0743 {
0744 private:
0745
0746 template<detail::ref_quals, bool, bool, class, class ...>
0747 friend struct detail::move_only_function_base;
0748
0749 using base = detail::move_only_function_base<detail::ref_quals::rvalue, false, false, R, Args...>;
0750
0751 public:
0752
0753 move_only_function() noexcept
0754 {
0755 }
0756
0757 move_only_function( std::nullptr_t ) noexcept
0758 : move_only_function()
0759 {
0760 }
0761
0762 template<
0763 class F,
0764 class VT = decay_t<F>,
0765 enable_if_t<
0766 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
0767 !detail::is_in_place_type_t<VT>::value &&
0768 detail::is_callable_from<detail::ref_quals::rvalue, false, false, VT, R, Args...>::value,
0769 int> = 0
0770 >
0771 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
0772 {
0773 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
0774 base::init( type_identity<VT>{}, std::forward<F>( f ) );
0775 }
0776
0777 template<
0778 class T, class ...CArgs,
0779 enable_if_t<
0780 std::is_constructible<T, CArgs...>::value &&
0781 detail::is_callable_from<detail::ref_quals::rvalue, false, false, T, R, Args...>::value,
0782 int> = 0
0783 >
0784 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
0785 {
0786 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0787 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
0788 }
0789
0790 template<
0791 class T, class U, class ...CArgs,
0792 enable_if_t<
0793 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
0794 detail::is_callable_from<detail::ref_quals::rvalue, false, false, T, R, Args...>::value,
0795 int> = 0
0796 >
0797 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
0798 {
0799 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0800 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
0801 }
0802
0803 move_only_function( move_only_function const& ) = delete;
0804 move_only_function( move_only_function&& ) = default;
0805
0806 ~move_only_function() = default;
0807
0808 move_only_function& operator=( move_only_function&& rhs )
0809 {
0810 if( this != &rhs )
0811 {
0812 this->base::operator=( static_cast<base&&>( rhs ) );
0813 }
0814 return *this;
0815 }
0816
0817 move_only_function& operator=( std::nullptr_t ) noexcept
0818 {
0819 this->base::operator=( nullptr );
0820 return *this;
0821 }
0822
0823 template<class F> move_only_function& operator=( F&& f )
0824 {
0825 move_only_function( std::forward<F>( f ) ).swap( *this );
0826 return *this;
0827 }
0828
0829 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
0830 {
0831 return fn.invoke_ == nullptr;
0832 }
0833
0834 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
0835 {
0836 return !( fn == nullptr );
0837 }
0838
0839 void swap( move_only_function& rhs ) noexcept
0840 {
0841 if( this != &rhs )
0842 {
0843 this->base::swap( rhs );
0844 }
0845 }
0846
0847 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
0848 {
0849 lhs.swap( rhs );
0850 }
0851
0852 explicit operator bool() const noexcept
0853 {
0854 return static_cast<bool>( *static_cast<base const*>( this ) );
0855 }
0856
0857 R operator()( Args... args ) &&
0858 {
0859 return this->invoke_( this->s_, std::forward<Args>( args )... );
0860 }
0861 };
0862
0863 template<class R, class ...Args>
0864 class move_only_function<R( Args... ) const> : detail::move_only_function_base<detail::ref_quals::none, true, false, R, Args...>
0865 {
0866 private:
0867
0868 template<detail::ref_quals, bool, bool, class, class ...>
0869 friend struct detail::move_only_function_base;
0870
0871 using base = detail::move_only_function_base<detail::ref_quals::none, true, false, R, Args...>;
0872
0873 public:
0874
0875 move_only_function() noexcept
0876 {
0877 }
0878
0879 move_only_function( std::nullptr_t ) noexcept
0880 : move_only_function()
0881 {
0882 }
0883
0884 template<
0885 class F,
0886 class VT = decay_t<F>,
0887 enable_if_t<
0888 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
0889 !detail::is_in_place_type_t<VT>::value &&
0890 detail::is_callable_from<detail::ref_quals::none, true, false, VT, R, Args...>::value,
0891 int> = 0
0892 >
0893 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
0894 {
0895 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
0896 base::init( type_identity<VT>{}, std::forward<F>( f ) );
0897 }
0898
0899 template<
0900 class T, class ...CArgs,
0901 enable_if_t<
0902 std::is_constructible<T, CArgs...>::value &&
0903 detail::is_callable_from<detail::ref_quals::none, true, false, T, R, Args...>::value,
0904 int> = 0
0905 >
0906 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
0907 {
0908 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0909 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
0910 }
0911
0912 template<
0913 class T, class U, class ...CArgs,
0914 enable_if_t<
0915 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
0916 detail::is_callable_from<detail::ref_quals::none, true, false, T, R, Args...>::value,
0917 int> = 0
0918 >
0919 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
0920 {
0921 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
0922 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
0923 }
0924
0925 move_only_function( move_only_function const& ) = delete;
0926 move_only_function( move_only_function&& ) = default;
0927
0928 ~move_only_function() = default;
0929
0930 move_only_function& operator=( move_only_function&& rhs )
0931 {
0932 if( this != &rhs )
0933 {
0934 this->base::operator=( static_cast<base&&>( rhs ) );
0935 }
0936 return *this;
0937 }
0938
0939 move_only_function& operator=( std::nullptr_t ) noexcept
0940 {
0941 this->base::operator=( nullptr );
0942 return *this;
0943 }
0944
0945 template<class F> move_only_function& operator=( F&& f )
0946 {
0947 move_only_function( std::forward<F>( f ) ).swap( *this );
0948 return *this;
0949 }
0950
0951 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
0952 {
0953 return fn.invoke_ == nullptr;
0954 }
0955
0956 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
0957 {
0958 return !( fn == nullptr );
0959 }
0960
0961 void swap( move_only_function& rhs ) noexcept
0962 {
0963 if( this != &rhs )
0964 {
0965 this->base::swap( rhs );
0966 }
0967 }
0968
0969 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
0970 {
0971 lhs.swap( rhs );
0972 }
0973
0974 explicit operator bool() const noexcept
0975 {
0976 return static_cast<bool>( *static_cast<base const*>( this ) );
0977 }
0978
0979 R operator()( Args... args ) const
0980 {
0981 return this->invoke_( this->s_, std::forward<Args>( args )... );
0982 }
0983 };
0984
0985 template<class R, class ...Args>
0986 class move_only_function<R( Args... ) const&> : detail::move_only_function_base<detail::ref_quals::lvalue, true, false, R, Args...>
0987 {
0988 private:
0989
0990 template<detail::ref_quals, bool, bool, class, class ...>
0991 friend struct detail::move_only_function_base;
0992
0993 using base = detail::move_only_function_base<detail::ref_quals::lvalue, true, false, R, Args...>;
0994
0995 public:
0996
0997 move_only_function() noexcept
0998 {
0999 }
1000
1001 move_only_function( std::nullptr_t ) noexcept
1002 : move_only_function()
1003 {
1004 }
1005
1006 template<
1007 class F,
1008 class VT = decay_t<F>,
1009 enable_if_t<
1010 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1011 !detail::is_in_place_type_t<VT>::value &&
1012 detail::is_callable_from<detail::ref_quals::lvalue, true, false, VT, R, Args...>::value,
1013 int> = 0
1014 >
1015 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1016 {
1017 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1018 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1019 }
1020
1021 template<
1022 class T, class ...CArgs,
1023 enable_if_t<
1024 std::is_constructible<T, CArgs...>::value &&
1025 detail::is_callable_from<detail::ref_quals::lvalue, true, false, T, R, Args...>::value,
1026 int> = 0
1027 >
1028 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1029 {
1030 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1031 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1032 }
1033
1034 template<
1035 class T, class U, class ...CArgs,
1036 enable_if_t<
1037 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1038 detail::is_callable_from<detail::ref_quals::lvalue, true, false, T, R, Args...>::value,
1039 int> = 0
1040 >
1041 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1042 {
1043 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1044 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1045 }
1046
1047 move_only_function( move_only_function const& ) = delete;
1048 move_only_function( move_only_function&& ) = default;
1049
1050 ~move_only_function() = default;
1051
1052 move_only_function& operator=( move_only_function&& rhs )
1053 {
1054 if( this != &rhs )
1055 {
1056 this->base::operator=( static_cast<base&&>( rhs ) );
1057 }
1058 return *this;
1059 }
1060
1061 move_only_function& operator=( std::nullptr_t ) noexcept
1062 {
1063 this->base::operator=( nullptr );
1064 return *this;
1065 }
1066
1067 template<class F> move_only_function& operator=( F&& f )
1068 {
1069 move_only_function( std::forward<F>( f ) ).swap( *this );
1070 return *this;
1071 }
1072
1073 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1074 {
1075 return fn.invoke_ == nullptr;
1076 }
1077
1078 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1079 {
1080 return !( fn == nullptr );
1081 }
1082
1083 void swap( move_only_function& rhs ) noexcept
1084 {
1085 if( this != &rhs )
1086 {
1087 this->base::swap( rhs );
1088 }
1089 }
1090
1091 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1092 {
1093 lhs.swap( rhs );
1094 }
1095
1096 explicit operator bool() const noexcept
1097 {
1098 return static_cast<bool>( *static_cast<base const*>( this ) );
1099 }
1100
1101 R operator()( Args... args ) const &
1102 {
1103 return this->invoke_( this->s_, std::forward<Args>( args )... );
1104 }
1105 };
1106
1107 template<class R, class ...Args>
1108 class move_only_function<R( Args... ) const&&> : detail::move_only_function_base<detail::ref_quals::rvalue, true, false, R, Args...>
1109 {
1110 private:
1111
1112 template<detail::ref_quals, bool, bool, class, class ...>
1113 friend struct detail::move_only_function_base;
1114
1115 using base = detail::move_only_function_base<detail::ref_quals::rvalue, true, false, R, Args...>;
1116
1117 public:
1118
1119 move_only_function() noexcept
1120 {
1121 }
1122
1123 move_only_function( std::nullptr_t ) noexcept
1124 : move_only_function()
1125 {
1126 }
1127
1128 template<
1129 class F,
1130 class VT = decay_t<F>,
1131 enable_if_t<
1132 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1133 !detail::is_in_place_type_t<VT>::value &&
1134 detail::is_callable_from<detail::ref_quals::rvalue, true, false, VT, R, Args...>::value,
1135 int> = 0
1136 >
1137 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1138 {
1139 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1140 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1141 }
1142
1143 template<
1144 class T, class ...CArgs,
1145 enable_if_t<
1146 std::is_constructible<T, CArgs...>::value &&
1147 detail::is_callable_from<detail::ref_quals::rvalue, true, false, T, R, Args...>::value,
1148 int> = 0
1149 >
1150 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1151 {
1152 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1153 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1154 }
1155
1156 template<
1157 class T, class U, class ...CArgs,
1158 enable_if_t<
1159 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1160 detail::is_callable_from<detail::ref_quals::rvalue, true, false, T, R, Args...>::value,
1161 int> = 0
1162 >
1163 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1164 {
1165 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1166 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1167 }
1168
1169 move_only_function( move_only_function const& ) = delete;
1170 move_only_function( move_only_function&& ) = default;
1171
1172 ~move_only_function() = default;
1173
1174 move_only_function& operator=( move_only_function&& rhs )
1175 {
1176 if( this != &rhs )
1177 {
1178 this->base::operator=( static_cast<base&&>( rhs ) );
1179 }
1180 return *this;
1181 }
1182
1183 move_only_function& operator=( std::nullptr_t ) noexcept
1184 {
1185 this->base::operator=( nullptr );
1186 return *this;
1187 }
1188
1189 template<class F> move_only_function& operator=( F&& f )
1190 {
1191 move_only_function( std::forward<F>( f ) ).swap( *this );
1192 return *this;
1193 }
1194
1195 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1196 {
1197 return fn.invoke_ == nullptr;
1198 }
1199
1200 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1201 {
1202 return !( fn == nullptr );
1203 }
1204
1205 void swap( move_only_function& rhs ) noexcept
1206 {
1207 if( this != &rhs )
1208 {
1209 this->base::swap( rhs );
1210 }
1211 }
1212
1213 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1214 {
1215 lhs.swap( rhs );
1216 }
1217
1218 explicit operator bool() const noexcept
1219 {
1220 return static_cast<bool>( *static_cast<base const*>( this ) );
1221 }
1222
1223 R operator()( Args... args ) const &&
1224 {
1225 return this->invoke_( this->s_, std::forward<Args>( args )... );
1226 }
1227 };
1228
1229 #if defined(__cpp_noexcept_function_type)
1230
1231 template<class R, class ...Args>
1232 class move_only_function<R( Args... ) noexcept> : detail::move_only_function_base<detail::ref_quals::none, false, true, R, Args...>
1233 {
1234 private:
1235
1236 template<detail::ref_quals, bool, bool, class, class ...>
1237 friend struct detail::move_only_function_base;
1238
1239 using base = detail::move_only_function_base<detail::ref_quals::none, false, true, R, Args...>;
1240
1241 public:
1242
1243 move_only_function() noexcept
1244 {
1245 }
1246
1247 move_only_function( std::nullptr_t ) noexcept
1248 : move_only_function()
1249 {
1250 }
1251
1252 template<
1253 class F,
1254 class VT = decay_t<F>,
1255 enable_if_t<
1256 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1257 !detail::is_in_place_type_t<VT>::value &&
1258 detail::is_callable_from<detail::ref_quals::none, false, true, VT, R, Args...>::value,
1259 int> = 0
1260 >
1261 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1262 {
1263 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1264 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1265 }
1266
1267 template<
1268 class T, class ...CArgs,
1269 enable_if_t<
1270 std::is_constructible<T, CArgs...>::value &&
1271 detail::is_callable_from<detail::ref_quals::none, false, true, T, R, Args...>::value,
1272 int> = 0
1273 >
1274 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1275 {
1276 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1277 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1278 }
1279
1280 template<
1281 class T, class U, class ...CArgs,
1282 enable_if_t<
1283 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1284 detail::is_callable_from<detail::ref_quals::none, false, true, T, R, Args...>::value,
1285 int> = 0
1286 >
1287 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1288 {
1289 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1290 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1291 }
1292
1293 move_only_function( move_only_function const& ) = delete;
1294 move_only_function( move_only_function&& ) = default;
1295
1296 ~move_only_function() = default;
1297
1298 move_only_function& operator=( move_only_function&& rhs )
1299 {
1300 if( this != &rhs )
1301 {
1302 this->base::operator=( static_cast<base&&>( rhs ) );
1303 }
1304 return *this;
1305 }
1306
1307 move_only_function& operator=( std::nullptr_t ) noexcept
1308 {
1309 this->base::operator=( nullptr );
1310 return *this;
1311 }
1312
1313 template<class F> move_only_function& operator=( F&& f )
1314 {
1315 move_only_function( std::forward<F>( f ) ).swap( *this );
1316 return *this;
1317 }
1318
1319 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1320 {
1321 return fn.invoke_ == nullptr;
1322 }
1323
1324 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1325 {
1326 return !( fn == nullptr );
1327 }
1328
1329 void swap( move_only_function& rhs ) noexcept
1330 {
1331 if( this != &rhs )
1332 {
1333 this->base::swap( rhs );
1334 }
1335 }
1336
1337 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1338 {
1339 lhs.swap( rhs );
1340 }
1341
1342 explicit operator bool() const noexcept
1343 {
1344 return static_cast<bool>( *static_cast<base const*>( this ) );
1345 }
1346
1347 R operator()( Args... args ) noexcept
1348 {
1349 return this->invoke_( this->s_, std::forward<Args>( args )... );
1350 }
1351 };
1352
1353 template<class R, class ...Args>
1354 class move_only_function<R( Args... ) & noexcept> : detail::move_only_function_base<detail::ref_quals::lvalue, false, true, R, Args...>
1355 {
1356 private:
1357
1358 template<detail::ref_quals, bool, bool, class, class ...>
1359 friend struct detail::move_only_function_base;
1360
1361 using base = detail::move_only_function_base<detail::ref_quals::lvalue, false, true, R, Args...>;
1362
1363 public:
1364
1365 move_only_function() noexcept
1366 {
1367 }
1368
1369 move_only_function( std::nullptr_t ) noexcept
1370 : move_only_function()
1371 {
1372 }
1373
1374 template<
1375 class F,
1376 class VT = decay_t<F>,
1377 enable_if_t<
1378 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1379 !detail::is_in_place_type_t<VT>::value &&
1380 detail::is_callable_from<detail::ref_quals::lvalue, false, true, VT, R, Args...>::value,
1381 int> = 0
1382 >
1383 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1384 {
1385 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1386 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1387 }
1388
1389 template<
1390 class T, class ...CArgs,
1391 enable_if_t<
1392 std::is_constructible<T, CArgs...>::value &&
1393 detail::is_callable_from<detail::ref_quals::lvalue, false, true, T, R, Args...>::value,
1394 int> = 0
1395 >
1396 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1397 {
1398 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1399 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1400 }
1401
1402 template<
1403 class T, class U, class ...CArgs,
1404 enable_if_t<
1405 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1406 detail::is_callable_from<detail::ref_quals::lvalue, false, true, T, R, Args...>::value,
1407 int> = 0
1408 >
1409 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1410 {
1411 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1412 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1413 }
1414
1415 move_only_function( move_only_function const& ) = delete;
1416 move_only_function( move_only_function&& ) = default;
1417
1418 ~move_only_function() = default;
1419
1420 move_only_function& operator=( move_only_function&& rhs )
1421 {
1422 if( this != &rhs )
1423 {
1424 this->base::operator=( static_cast<base&&>( rhs ) );
1425 }
1426 return *this;
1427 }
1428
1429 move_only_function& operator=( std::nullptr_t ) noexcept
1430 {
1431 this->base::operator=( nullptr );
1432 return *this;
1433 }
1434
1435 template<class F> move_only_function& operator=( F&& f )
1436 {
1437 move_only_function( std::forward<F>( f ) ).swap( *this );
1438 return *this;
1439 }
1440
1441 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1442 {
1443 return fn.invoke_ == nullptr;
1444 }
1445
1446 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1447 {
1448 return !( fn == nullptr );
1449 }
1450
1451 void swap( move_only_function& rhs ) noexcept
1452 {
1453 if( this != &rhs )
1454 {
1455 this->base::swap( rhs );
1456 }
1457 }
1458
1459 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1460 {
1461 lhs.swap( rhs );
1462 }
1463
1464 explicit operator bool() const noexcept
1465 {
1466 return static_cast<bool>( *static_cast<base const*>( this ) );
1467 }
1468
1469 R operator()( Args... args ) & noexcept
1470 {
1471 return this->invoke_( this->s_, std::forward<Args>( args )... );
1472 }
1473 };
1474
1475 template<class R, class ...Args>
1476 class move_only_function<R( Args... ) && noexcept> : detail::move_only_function_base<detail::ref_quals::rvalue, false, true, R, Args...>
1477 {
1478 private:
1479
1480 template<detail::ref_quals, bool, bool, class, class ...>
1481 friend struct detail::move_only_function_base;
1482
1483 using base = detail::move_only_function_base<detail::ref_quals::rvalue, false, true, R, Args...>;
1484
1485 public:
1486
1487 move_only_function() noexcept
1488 {
1489 }
1490
1491 move_only_function( std::nullptr_t ) noexcept
1492 : move_only_function()
1493 {
1494 }
1495
1496 template<
1497 class F,
1498 class VT = decay_t<F>,
1499 enable_if_t<
1500 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1501 !detail::is_in_place_type_t<VT>::value &&
1502 detail::is_callable_from<detail::ref_quals::rvalue, false, true, VT, R, Args...>::value,
1503 int> = 0
1504 >
1505 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1506 {
1507 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1508 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1509 }
1510
1511 template<
1512 class T, class ...CArgs,
1513 enable_if_t<
1514 std::is_constructible<T, CArgs...>::value &&
1515 detail::is_callable_from<detail::ref_quals::rvalue, false, true, T, R, Args...>::value,
1516 int> = 0
1517 >
1518 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1519 {
1520 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1521 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1522 }
1523
1524 template<
1525 class T, class U, class ...CArgs,
1526 enable_if_t<
1527 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1528 detail::is_callable_from<detail::ref_quals::rvalue, false, true, T, R, Args...>::value,
1529 int> = 0
1530 >
1531 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1532 {
1533 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1534 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1535 }
1536
1537 move_only_function( move_only_function const& ) = delete;
1538 move_only_function( move_only_function&& ) = default;
1539
1540 ~move_only_function() = default;
1541
1542 move_only_function& operator=( move_only_function&& rhs )
1543 {
1544 if( this != &rhs )
1545 {
1546 this->base::operator=( static_cast<base&&>( rhs ) );
1547 }
1548 return *this;
1549 }
1550
1551 move_only_function& operator=( std::nullptr_t ) noexcept
1552 {
1553 this->base::operator=( nullptr );
1554 return *this;
1555 }
1556
1557 template<class F> move_only_function& operator=( F&& f )
1558 {
1559 move_only_function( std::forward<F>( f ) ).swap( *this );
1560 return *this;
1561 }
1562
1563 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1564 {
1565 return fn.invoke_ == nullptr;
1566 }
1567
1568 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1569 {
1570 return !( fn == nullptr );
1571 }
1572
1573 void swap( move_only_function& rhs ) noexcept
1574 {
1575 if( this != &rhs )
1576 {
1577 this->base::swap( rhs );
1578 }
1579 }
1580
1581 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1582 {
1583 lhs.swap( rhs );
1584 }
1585
1586 explicit operator bool() const noexcept
1587 {
1588 return static_cast<bool>( *static_cast<base const*>( this ) );
1589 }
1590
1591 R operator()( Args... args ) && noexcept
1592 {
1593 return this->invoke_( this->s_, std::forward<Args>( args )... );
1594 }
1595 };
1596
1597 template<class R, class ...Args>
1598 class move_only_function<R( Args... ) const noexcept> : detail::move_only_function_base<detail::ref_quals::none, true, true, R, Args...>
1599 {
1600 private:
1601
1602 template<detail::ref_quals, bool, bool, class, class ...>
1603 friend struct detail::move_only_function_base;
1604
1605 using base = detail::move_only_function_base<detail::ref_quals::none, true, true, R, Args...>;
1606
1607 public:
1608
1609 move_only_function() noexcept
1610 {
1611 }
1612
1613 move_only_function( std::nullptr_t ) noexcept
1614 : move_only_function()
1615 {
1616 }
1617
1618 template<
1619 class F,
1620 class VT = decay_t<F>,
1621 enable_if_t<
1622 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1623 !detail::is_in_place_type_t<VT>::value &&
1624 detail::is_callable_from<detail::ref_quals::none, true, true, VT, R, Args...>::value,
1625 int> = 0
1626 >
1627 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1628 {
1629 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1630 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1631 }
1632
1633 template<
1634 class T, class ...CArgs,
1635 enable_if_t<
1636 std::is_constructible<T, CArgs...>::value &&
1637 detail::is_callable_from<detail::ref_quals::none, true, true, T, R, Args...>::value,
1638 int> = 0
1639 >
1640 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1641 {
1642 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1643 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1644 }
1645
1646 template<
1647 class T, class U, class ...CArgs,
1648 enable_if_t<
1649 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1650 detail::is_callable_from<detail::ref_quals::none, true, true, T, R, Args...>::value,
1651 int> = 0
1652 >
1653 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1654 {
1655 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1656 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1657 }
1658
1659 move_only_function( move_only_function const& ) = delete;
1660 move_only_function( move_only_function&& ) = default;
1661
1662 ~move_only_function() = default;
1663
1664 move_only_function& operator=( move_only_function&& rhs )
1665 {
1666 if( this != &rhs )
1667 {
1668 this->base::operator=( static_cast<base&&>( rhs ) );
1669 }
1670 return *this;
1671 }
1672
1673 move_only_function& operator=( std::nullptr_t ) noexcept
1674 {
1675 this->base::operator=( nullptr );
1676 return *this;
1677 }
1678
1679 template<class F> move_only_function& operator=( F&& f )
1680 {
1681 move_only_function( std::forward<F>( f ) ).swap( *this );
1682 return *this;
1683 }
1684
1685 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1686 {
1687 return fn.invoke_ == nullptr;
1688 }
1689
1690 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1691 {
1692 return !( fn == nullptr );
1693 }
1694
1695 void swap( move_only_function& rhs ) noexcept
1696 {
1697 if( this != &rhs )
1698 {
1699 this->base::swap( rhs );
1700 }
1701 }
1702
1703 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1704 {
1705 lhs.swap( rhs );
1706 }
1707
1708 explicit operator bool() const noexcept
1709 {
1710 return static_cast<bool>( *static_cast<base const*>( this ) );
1711 }
1712
1713 R operator()( Args... args ) const noexcept
1714 {
1715 return this->invoke_( this->s_, std::forward<Args>( args )... );
1716 }
1717 };
1718
1719 template<class R, class ...Args>
1720 class move_only_function<R( Args... ) const& noexcept> : detail::move_only_function_base<detail::ref_quals::lvalue, true, true, R, Args...>
1721 {
1722 private:
1723
1724 template<detail::ref_quals, bool, bool, class, class ...>
1725 friend struct detail::move_only_function_base;
1726
1727 using base = detail::move_only_function_base<detail::ref_quals::lvalue, true, true, R, Args...>;
1728
1729 public:
1730
1731 move_only_function() noexcept
1732 {
1733 }
1734
1735 move_only_function( std::nullptr_t ) noexcept
1736 : move_only_function()
1737 {
1738 }
1739
1740 template<
1741 class F,
1742 class VT = decay_t<F>,
1743 enable_if_t<
1744 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1745 !detail::is_in_place_type_t<VT>::value &&
1746 detail::is_callable_from<detail::ref_quals::lvalue, true, true, VT, R, Args...>::value,
1747 int> = 0
1748 >
1749 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1750 {
1751 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1752 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1753 }
1754
1755 template<
1756 class T, class ...CArgs,
1757 enable_if_t<
1758 std::is_constructible<T, CArgs...>::value &&
1759 detail::is_callable_from<detail::ref_quals::lvalue, true, true, T, R, Args...>::value,
1760 int> = 0
1761 >
1762 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1763 {
1764 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1765 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1766 }
1767
1768 template<
1769 class T, class U, class ...CArgs,
1770 enable_if_t<
1771 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1772 detail::is_callable_from<detail::ref_quals::lvalue, true, true, T, R, Args...>::value,
1773 int> = 0
1774 >
1775 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1776 {
1777 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1778 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1779 }
1780
1781 move_only_function( move_only_function const& ) = delete;
1782 move_only_function( move_only_function&& ) = default;
1783
1784 ~move_only_function() = default;
1785
1786 move_only_function& operator=( move_only_function&& rhs )
1787 {
1788 if( this != &rhs )
1789 {
1790 this->base::operator=( static_cast<base&&>( rhs ) );
1791 }
1792 return *this;
1793 }
1794
1795 move_only_function& operator=( std::nullptr_t ) noexcept
1796 {
1797 this->base::operator=( nullptr );
1798 return *this;
1799 }
1800
1801 template<class F> move_only_function& operator=( F&& f )
1802 {
1803 move_only_function( std::forward<F>( f ) ).swap( *this );
1804 return *this;
1805 }
1806
1807 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1808 {
1809 return fn.invoke_ == nullptr;
1810 }
1811
1812 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1813 {
1814 return !( fn == nullptr );
1815 }
1816
1817 void swap( move_only_function& rhs ) noexcept
1818 {
1819 if( this != &rhs )
1820 {
1821 this->base::swap( rhs );
1822 }
1823 }
1824
1825 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1826 {
1827 lhs.swap( rhs );
1828 }
1829
1830 explicit operator bool() const noexcept
1831 {
1832 return static_cast<bool>( *static_cast<base const*>( this ) );
1833 }
1834
1835 R operator()( Args... args ) const& noexcept
1836 {
1837 return this->invoke_( this->s_, std::forward<Args>( args )... );
1838 }
1839 };
1840
1841 template<class R, class ...Args>
1842 class move_only_function<R( Args... ) const&& noexcept> : detail::move_only_function_base<detail::ref_quals::rvalue, true, true, R, Args...>
1843 {
1844 private:
1845
1846 template<detail::ref_quals, bool, bool, class, class ...>
1847 friend struct detail::move_only_function_base;
1848
1849 using base = detail::move_only_function_base<detail::ref_quals::rvalue, true, true, R, Args...>;
1850
1851 public:
1852
1853 move_only_function() noexcept
1854 {
1855 }
1856
1857 move_only_function( std::nullptr_t ) noexcept
1858 : move_only_function()
1859 {
1860 }
1861
1862 template<
1863 class F,
1864 class VT = decay_t<F>,
1865 enable_if_t<
1866 !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
1867 !detail::is_in_place_type_t<VT>::value &&
1868 detail::is_callable_from<detail::ref_quals::rvalue, true, true, VT, R, Args...>::value,
1869 int> = 0
1870 >
1871 move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
1872 {
1873 if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
1874 base::init( type_identity<VT>{}, std::forward<F>( f ) );
1875 }
1876
1877 template<
1878 class T, class ...CArgs,
1879 enable_if_t<
1880 std::is_constructible<T, CArgs...>::value &&
1881 detail::is_callable_from<detail::ref_quals::rvalue, true, true, T, R, Args...>::value,
1882 int> = 0
1883 >
1884 explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
1885 {
1886 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1887 base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
1888 }
1889
1890 template<
1891 class T, class U, class ...CArgs,
1892 enable_if_t<
1893 std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
1894 detail::is_callable_from<detail::ref_quals::rvalue, true, true, T, R, Args...>::value,
1895 int> = 0
1896 >
1897 explicit move_only_function( in_place_type_t<T>, std::initializer_list<U> il, CArgs&& ... args ) noexcept( detail::nothrow_init<T, std::initializer_list<U>&, CArgs...>::value )
1898 {
1899 static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
1900 base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
1901 }
1902
1903 move_only_function( move_only_function const& ) = delete;
1904 move_only_function( move_only_function&& ) = default;
1905
1906 ~move_only_function() = default;
1907
1908 move_only_function& operator=( move_only_function&& rhs )
1909 {
1910 if( this != &rhs )
1911 {
1912 this->base::operator=( static_cast<base&&>( rhs ) );
1913 }
1914 return *this;
1915 }
1916
1917 move_only_function& operator=( std::nullptr_t ) noexcept
1918 {
1919 this->base::operator=( nullptr );
1920 return *this;
1921 }
1922
1923 template<class F> move_only_function& operator=( F&& f )
1924 {
1925 move_only_function( std::forward<F>( f ) ).swap( *this );
1926 return *this;
1927 }
1928
1929 friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
1930 {
1931 return fn.invoke_ == nullptr;
1932 }
1933
1934 friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
1935 {
1936 return !( fn == nullptr );
1937 }
1938
1939 void swap( move_only_function& rhs ) noexcept
1940 {
1941 if( this != &rhs )
1942 {
1943 this->base::swap( rhs );
1944 }
1945 }
1946
1947 friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
1948 {
1949 lhs.swap( rhs );
1950 }
1951
1952 explicit operator bool() const noexcept
1953 {
1954 return static_cast<bool>( *static_cast<base const*>( this ) );
1955 }
1956
1957 R operator()( Args... args ) const&& noexcept
1958 {
1959 return this->invoke_( this->s_, std::forward<Args>( args )... );
1960 }
1961 };
1962
1963 #endif
1964
1965 }
1966 }
1967
1968 #if BOOST_WORKAROUND(BOOST_GCC, >= 6 * 10000)
1969 # pragma GCC diagnostic pop
1970 #endif
1971
1972 #endif