| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972 |
- #ifndef BOOST_COMPAT_MOVE_ONLY_FUNCTION_HPP_INCLUDED
- #define BOOST_COMPAT_MOVE_ONLY_FUNCTION_HPP_INCLUDED
- // Copyright 2025 Christian Mazakas.
- // Distributed under the Boost Software License, Version 1.0.
- // https://www.boost.org/LICENSE_1_0.txt
- #include <boost/compat/invoke.hpp>
- #include <boost/compat/type_traits.hpp>
- #include <boost/assert.hpp>
- #include <cstddef>
- #include <initializer_list>
- #include <type_traits>
- #include <boost/config/workaround.hpp>
- #if BOOST_WORKAROUND(BOOST_GCC, >= 6 * 10000)
- # pragma GCC diagnostic push
- # pragma GCC diagnostic ignored "-Wnonnull-compare"
- # pragma GCC diagnostic ignored "-Waddress"
- #endif
- namespace boost {
- namespace compat {
- template<class... S>
- class move_only_function;
- template< class T >
- struct in_place_type_t { explicit in_place_type_t() = default; };
- namespace detail
- {
- union pointers
- {
- void* pobj_;
- void ( *pfn_ )();
- };
- struct storage
- {
- // we want SBO to be large enough to store a type which can be used for delegation purposes
- struct delegate { void( storage::*pmfn_ )(); storage* pobj_; };
- union
- {
- void* pobj_;
- void ( *pfn_ )();
- alignas(delegate) unsigned char buf_[ sizeof(delegate) ];
- };
- template<class T>
- constexpr static bool use_sbo() noexcept
- {
- return sizeof( T ) <= sizeof( storage ) && alignof( T ) <= alignof( storage ) && std::is_nothrow_move_constructible<T>::value;
- }
- void* addr() noexcept
- {
- return buf_;
- }
- };
- template<class>
- struct is_polymorphic_function : std::false_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... )>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) &>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) &&>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) const>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) const&>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) const&&>> : std::true_type
- {
- };
- #if defined(__cpp_noexcept_function_type)
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) noexcept>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) & noexcept>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) && noexcept>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) const noexcept>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) const& noexcept>> : std::true_type
- {
- };
- template<class R, class ...Args>
- struct is_polymorphic_function<move_only_function<R( Args... ) const&& noexcept>> : std::true_type
- {
- };
- #endif
- template<class T>
- using is_move_only_function = is_polymorphic_function<T>;
- template<class T>
- struct is_in_place_type_t : std::false_type
- {
- };
- template<class T>
- struct is_in_place_type_t<in_place_type_t<T>> : std::true_type
- {
- };
- template<class T, class ...Args>
- struct nothrow_init
- {
- constexpr static bool const value = ( storage::use_sbo<T>() && std::is_nothrow_constructible<T, Args...>::value ) || false;
- };
- enum class ref_quals { none, lvalue, rvalue };
- template<ref_quals RQ, bool Const, bool NoEx, class VT, class R, class ...Args>
- struct is_callable_from;
- template<ref_quals RQ, bool Const, class VT, class R, class ...Args>
- struct is_callable_from<RQ, Const, true, VT, R, Args...>
- {
- using cv_VT = conditional_t<Const, add_const_t<VT>, VT>;
- using cv_ref_VT = conditional_t<
- RQ == ref_quals::none, cv_VT,
- conditional_t<
- RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
- >
- >;
- using inv_quals_VT = conditional_t<
- RQ == ref_quals::none, add_lvalue_reference_t<cv_VT>,
- conditional_t<
- RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
- >
- >;
- constexpr static bool const value =
- is_nothrow_invocable_r<R, cv_ref_VT, Args...>::value &&
- is_nothrow_invocable_r<R, inv_quals_VT, Args...>::value;
- };
- template<ref_quals RQ, bool Const, class VT, class R, class ...Args>
- struct is_callable_from<RQ, Const, false, VT, R, Args...>
- {
- using cv_VT = conditional_t<Const, add_const_t<VT>, VT>;
- using cv_ref_VT = conditional_t<
- RQ == ref_quals::none, cv_VT,
- conditional_t<
- RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
- >
- >;
- using inv_quals_VT = conditional_t<
- RQ == ref_quals::none, add_lvalue_reference_t<cv_VT>,
- conditional_t<
- RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_VT>, add_lvalue_reference_t<cv_VT>
- >
- >;
- constexpr static bool const value =
- is_invocable_r<R, cv_ref_VT, Args...>::value &&
- is_invocable_r<R, inv_quals_VT, Args...>::value;
- };
- inline std::nullptr_t get_first_arg()
- {
- return nullptr;
- }
- template<class T, class ...CArgs>
- T&& get_first_arg( T&& t, CArgs&& ... )
- {
- return std::forward<T>( t );
- }
- template<class ...Ts>
- bool is_nullary_arg( Ts&&... )
- {
- return false;
- }
- template<
- class F, class VT = decay_t<F>,
- enable_if_t<
- std::is_member_pointer<VT>::value ||
- is_move_only_function<VT>::value,
- int> = 0
- >
- bool is_nullary_arg( F&& f )
- {
- return f == nullptr;
- }
- template<
- class F, class VT = decay_t<F>,
- enable_if_t<
- std::is_function<remove_pointer_t<VT>>::value,
- int> = 0
- >
- bool is_nullary_arg( F f )
- {
- return f == nullptr;
- }
- template<bool NoEx, class R, class ...Args>
- struct mo_invoke_function_holder
- {
- static R invoke_function( storage s, Args&&... args) noexcept( NoEx )
- {
- auto f = reinterpret_cast<R(*)( Args... )>( s.pfn_ );
- return compat::invoke_r<R>( f, std::forward<Args>( args )... );
- }
- };
- template<ref_quals RQ, bool Const, bool NoEx, class F, class R, class ...Args>
- struct mo_invoke_object_holder
- {
- static R invoke_object( storage s, Args&&... args ) noexcept( NoEx )
- {
- using T = remove_reference_t<F>;
- using cv_T = conditional_t<Const, add_const_t<T>, T>;
- using cv_ref_T = conditional_t<
- RQ == ref_quals::none, add_lvalue_reference_t<cv_T>,
- conditional_t<
- RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_T>, add_lvalue_reference_t<cv_T>
- >
- >;
- return compat::invoke_r<R>( static_cast<cv_ref_T>( *static_cast<cv_T*>( s.pobj_ ) ), std::forward<Args>( args )... );
- }
- };
- template<ref_quals RQ, bool Const, bool NoEx, class F, class R, class ...Args>
- struct mo_invoke_local_holder
- {
- static R invoke_local( storage s, Args&&... args ) noexcept( NoEx )
- {
- using T = remove_reference_t<F>;
- using cv_T = conditional_t<Const, add_const_t<T>, T>;
- using cv_ref_T = conditional_t<
- RQ == ref_quals::none, add_lvalue_reference_t<cv_T>,
- conditional_t<
- RQ == ref_quals::rvalue, add_rvalue_reference_t<cv_T>, add_lvalue_reference_t<cv_T>
- >
- >;
- return compat::invoke_r<R>( static_cast<cv_ref_T>( *static_cast<cv_T*>( s.addr() ) ), std::forward<Args>( args )... );
- }
- };
- enum class op_type { move, destroy };
- template <ref_quals RQ, bool Const, bool NoEx, class R, class ...Args>
- struct move_only_function_base
- {
- move_only_function_base() = default;
- move_only_function_base( move_only_function_base&& rhs ) noexcept
- {
- manager_ = rhs.manager_;
- manager_( op_type::move, s_, &rhs.s_ );
- invoke_ = rhs.invoke_;
- rhs.invoke_ = nullptr;
- rhs.manager_ = &manage_empty;
- }
- ~move_only_function_base()
- {
- destroy();
- }
- void swap( move_only_function_base& rhs ) noexcept
- {
- // to properly swap with storages, we need to treat the destination storage
- // the same as the source storage, which means that we need to use the
- // source manager_'s move operation
- storage s;
- rhs.manager_( op_type::move, s, &rhs.s_ );
- manager_( op_type::move, rhs.s_, &s_ );
- rhs.manager_( op_type::move, s_, &s );
- std::swap( manager_, rhs.manager_ );
- std::swap( invoke_, rhs.invoke_ );
- }
- move_only_function_base& operator=( move_only_function_base&& rhs )
- {
- destroy();
- manager_ = rhs.manager_;
- manager_( op_type::move, s_, &rhs.s_ );
- invoke_ = rhs.invoke_;
- rhs.invoke_ = nullptr;
- rhs.manager_ = &manage_empty;
- return *this;
- }
- move_only_function_base& operator=( std::nullptr_t ) noexcept
- {
- destroy();
- invoke_ = nullptr;
- manager_ = &manage_empty;
- return *this;
- }
- static void manage_empty( op_type, detail::storage&, detail::storage* )
- {
- }
- static void manage_function( op_type op, detail::storage& s, detail::storage* src )
- {
- switch( op )
- {
- case op_type::move:
- s.pfn_ = src->pfn_;
- src->pfn_ = nullptr;
- break;
- default:
- break;
- }
- }
- template<class VT>
- static void manage_object( op_type op, detail::storage& s, detail::storage* src )
- {
- switch( op )
- {
- case op_type::destroy:
- delete static_cast<VT*>( s.pobj_ );
- break;
- case op_type::move:
- s.pobj_ = src->pobj_;
- src->pobj_ = nullptr;
- break;
- default:
- break;
- }
- }
- template<class VT>
- static void manage_local( op_type op, detail::storage& s, detail::storage* src )
- {
- switch( op )
- {
- case op_type::destroy:
- static_cast<VT*>( s.addr() )->~VT();
- break;
- case op_type::move:
- {
- VT* p = static_cast<VT*>( src->addr() );
- new(s.addr()) VT( std::move( *p ) );
- // destruct the element here because move construction will leave the container empty
- // outside of this function
- p->~VT();
- break;
- }
- default:
- break;
- }
- }
- template <ref_quals RQ2, bool Const2, bool NoEx2, class R2, class ...Args2>
- void
- move_from_compatible_base( move_only_function_base<RQ2, Const2, NoEx2, R2, Args2...>& base )
- {
- using polymorphic_base = move_only_function_base<RQ2, Const2, NoEx2, R2, Args2...>;
- manager_ = base.manager_;
- manager_( op_type::move, s_, &base.s_ );
- invoke_ = base.invoke_;
- base.invoke_ = nullptr;
- base.manager_ = &polymorphic_base::manage_empty;
- }
- template<class F>
- void base_init( std::true_type, F&& f )
- {
- move_from_compatible_base( f );
- }
- template<class ...F>
- void base_init( std::false_type, F&&... )
- {
- }
- template<class VT, class ...CArgs>
- void init( std::false_type /* is_function */, CArgs&& ...args )
- {
- if( is_polymorphic_function<VT>::value )
- {
- base_init( is_polymorphic_function<VT>{}, std::forward<CArgs>( args )... );
- return;
- }
- if( !storage::use_sbo<VT>() )
- {
- s_.pobj_ = new VT( std::forward<CArgs>( args )... );
- invoke_ = &mo_invoke_object_holder<RQ, Const, NoEx, VT, R, Args...>::invoke_object;
- manager_ = &manage_object<VT>;
- }
- else
- {
- new( s_.addr() ) VT( std::forward<CArgs>( args )... );
- invoke_ = &mo_invoke_local_holder<RQ, Const, NoEx, VT, R, Args...>::invoke_local;
- manager_ = &manage_local<VT>;
- }
- }
- template<class VT, class ...CArgs>
- void init( std::true_type /* is_function */, CArgs ...args )
- {
- R (*pfn)( Args... ) = get_first_arg( args... );
- s_.pfn_ = reinterpret_cast<void(*)()>( pfn );
- invoke_ = &detail::mo_invoke_function_holder<NoEx, R, Args...>::invoke_function;
- manager_ = &manage_function;
- }
- template <class VT, class ...CArgs>
- void init( type_identity<VT>, CArgs&& ...args )
- {
- init<VT>( std::is_function<remove_pointer_t<VT>>(), std::forward<CArgs>( args )... );
- }
- void destroy()
- {
- manager_( op_type::destroy, s_, nullptr );
- }
- explicit operator bool() const noexcept
- {
- return invoke_ != nullptr;
- }
- detail::storage s_;
- #if defined(__cpp_noexcept_function_type)
- R ( *invoke_ )( detail::storage, Args&&... ) noexcept( NoEx ) = nullptr;
- #else
- R ( *invoke_ )( detail::storage, Args&&... ) = nullptr;
- #endif
- void ( *manager_ )( op_type, detail::storage&, detail::storage* ) = &manage_empty;
- };
- } // namespace detail
- template<class R, class ...Args>
- class move_only_function<R( Args... )> : detail::move_only_function_base<detail::ref_quals::none, false, false, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::none, false, false, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::none, false, false, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, false, false, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, false, false, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args )
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) &> : detail::move_only_function_base<detail::ref_quals::lvalue, false, false, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::lvalue, false, false, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, false, false, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, false, false, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, false, false, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) &
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) &&> : detail::move_only_function_base<detail::ref_quals::rvalue, false, false, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::rvalue, false, false, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, false, false, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, false, false, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, false, false, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) &&
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) const> : detail::move_only_function_base<detail::ref_quals::none, true, false, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::none, true, false, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::none, true, false, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, true, false, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, true, false, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) const
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) const&> : detail::move_only_function_base<detail::ref_quals::lvalue, true, false, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::lvalue, true, false, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, true, false, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, true, false, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, true, false, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) const &
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) const&&> : detail::move_only_function_base<detail::ref_quals::rvalue, true, false, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::rvalue, true, false, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, true, false, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, true, false, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, true, false, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) const &&
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- #if defined(__cpp_noexcept_function_type)
- template<class R, class ...Args>
- class move_only_function<R( Args... ) noexcept> : detail::move_only_function_base<detail::ref_quals::none, false, true, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::none, false, true, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::none, false, true, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, false, true, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, false, true, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) noexcept
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) & noexcept> : detail::move_only_function_base<detail::ref_quals::lvalue, false, true, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::lvalue, false, true, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, false, true, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, false, true, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, false, true, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) & noexcept
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) && noexcept> : detail::move_only_function_base<detail::ref_quals::rvalue, false, true, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::rvalue, false, true, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, false, true, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, false, true, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, false, true, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) && noexcept
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) const noexcept> : detail::move_only_function_base<detail::ref_quals::none, true, true, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::none, true, true, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::none, true, true, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, true, true, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::none, true, true, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) const noexcept
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) const& noexcept> : detail::move_only_function_base<detail::ref_quals::lvalue, true, true, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::lvalue, true, true, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, true, true, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, true, true, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::lvalue, true, true, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) const& noexcept
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- template<class R, class ...Args>
- class move_only_function<R( Args... ) const&& noexcept> : detail::move_only_function_base<detail::ref_quals::rvalue, true, true, R, Args...>
- {
- private:
- template<detail::ref_quals, bool, bool, class, class ...>
- friend struct detail::move_only_function_base;
- using base = detail::move_only_function_base<detail::ref_quals::rvalue, true, true, R, Args...>;
- public:
- move_only_function() noexcept
- {
- }
- move_only_function( std::nullptr_t ) noexcept
- : move_only_function()
- {
- }
- template<
- class F,
- class VT = decay_t<F>,
- enable_if_t<
- !std::is_same<move_only_function, remove_cvref_t<F>>::value &&
- !detail::is_in_place_type_t<VT>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, true, true, VT, R, Args...>::value,
- int> = 0
- >
- move_only_function( F&& f ) noexcept( detail::nothrow_init<VT, F>::value )
- {
- if( detail::is_nullary_arg( std::forward<F>( f ) ) ) return;
- base::init( type_identity<VT>{}, std::forward<F>( f ) );
- }
- template<
- class T, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, true, true, T, R, Args...>::value,
- int> = 0
- >
- explicit move_only_function( in_place_type_t<T>, CArgs&& ... args ) noexcept( detail::nothrow_init<T, CArgs...>::value )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, std::forward<CArgs>( args )... );
- }
- template<
- class T, class U, class ...CArgs,
- enable_if_t<
- std::is_constructible<T, std::initializer_list<U>&, CArgs...>::value &&
- detail::is_callable_from<detail::ref_quals::rvalue, true, true, T, R, Args...>::value,
- int> = 0
- >
- 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 )
- {
- static_assert( std::is_same<T, decay_t<T>>::value, "T and `decay_t<T>` must be the same" );
- base::init( type_identity<T>{}, il, std::forward<CArgs>( args )... );
- }
- move_only_function( move_only_function const& ) = delete;
- move_only_function( move_only_function&& ) = default;
- ~move_only_function() = default;
- move_only_function& operator=( move_only_function&& rhs )
- {
- if( this != &rhs )
- {
- this->base::operator=( static_cast<base&&>( rhs ) );
- }
- return *this;
- }
- move_only_function& operator=( std::nullptr_t ) noexcept
- {
- this->base::operator=( nullptr );
- return *this;
- }
- template<class F> move_only_function& operator=( F&& f )
- {
- move_only_function( std::forward<F>( f ) ).swap( *this );
- return *this;
- }
- friend bool operator==( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return fn.invoke_ == nullptr;
- }
- friend bool operator!=( move_only_function const& fn, std::nullptr_t ) noexcept
- {
- return !( fn == nullptr );
- }
- void swap( move_only_function& rhs ) noexcept
- {
- if( this != &rhs )
- {
- this->base::swap( rhs );
- }
- }
- friend void swap( move_only_function& lhs, move_only_function& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- explicit operator bool() const noexcept
- {
- return static_cast<bool>( *static_cast<base const*>( this ) );
- }
- R operator()( Args... args ) const&& noexcept
- {
- return this->invoke_( this->s_, std::forward<Args>( args )... );
- }
- };
- #endif
- } // namespace compat
- } // namespace boost
- #if BOOST_WORKAROUND(BOOST_GCC, >= 6 * 10000)
- # pragma GCC diagnostic pop
- #endif
- #endif // #ifndef BOOST_COMPAT_MOVE_ONLY_FUNCTION_HPP_INCLUDED
|