1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642 |
- #ifndef BOOST_SCOPE_UNIQUE_RESOURCE_HPP_INCLUDED_
- #define BOOST_SCOPE_UNIQUE_RESOURCE_HPP_INCLUDED_
- #include <new>
- #include <type_traits>
- #include <boost/core/addressof.hpp>
- #include <boost/core/invoke_swap.hpp>
- #include <boost/scope/unique_resource_fwd.hpp>
- #include <boost/scope/detail/config.hpp>
- #include <boost/scope/detail/compact_storage.hpp>
- #include <boost/scope/detail/move_or_copy_assign_ref.hpp>
- #include <boost/scope/detail/move_or_copy_construct_ref.hpp>
- #include <boost/scope/detail/is_nonnull_default_constructible.hpp>
- #include <boost/scope/detail/type_traits/is_swappable.hpp>
- #include <boost/scope/detail/type_traits/is_nothrow_swappable.hpp>
- #include <boost/scope/detail/type_traits/is_nothrow_invocable.hpp>
- #include <boost/scope/detail/type_traits/negation.hpp>
- #include <boost/scope/detail/type_traits/conjunction.hpp>
- #include <boost/scope/detail/type_traits/disjunction.hpp>
- #include <boost/scope/detail/header.hpp>
- #ifdef BOOST_HAS_PRAGMA_ONCE
- #pragma once
- #endif
- namespace boost {
- namespace scope {
- #if !defined(BOOST_NO_CXX17_FOLD_EXPRESSIONS) && !defined(BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS)
- template< auto DefaultValue, auto... UnallocatedValues >
- struct unallocated_resource
- {
-
- static decltype(DefaultValue) make_default() noexcept
- {
- return DefaultValue;
- }
-
- template< typename Resource >
- static bool is_allocated(Resource const& res) noexcept
- {
- static_assert(noexcept(res != DefaultValue && (... && (res != UnallocatedValues))),
- "Invalid unallocated resource value types: comparing resource values with the unallocated values must be noexcept");
- return res != DefaultValue && (... && (res != UnallocatedValues));
- }
- };
- #endif
- struct default_resource_t { };
- BOOST_INLINE_VARIABLE constexpr default_resource_t default_resource = { };
- namespace detail {
- template< typename T >
- struct is_default_resource : public std::false_type { };
- template< >
- struct is_default_resource< default_resource_t > : public std::true_type { };
- template< >
- struct is_default_resource< const default_resource_t > : public std::true_type { };
- template< >
- struct is_default_resource< volatile default_resource_t > : public std::true_type { };
- template< >
- struct is_default_resource< const volatile default_resource_t > : public std::true_type { };
- template< typename T >
- struct is_default_resource< T& > : public is_default_resource< T >::type { };
- template< typename T >
- class ref_wrapper
- {
- private:
- T* m_value;
- public:
- explicit
- #if !defined(BOOST_CORE_NO_CONSTEXPR_ADDRESSOF)
- constexpr
- #endif
- ref_wrapper(T& value) noexcept :
- m_value(boost::addressof(value))
- {
- }
- ref_wrapper& operator= (T& value) noexcept
- {
- m_value = boost::addressof(value);
- return *this;
- }
- ref_wrapper(T&&) = delete;
- ref_wrapper& operator= (T&&) = delete;
- operator T& () const noexcept
- {
- return *m_value;
- }
- template< typename... Args >
- void operator() (Args&&... args) const noexcept(detail::is_nothrow_invocable< T&, Args&&... >::value)
- {
- (*m_value)(static_cast< Args&& >(args)...);
- }
- };
- template< typename T >
- struct wrap_reference
- {
- using type = T;
- };
- template< typename T >
- struct wrap_reference< T& >
- {
- using type = ref_wrapper< T >;
- };
- template< typename Resource, bool UseCompactStorage >
- class resource_holder :
- public detail::compact_storage< typename wrap_reference< Resource >::type >
- {
- public:
- using resource_type = Resource;
- using internal_resource_type = typename wrap_reference< resource_type >::type;
- private:
- using resource_base = detail::compact_storage< internal_resource_type >;
- public:
- template<
- bool Requires = std::is_default_constructible< internal_resource_type >::value,
- typename = typename std::enable_if< Requires >::type
- >
- constexpr resource_holder() noexcept(std::is_nothrow_default_constructible< internal_resource_type >::value) :
- resource_base()
- {
- }
- template<
- typename R,
- typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
- >
- explicit resource_holder(R&& res) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
- resource_base(static_cast< R&& >(res))
- {
- }
- template<
- typename R,
- typename D,
- typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
- >
- explicit resource_holder(R&& res, D&& del, bool allocated) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
- resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), allocated, typename std::is_nothrow_constructible< resource_type, R >::type())
- {
- }
- resource_type& get() noexcept
- {
- return resource_base::get();
- }
- resource_type const& get() const noexcept
- {
- return resource_base::get();
- }
- internal_resource_type& get_internal() noexcept
- {
- return resource_base::get();
- }
- internal_resource_type const& get_internal() const noexcept
- {
- return resource_base::get();
- }
- void move_from(internal_resource_type&& that) noexcept(std::is_nothrow_move_assignable< internal_resource_type >::value)
- {
- resource_base::get() = static_cast< internal_resource_type&& >(that);
- }
- private:
- template< typename R, typename D >
- explicit resource_holder(R&& res, D&& del, bool allocated, std::true_type) noexcept :
- resource_base(static_cast< R&& >(res))
- {
- }
- template< typename R, typename D >
- explicit resource_holder(R&& res, D&& del, bool allocated, std::false_type) try :
- resource_base(res)
- {
- }
- catch (...)
- {
- if (allocated)
- del(res);
- }
- };
- template< typename Resource >
- class resource_holder< Resource, false >
- {
- public:
- using resource_type = Resource;
- using internal_resource_type = typename wrap_reference< resource_type >::type;
- private:
-
- internal_resource_type m_resource;
- public:
- template<
- bool Requires = std::is_default_constructible< internal_resource_type >::value,
- typename = typename std::enable_if< Requires >::type
- >
- constexpr resource_holder() noexcept(std::is_nothrow_default_constructible< internal_resource_type >::value) :
- m_resource()
- {
- }
- template<
- typename R,
- typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
- >
- explicit resource_holder(R&& res) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
- m_resource(static_cast< R&& >(res))
- {
- }
- template<
- typename R,
- typename D,
- typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
- >
- explicit resource_holder(R&& res, D&& del, bool allocated) noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
- resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), allocated, typename std::is_nothrow_constructible< resource_type, R >::type())
- {
- }
- resource_type& get() noexcept
- {
- return m_resource;
- }
- resource_type const& get() const noexcept
- {
- return m_resource;
- }
- internal_resource_type& get_internal() noexcept
- {
- return m_resource;
- }
- internal_resource_type const& get_internal() const noexcept
- {
- return m_resource;
- }
- void move_from(internal_resource_type&& that)
- noexcept(std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::value)
- {
- internal_resource_type* p = boost::addressof(m_resource);
- p->~internal_resource_type();
- new (p) internal_resource_type(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that));
- }
- private:
- template< typename R, typename D >
- explicit resource_holder(R&& res, D&& del, bool allocated, std::true_type) noexcept :
- m_resource(static_cast< R&& >(res))
- {
- }
- template< typename R, typename D >
- explicit resource_holder(R&& res, D&& del, bool allocated, std::false_type) try :
- m_resource(res)
- {
- }
- catch (...)
- {
- if (allocated)
- del(res);
- }
- };
- template< typename Resource, typename Deleter >
- class deleter_holder :
- public detail::compact_storage< typename wrap_reference< Deleter >::type >
- {
- public:
- using resource_type = Resource;
- using deleter_type = Deleter;
- using internal_deleter_type = typename wrap_reference< deleter_type >::type;
- private:
- using deleter_base = detail::compact_storage< internal_deleter_type >;
- public:
- template<
- bool Requires = detail::is_nonnull_default_constructible< internal_deleter_type >::value,
- typename = typename std::enable_if< Requires >::type
- >
- constexpr deleter_holder() noexcept(detail::is_nothrow_nonnull_default_constructible< internal_deleter_type >::value) :
- deleter_base()
- {
- }
- template<
- typename D,
- typename = typename std::enable_if< std::is_constructible< internal_deleter_type, D >::value >::type
- >
- explicit deleter_holder(D&& del) noexcept(std::is_nothrow_constructible< internal_deleter_type, D >::value) :
- deleter_base(static_cast< D&& >(del))
- {
- }
- template<
- typename D,
- typename = typename std::enable_if< std::is_constructible< internal_deleter_type, D >::value >::type
- >
- explicit deleter_holder(D&& del, resource_type& res, bool allocated) noexcept(std::is_nothrow_constructible< internal_deleter_type, D >::value) :
- deleter_holder(static_cast< D&& >(del), res, allocated, typename std::is_nothrow_constructible< internal_deleter_type, D >::type())
- {
- }
- deleter_type& get() noexcept
- {
- return deleter_base::get();
- }
- deleter_type const& get() const noexcept
- {
- return deleter_base::get();
- }
- internal_deleter_type& get_internal() noexcept
- {
- return deleter_base::get();
- }
- internal_deleter_type const& get_internal() const noexcept
- {
- return deleter_base::get();
- }
- private:
- template< typename D >
- explicit deleter_holder(D&& del, resource_type& res, bool allocated, std::true_type) noexcept :
- deleter_base(static_cast< D&& >(del))
- {
- }
- template< typename D >
- explicit deleter_holder(D&& del, resource_type& res, bool allocated, std::false_type) try :
- deleter_base(del)
- {
- }
- catch (...)
- {
- if (BOOST_LIKELY(allocated))
- del(res);
- }
- };
- template< typename Resource, typename Deleter >
- using use_resource_compact_storage = detail::disjunction<
- std::is_nothrow_move_assignable< typename wrap_reference< Resource >::type >,
- std::is_nothrow_constructible< typename wrap_reference< Deleter >::type, typename detail::move_or_copy_construct_ref< Deleter >::type >,
- detail::negation< std::is_nothrow_constructible< typename wrap_reference< Resource >::type, typename detail::move_or_copy_construct_ref< Resource >::type > >
- >;
- template< typename Resource, typename Deleter, typename Traits >
- class unique_resource_data :
- public detail::resource_holder< Resource, use_resource_compact_storage< Resource, Deleter >::value >,
- public detail::deleter_holder< Resource, Deleter >
- {
- public:
- using resource_type = Resource;
- using deleter_type = Deleter;
- using traits_type = Traits;
- private:
- using resource_holder = detail::resource_holder< resource_type, use_resource_compact_storage< resource_type, deleter_type >::value >;
- using deleter_holder = detail::deleter_holder< resource_type, deleter_type >;
- using result_of_make_default = decltype(traits_type::make_default());
- public:
- using internal_resource_type = typename resource_holder::internal_resource_type;
- using internal_deleter_type = typename deleter_holder::internal_deleter_type;
- static_assert(noexcept(traits_type::make_default()), "Invalid unique_resource resource traits: make_default must be noexcept");
- static_assert(std::is_nothrow_assignable< internal_resource_type&, result_of_make_default >::value,
- "Invalid unique_resource resource traits: resource must be nothrow-assignable from the result of make_default");
- static_assert(noexcept(traits_type::is_allocated(std::declval< resource_type const& >())), "Invalid unique_resource resource traits: is_allocated must be noexcept");
- public:
- template<
- bool Requires = detail::conjunction<
- std::is_constructible< resource_holder, result_of_make_default >,
- std::is_default_constructible< deleter_holder >
- >::value,
- typename = typename std::enable_if< Requires >::type
- >
- constexpr unique_resource_data()
- noexcept(detail::conjunction<
- std::is_nothrow_constructible< resource_holder, result_of_make_default >,
- std::is_nothrow_default_constructible< deleter_holder >
- >::value) :
- resource_holder(traits_type::make_default()),
- deleter_holder()
- {
- }
- unique_resource_data(unique_resource_data const&) = delete;
- unique_resource_data& operator= (unique_resource_data const&) = delete;
- unique_resource_data(unique_resource_data&& that)
- noexcept(detail::conjunction<
- std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >,
- std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >
- >::value) :
- unique_resource_data
- (
- static_cast< unique_resource_data&& >(that),
- typename std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::type(),
- typename std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >::type()
- )
- {
- }
- template<
- typename D,
- typename = typename std::enable_if< detail::conjunction<
- std::is_constructible< resource_holder, result_of_make_default >,
- std::is_constructible< deleter_holder, D >
- >::value >::type
- >
- explicit unique_resource_data(default_resource_t, D&& del)
- noexcept(detail::conjunction<
- std::is_nothrow_constructible< resource_holder, result_of_make_default >,
- std::is_nothrow_constructible< deleter_holder, D >
- >::value) :
- resource_holder(traits_type::make_default()),
- deleter_holder(static_cast< D&& >(del))
- {
- }
- template<
- typename R,
- typename D,
- typename = typename std::enable_if< detail::conjunction<
- detail::negation< detail::is_default_resource< R > >,
- std::is_constructible< resource_holder, R, D, bool >,
- std::is_constructible< deleter_holder, D, resource_type&, bool >
- >::value >::type
- >
- explicit unique_resource_data(R&& res, D&& del)
- noexcept(detail::conjunction<
- std::is_nothrow_constructible< resource_holder, R, D, bool >,
- std::is_nothrow_constructible< deleter_holder, D, resource_type&, bool >
- >::value) :
- unique_resource_data(static_cast< R&& >(res), static_cast< D&& >(del), traits_type::is_allocated(res))
- {
-
-
- static_assert(noexcept(traits_type::is_allocated(res)), "Invalid unique_resource resource traits: is_allocated must be noexcept");
- }
- template<
- bool Requires = detail::conjunction<
- std::is_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
- std::is_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
- >::value
- >
- typename std::enable_if< Requires, unique_resource_data& >::type operator= (unique_resource_data&& that)
- noexcept(detail::conjunction<
- std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
- std::is_nothrow_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
- >::value)
- {
- assign(static_cast< unique_resource_data&& >(that), typename std::is_nothrow_move_assignable< internal_deleter_type >::type());
- return *this;
- }
- resource_type& get_resource() noexcept
- {
- return resource_holder::get();
- }
- resource_type const& get_resource() const noexcept
- {
- return resource_holder::get();
- }
- internal_resource_type& get_internal_resource() noexcept
- {
- return resource_holder::get_internal();
- }
- internal_resource_type const& get_internal_resource() const noexcept
- {
- return resource_holder::get_internal();
- }
- deleter_type& get_deleter() noexcept
- {
- return deleter_holder::get();
- }
- deleter_type const& get_deleter() const noexcept
- {
- return deleter_holder::get();
- }
- internal_deleter_type& get_internal_deleter() noexcept
- {
- return deleter_holder::get_internal();
- }
- internal_deleter_type const& get_internal_deleter() const noexcept
- {
- return deleter_holder::get_internal();
- }
- bool is_allocated() const noexcept
- {
- return traits_type::is_allocated(get_resource());
- }
- void set_unallocated() noexcept
- {
- get_internal_resource() = traits_type::make_default();
- }
- template< typename R >
- void assign_resource(R&& res) noexcept(std::is_nothrow_assignable< internal_resource_type&, R >::value)
- {
- get_internal_resource() = static_cast< R&& >(res);
- }
- template<
- bool Requires = detail::conjunction<
- detail::is_swappable< internal_resource_type >,
- detail::is_swappable< internal_deleter_type >,
- detail::disjunction<
- detail::is_nothrow_swappable< internal_resource_type >,
- detail::is_nothrow_swappable< internal_deleter_type >
- >
- >::value
- >
- typename std::enable_if< Requires >::type swap(unique_resource_data& that)
- noexcept(detail::conjunction< detail::is_nothrow_swappable< internal_resource_type >, detail::is_nothrow_swappable< internal_deleter_type > >::value)
- {
- swap_impl
- (
- that,
- std::integral_constant< bool, detail::is_nothrow_swappable< internal_resource_type >::value >(),
- std::integral_constant< bool, detail::conjunction<
- detail::is_nothrow_swappable< internal_resource_type >,
- detail::is_nothrow_swappable< internal_deleter_type >
- >::value >()
- );
- }
- private:
- unique_resource_data(unique_resource_data&& that, std::true_type, std::true_type) noexcept :
- resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
- deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter()))
- {
- that.set_unallocated();
- }
- unique_resource_data(unique_resource_data&& that, std::false_type, std::true_type) :
- resource_holder(static_cast< resource_type const& >(that.get_resource())),
- deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter()))
- {
- that.set_unallocated();
- }
- unique_resource_data(unique_resource_data&& that, std::true_type, std::false_type) try :
- resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
- deleter_holder(static_cast< deleter_type const& >(that.get_deleter()))
- {
- that.set_unallocated();
- }
- catch (...)
- {
-
-
- that.resource_holder::move_from(static_cast< internal_resource_type&& >(resource_holder::get_internal()));
- }
- unique_resource_data(unique_resource_data&& that, std::false_type, std::false_type) :
- resource_holder(static_cast< resource_type const& >(that.get_resource())),
- deleter_holder(static_cast< deleter_type const& >(that.get_deleter()))
- {
- that.set_unallocated();
- }
- template<
- typename R,
- typename D,
- typename = typename std::enable_if< detail::conjunction<
- std::is_constructible< resource_holder, R, D, bool >,
- std::is_constructible< deleter_holder, D, resource_type&, bool >
- >::value >::type
- >
- explicit unique_resource_data(R&& res, D&& del, bool allocated)
- noexcept(detail::conjunction<
- std::is_nothrow_constructible< resource_holder, R, D, bool >,
- std::is_nothrow_constructible< deleter_holder, D, resource_type&, bool >
- >::value) :
- resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), allocated),
- deleter_holder(static_cast< D&& >(del), resource_holder::get(), allocated)
- {
- }
- void assign(unique_resource_data&& that, std::true_type)
- noexcept(std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >::value)
- {
- get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
- get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
- that.set_unallocated();
- }
- void assign(unique_resource_data&& that, std::false_type)
- {
- get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
- get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
- that.set_unallocated();
- }
- void swap_impl(unique_resource_data& that, std::true_type, std::true_type) noexcept
- {
- boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
- boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
- }
- void swap_impl(unique_resource_data& that, std::true_type, std::false_type)
- {
- boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
- boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
- }
- void swap_impl(unique_resource_data& that, std::false_type, std::false_type)
- {
- boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
- boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
- }
- };
- template< typename Resource, typename Deleter >
- class unique_resource_data< Resource, Deleter, void > :
- public detail::resource_holder< Resource, use_resource_compact_storage< Resource, Deleter >::value >,
- public detail::deleter_holder< Resource, Deleter >
- {
- public:
- using resource_type = Resource;
- using deleter_type = Deleter;
- using traits_type = void;
- private:
- using resource_holder = detail::resource_holder< resource_type, use_resource_compact_storage< resource_type, deleter_type >::value >;
- using deleter_holder = detail::deleter_holder< resource_type, deleter_type >;
- public:
- using internal_resource_type = typename resource_holder::internal_resource_type;
- using internal_deleter_type = typename deleter_holder::internal_deleter_type;
- private:
- bool m_allocated;
- public:
- template<
- bool Requires = detail::conjunction< std::is_default_constructible< resource_holder >, std::is_default_constructible< deleter_holder > >::value,
- typename = typename std::enable_if< Requires >::type
- >
- constexpr unique_resource_data()
- noexcept(detail::conjunction< std::is_nothrow_default_constructible< resource_holder >, std::is_nothrow_default_constructible< deleter_holder > >::value) :
- resource_holder(),
- deleter_holder(),
- m_allocated(false)
- {
- }
- unique_resource_data(unique_resource_data const&) = delete;
- unique_resource_data& operator= (unique_resource_data const&) = delete;
- template<
- bool Requires = detail::conjunction<
- std::is_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >,
- std::is_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >
- >::value,
- typename = typename std::enable_if< Requires >::type
- >
- unique_resource_data(unique_resource_data&& that)
- noexcept(detail::conjunction<
- std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >,
- std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >
- >::value) :
- unique_resource_data
- (
- static_cast< unique_resource_data&& >(that),
- typename std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::type(),
- typename std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >::type()
- )
- {
- }
- template<
- typename D,
- typename = typename std::enable_if< detail::conjunction<
- std::is_default_constructible< resource_holder >,
- std::is_constructible< deleter_holder, D >
- >::value >::type
- >
- explicit unique_resource_data(default_resource_t, D&& del)
- noexcept(detail::conjunction<
- std::is_nothrow_default_constructible< resource_holder >,
- std::is_nothrow_constructible< deleter_holder, D >
- >::value) :
- resource_holder(),
- deleter_holder(static_cast< D&& >(del)),
- m_allocated(false)
- {
- }
- template<
- typename R,
- typename D,
- typename = typename std::enable_if< detail::conjunction<
- detail::negation< detail::is_default_resource< R > >,
- std::is_constructible< resource_holder, R, D, bool >,
- std::is_constructible< deleter_holder, D, resource_type&, bool >
- >::value >::type
- >
- explicit unique_resource_data(R&& res, D&& del)
- noexcept(detail::conjunction<
- std::is_nothrow_constructible< resource_holder, R, D, bool >,
- std::is_nothrow_constructible< deleter_holder, D, resource_type&, bool >
- >::value) :
- resource_holder(static_cast< R&& >(res), static_cast< D&& >(del), true),
- deleter_holder(static_cast< D&& >(del), resource_holder::get(), true),
- m_allocated(true)
- {
- }
- template<
- bool Requires = detail::conjunction<
- std::is_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
- std::is_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
- >::value
- >
- typename std::enable_if< Requires, unique_resource_data& >::type operator= (unique_resource_data&& that)
- noexcept(detail::conjunction<
- std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >,
- std::is_nothrow_assignable< internal_deleter_type&, typename detail::move_or_copy_assign_ref< deleter_type >::type >
- >::value)
- {
- assign(static_cast< unique_resource_data&& >(that), typename std::is_nothrow_move_assignable< internal_deleter_type >::type());
- return *this;
- }
- resource_type& get_resource() noexcept
- {
- return resource_holder::get();
- }
- resource_type const& get_resource() const noexcept
- {
- return resource_holder::get();
- }
- internal_resource_type& get_internal_resource() noexcept
- {
- return resource_holder::get_internal();
- }
- internal_resource_type const& get_internal_resource() const noexcept
- {
- return resource_holder::get_internal();
- }
- deleter_type& get_deleter() noexcept
- {
- return deleter_holder::get();
- }
- deleter_type const& get_deleter() const noexcept
- {
- return deleter_holder::get();
- }
- internal_deleter_type& get_internal_deleter() noexcept
- {
- return deleter_holder::get_internal();
- }
- internal_deleter_type const& get_internal_deleter() const noexcept
- {
- return deleter_holder::get_internal();
- }
- bool is_allocated() const noexcept
- {
- return m_allocated;
- }
- void set_unallocated() noexcept
- {
- m_allocated = false;
- }
- template< typename R >
- void assign_resource(R&& res) noexcept(std::is_nothrow_assignable< internal_resource_type&, R >::value)
- {
- get_internal_resource() = static_cast< R&& >(res);
- m_allocated = true;
- }
- template<
- bool Requires = detail::conjunction<
- detail::is_swappable< internal_resource_type >,
- detail::is_swappable< internal_deleter_type >,
- detail::disjunction<
- detail::is_nothrow_swappable< internal_resource_type >,
- detail::is_nothrow_swappable< internal_deleter_type >
- >
- >::value
- >
- typename std::enable_if< Requires >::type swap(unique_resource_data& that)
- noexcept(detail::conjunction< detail::is_nothrow_swappable< internal_resource_type >, detail::is_nothrow_swappable< internal_deleter_type > >::value)
- {
- swap_impl
- (
- that,
- std::integral_constant< bool, detail::is_nothrow_swappable< internal_resource_type >::value >(),
- std::integral_constant< bool, detail::conjunction<
- detail::is_nothrow_swappable< internal_resource_type >,
- detail::is_nothrow_swappable< internal_deleter_type >
- >::value >()
- );
- }
- private:
- unique_resource_data(unique_resource_data&& that, std::true_type, std::true_type) noexcept :
- resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
- deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter())),
- m_allocated(that.m_allocated)
- {
- that.m_allocated = false;
- }
- unique_resource_data(unique_resource_data&& that, std::false_type, std::true_type) :
- resource_holder(static_cast< resource_type const& >(that.get_resource())),
- deleter_holder(static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter())),
- m_allocated(that.m_allocated)
- {
- that.m_allocated = false;
- }
- unique_resource_data(unique_resource_data&& that, std::true_type, std::false_type) try :
- resource_holder(static_cast< typename detail::move_or_copy_construct_ref< resource_type >::type >(that.get_resource())),
- deleter_holder(static_cast< deleter_type const& >(that.get_deleter())),
- m_allocated(that.m_allocated)
- {
- that.m_allocated = false;
- }
- catch (...)
- {
-
-
- that.resource_holder::move_from(static_cast< internal_resource_type&& >(resource_holder::get_internal()));
- }
- unique_resource_data(unique_resource_data&& that, std::false_type, std::false_type) :
- resource_holder(static_cast< resource_type const& >(that.get_resource())),
- deleter_holder(static_cast< deleter_type const& >(that.get_deleter())),
- m_allocated(that.m_allocated)
- {
- that.m_allocated = false;
- }
- void assign(unique_resource_data&& that, std::true_type)
- noexcept(std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< resource_type >::type >::value)
- {
- get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
- get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
- m_allocated = that.m_allocated;
- that.m_allocated = false;
- }
- void assign(unique_resource_data&& that, std::false_type)
- {
- get_internal_deleter() = static_cast< typename detail::move_or_copy_assign_ref< deleter_type >::type >(that.get_deleter());
- get_internal_resource() = static_cast< typename detail::move_or_copy_assign_ref< resource_type >::type >(that.get_resource());
- m_allocated = that.m_allocated;
- that.m_allocated = false;
- }
- void swap_impl(unique_resource_data& that, std::true_type, std::true_type) noexcept
- {
- boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
- boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
- boost::core::invoke_swap(m_allocated, that.m_allocated);
- }
- void swap_impl(unique_resource_data& that, std::true_type, std::false_type)
- {
- boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
- boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
- boost::core::invoke_swap(m_allocated, that.m_allocated);
- }
- void swap_impl(unique_resource_data& that, std::false_type, std::false_type)
- {
- boost::core::invoke_swap(get_internal_resource(), that.get_internal_resource());
- boost::core::invoke_swap(get_internal_deleter(), that.get_internal_deleter());
- boost::core::invoke_swap(m_allocated, that.m_allocated);
- }
- };
- template< typename T >
- struct is_dereferenceable_impl
- {
- template< typename U, typename R = decltype(*std::declval< U const& >()) >
- static std::true_type _is_dereferenceable_check(int);
- template< typename U >
- static std::false_type _is_dereferenceable_check(...);
- using type = decltype(is_dereferenceable_impl::_is_dereferenceable_check< T >(0));
- };
- template< typename T >
- struct is_dereferenceable : public is_dereferenceable_impl< T >::type { };
- template< >
- struct is_dereferenceable< void* > : public std::false_type { };
- template< >
- struct is_dereferenceable< const void* > : public std::false_type { };
- template< >
- struct is_dereferenceable< volatile void* > : public std::false_type { };
- template< >
- struct is_dereferenceable< const volatile void* > : public std::false_type { };
- template< >
- struct is_dereferenceable< void*& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const void*& > : public std::false_type { };
- template< >
- struct is_dereferenceable< volatile void*& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const volatile void*& > : public std::false_type { };
- template< >
- struct is_dereferenceable< void* const& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const void* const& > : public std::false_type { };
- template< >
- struct is_dereferenceable< volatile void* const& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const volatile void* const& > : public std::false_type { };
- template< >
- struct is_dereferenceable< void* volatile& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const void* volatile& > : public std::false_type { };
- template< >
- struct is_dereferenceable< volatile void* volatile& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const volatile void* volatile& > : public std::false_type { };
- template< >
- struct is_dereferenceable< void* const volatile& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const void* const volatile& > : public std::false_type { };
- template< >
- struct is_dereferenceable< volatile void* const volatile& > : public std::false_type { };
- template< >
- struct is_dereferenceable< const volatile void* const volatile& > : public std::false_type { };
- template< typename T, bool = detail::is_dereferenceable< T >::value >
- struct dereference_traits { };
- template< typename T >
- struct dereference_traits< T, true >
- {
- using result_type = decltype(*std::declval< T const& >());
- static constexpr bool is_noexcept = noexcept(*std::declval< T const& >());
- };
- }
- template< typename Resource, typename Deleter, typename Traits BOOST_SCOPE_DETAIL_DOC(= void) >
- class unique_resource
- {
- public:
-
- using resource_type = Resource;
-
- using deleter_type = Deleter;
-
- using traits_type = Traits;
- private:
- using data = detail::unique_resource_data< resource_type, deleter_type, traits_type >;
- using internal_resource_type = typename data::internal_resource_type;
- using internal_deleter_type = typename data::internal_deleter_type;
- data m_data;
- public:
-
-
- template<
- bool Requires = std::is_default_constructible< data >::value,
- typename = typename std::enable_if< Requires >::type
- >
-
- constexpr unique_resource() noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_default_constructible< data >::value))
- {
- }
-
- template<
- typename D
-
- , typename = typename std::enable_if<
- std::is_constructible< data, default_resource_t, typename detail::move_or_copy_construct_ref< D, deleter_type >::type >::value
- >::type
-
- >
- unique_resource(default_resource_t res, D&& del)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
- std::is_nothrow_constructible<
- data,
- default_resource_t,
- typename detail::move_or_copy_construct_ref< D, deleter_type >::type
- >::value
- )) :
- m_data
- (
- res,
- static_cast< typename detail::move_or_copy_construct_ref< D, deleter_type >::type >(del)
- )
- {
- }
-
- template<
- typename R
-
- , typename = typename std::enable_if< detail::conjunction<
- detail::is_nothrow_nonnull_default_constructible< deleter_type >,
- std::is_constructible< data, typename detail::move_or_copy_construct_ref< R, resource_type >::type, typename detail::move_or_copy_construct_ref< deleter_type >::type >,
- detail::disjunction< detail::negation< std::is_reference< resource_type > >, std::is_reference< R > >
- >::value >::type
-
- >
- explicit unique_resource(R&& res)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
- std::is_nothrow_constructible<
- data,
- typename detail::move_or_copy_construct_ref< R, resource_type >::type,
- typename detail::move_or_copy_construct_ref< deleter_type >::type
- >::value
- )) :
- m_data
- (
- static_cast< typename detail::move_or_copy_construct_ref< R, resource_type >::type >(res),
- static_cast< typename detail::move_or_copy_construct_ref< deleter_type >::type >(deleter_type())
- )
- {
- }
-
- template<
- typename R,
- typename D
-
- , typename = typename std::enable_if< detail::conjunction<
- std::is_constructible< data, typename detail::move_or_copy_construct_ref< R, resource_type >::type, typename detail::move_or_copy_construct_ref< D, deleter_type >::type >,
- detail::disjunction< detail::negation< std::is_reference< resource_type > >, std::is_reference< R > >
- >::value >::type
-
- >
- unique_resource(R&& res, D&& del)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
- std::is_nothrow_constructible<
- data,
- typename detail::move_or_copy_construct_ref< R, resource_type >::type,
- typename detail::move_or_copy_construct_ref< D, deleter_type >::type
- >::value
- )) :
- m_data
- (
- static_cast< typename detail::move_or_copy_construct_ref< R, resource_type >::type >(res),
- static_cast< typename detail::move_or_copy_construct_ref< D, deleter_type >::type >(del)
- )
- {
- }
- unique_resource(unique_resource const&) = delete;
- unique_resource& operator= (unique_resource const&) = delete;
-
-
- template<
- bool Requires = std::is_move_constructible< data >::value,
- typename = typename std::enable_if< Requires >::type
- >
-
- unique_resource(unique_resource&& that) noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_move_constructible< data >::value)) :
- m_data(static_cast< data&& >(that.m_data))
- {
- }
-
- #if !defined(BOOST_SCOPE_DOXYGEN)
- template< bool Requires = std::is_move_assignable< data >::value >
- typename std::enable_if< Requires, unique_resource& >::type
- #else
- unique_resource&
- #endif
- operator= (unique_resource&& that)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(std::is_nothrow_move_assignable< data >::value))
- {
- reset();
- m_data = static_cast< data&& >(that.m_data);
- return *this;
- }
-
- ~unique_resource() noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_invocable< deleter_type&, resource_type& >::value))
- {
- if (BOOST_LIKELY(m_data.is_allocated()))
- m_data.get_deleter()(m_data.get_resource());
- }
-
- explicit operator bool () const noexcept
- {
- return m_data.is_allocated();
- }
-
- bool allocated() const noexcept
- {
- return m_data.is_allocated();
- }
-
- resource_type const& get() const noexcept
- {
- return m_data.get_resource();
- }
-
- deleter_type const& get_deleter() const noexcept
- {
- return m_data.get_deleter();
- }
-
- void release() noexcept
- {
- m_data.set_unallocated();
- }
-
- void reset() noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_invocable< deleter_type&, resource_type& >::value))
- {
- if (BOOST_LIKELY(m_data.is_allocated()))
- {
- m_data.get_deleter()(m_data.get_resource());
- m_data.set_unallocated();
- }
- }
-
- template< typename R >
- #if !defined(BOOST_SCOPE_DOXYGEN)
- typename std::enable_if< detail::conjunction<
- std::is_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< R, resource_type >::type >,
- detail::disjunction< detail::negation< std::is_reference< resource_type > >, std::is_reference< R > >
- >::value >::type
- #else
- void
- #endif
- reset(R&& res)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
- detail::conjunction<
- detail::is_nothrow_invocable< deleter_type&, resource_type& >,
- std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< R, resource_type >::type >
- >::value
- ))
- {
- reset_impl
- (
- static_cast< R&& >(res),
- typename detail::conjunction<
- detail::is_nothrow_invocable< deleter_type&, resource_type& >,
- std::is_nothrow_assignable< internal_resource_type&, typename detail::move_or_copy_assign_ref< R, resource_type >::type >
- >::type()
- );
- }
-
- #if !defined(BOOST_SCOPE_DOXYGEN)
- template< bool Requires = detail::is_dereferenceable< resource_type >::value >
- typename std::enable_if< Requires, resource_type const& >::type
- #else
- resource_type const&
- #endif
- operator-> () const noexcept
- {
- return get();
- }
-
- #if !defined(BOOST_SCOPE_DOXYGEN)
- template< bool Requires = detail::is_dereferenceable< resource_type >::value >
- typename detail::dereference_traits< resource_type, Requires >::result_type
- #else
- auto
- #endif
- operator* () const
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::dereference_traits< resource_type, Requires >::is_noexcept))
- {
- return *get();
- }
-
- #if !defined(BOOST_SCOPE_DOXYGEN)
- template< bool Requires = detail::is_swappable< data >::value >
- typename std::enable_if< Requires >::type
- #else
- void
- #endif
- swap(unique_resource& that)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_swappable< data >::value))
- {
- m_data.swap(that.m_data);
- }
-
- #if !defined(BOOST_SCOPE_DOXYGEN)
- template< bool Requires = detail::is_swappable< data >::value >
- friend typename std::enable_if< Requires >::type
- #else
- friend void
- #endif
- swap(unique_resource& left, unique_resource& right)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(detail::is_nothrow_swappable< data >::value))
- {
- left.swap(right);
- }
- private:
-
- template< typename R >
- void reset_impl(R&& res, std::true_type) noexcept
- {
- reset();
- m_data.assign_resource(static_cast< typename detail::move_or_copy_assign_ref< R, resource_type >::type >(res));
- }
-
- template< typename R >
- void reset_impl(R&& res, std::false_type)
- {
- try
- {
- reset();
- m_data.assign_resource(static_cast< typename detail::move_or_copy_assign_ref< R, resource_type >::type >(res));
- }
- catch (...)
- {
- m_data.get_deleter()(static_cast< R&& >(res));
- throw;
- }
- }
- };
- #if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
- template<
- typename Resource,
- typename Deleter,
- typename = typename std::enable_if< !detail::is_default_resource< Resource >::value >::type
- >
- unique_resource(Resource, Deleter) -> unique_resource< Resource, Deleter >;
- #endif
- template< typename Resource, typename Deleter, typename Invalid >
- inline unique_resource< typename std::decay< Resource >::type, typename std::decay< Deleter >::type >
- make_unique_resource_checked(Resource&& res, Invalid const& invalid, Deleter&& del)
- noexcept(BOOST_SCOPE_DETAIL_DOC_HIDDEN(
- detail::conjunction<
- std::is_nothrow_constructible< typename std::decay< Resource >::type, typename detail::move_or_copy_construct_ref< Resource, typename std::decay< Resource >::type >::type >,
- std::is_nothrow_constructible< typename std::decay< Deleter >::type, typename detail::move_or_copy_construct_ref< Deleter, typename std::decay< Deleter >::type >::type >
- >::value
- ))
- {
- using unique_resource_type = unique_resource< typename std::decay< Resource >::type, typename std::decay< Deleter >::type >;
- if (!(res == invalid))
- return unique_resource_type(static_cast< Resource&& >(res), static_cast< Deleter&& >(del));
- else
- return unique_resource_type(default_resource_t(), static_cast< Deleter&& >(del));
- }
- }
- }
- #include <boost/scope/detail/footer.hpp>
- #endif
|