Back to home page

EIC code displayed by LXR

 
 

    


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 // Copyright 2025 Christian Mazakas.
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
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     // we want SBO to be large enough to store a type which can be used for delegation purposes
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         // to properly swap with storages, we need to treat the destination storage
0317         // the same as the source storage, which means that we need to use the
0318         // source manager_'s move operation
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                 // destruct the element here because move construction will leave the container empty
0402                 // outside of this function
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 /* is_function */, 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 /* is_function */, 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 } // namespace detail
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 } // namespace compat
1966 } // namespace boost
1967 
1968 #if BOOST_WORKAROUND(BOOST_GCC, >= 6 * 10000)
1969 #   pragma GCC diagnostic pop
1970 #endif
1971 
1972 #endif // #ifndef BOOST_COMPAT_MOVE_ONLY_FUNCTION_HPP_INCLUDED