mirror of
https://github.com/boostorg/scope.git
synced 2026-01-24 18:32:10 +00:00
Avoid using try/catch in non-throwing ctors to silence MSVC warnings.
This commit is contained in:
@@ -72,11 +72,23 @@ private:
|
||||
bool m_active;
|
||||
|
||||
template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
|
||||
explicit data(F&& func, bool active) noexcept(std::is_nothrow_constructible< Func, F >::value) :
|
||||
explicit data(F&& func, bool active, std::true_type) noexcept :
|
||||
func_base(static_cast< F&& >(func)),
|
||||
m_active(active)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
|
||||
explicit data(F&& func, bool active, std::false_type) try :
|
||||
func_base(static_cast< F&& >(func)),
|
||||
m_active(active)
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (active)
|
||||
func();
|
||||
}
|
||||
};
|
||||
|
||||
data m_data;
|
||||
@@ -86,28 +98,44 @@ public:
|
||||
template<
|
||||
typename F,
|
||||
typename = typename std::enable_if< detail::conjunction<
|
||||
std::is_constructible< data, typename detail::move_or_copy_construct_ref< F, Func >::type, bool >,
|
||||
std::is_constructible< data, typename detail::move_or_copy_construct_ref< F, Func >::type, bool, typename std::is_nothrow_constructible< Func, F >::type >,
|
||||
detail::is_not_like_scope_exit< F >
|
||||
>::value >::type
|
||||
>
|
||||
explicit scope_exit(F&& func, bool active = true)
|
||||
noexcept(std::is_nothrow_constructible< data, typename detail::move_or_copy_construct_ref< F, Func >::type, bool >::value) try :
|
||||
m_data(static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func), active)
|
||||
noexcept(std::is_nothrow_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< F, Func >::type,
|
||||
bool,
|
||||
typename std::is_nothrow_constructible< Func, F >::type
|
||||
>::value) :
|
||||
m_data(static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func), active, typename std::is_nothrow_constructible< Func, F >::type())
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (active)
|
||||
func();
|
||||
}
|
||||
|
||||
//! Move-constructs a scope guard, deactivates the original scope guard.
|
||||
template<
|
||||
bool Requires = std::is_constructible< data, typename detail::move_or_copy_construct_ref< Func >::type, bool >::value,
|
||||
bool Requires = std::is_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< Func >::type,
|
||||
bool,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< Func >::type >::type
|
||||
>::value,
|
||||
typename = typename std::enable_if< Requires >::type
|
||||
>
|
||||
scope_exit(scope_exit&& that) noexcept(std::is_nothrow_constructible< data, typename detail::move_or_copy_construct_ref< Func >::type, bool >::value) :
|
||||
m_data(static_cast< typename detail::move_or_copy_construct_ref< Func >::type >(that.m_data.get()), that.m_data.m_active)
|
||||
scope_exit(scope_exit&& that)
|
||||
noexcept(std::is_nothrow_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< Func >::type,
|
||||
bool,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< Func >::type >::type
|
||||
>::value) :
|
||||
m_data
|
||||
(
|
||||
static_cast< typename detail::move_or_copy_construct_ref< Func >::type >(that.m_data.get()),
|
||||
that.m_data.m_active,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< Func >::type >::type()
|
||||
)
|
||||
{
|
||||
that.m_data.m_active = false;
|
||||
}
|
||||
|
||||
@@ -77,12 +77,25 @@ private:
|
||||
bool m_active;
|
||||
|
||||
template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
|
||||
explicit data(F&& func, unsigned int uncaught_count, bool active) noexcept(std::is_nothrow_constructible< Func, F >::value) :
|
||||
explicit data(F&& func, unsigned int uncaught_count, bool active, std::true_type) noexcept :
|
||||
func_base(static_cast< F&& >(func)),
|
||||
m_uncaught_count(uncaught_count),
|
||||
m_active(active)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
|
||||
explicit data(F&& func, unsigned int uncaught_count, bool active, std::false_type) try :
|
||||
func_base(static_cast< F&& >(func)),
|
||||
m_uncaught_count(uncaught_count),
|
||||
m_active(active)
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (active)
|
||||
func();
|
||||
}
|
||||
};
|
||||
|
||||
data m_data;
|
||||
@@ -92,28 +105,54 @@ public:
|
||||
template<
|
||||
typename F,
|
||||
typename = typename std::enable_if< detail::conjunction<
|
||||
std::is_constructible< data, typename detail::move_or_copy_construct_ref< F, Func >::type, unsigned int, bool >,
|
||||
std::is_constructible< data, typename detail::move_or_copy_construct_ref< F, Func >::type, unsigned int, bool, typename std::is_nothrow_constructible< Func, F >::type >,
|
||||
detail::is_not_like_scope_fail< F >
|
||||
>::value >::type
|
||||
>
|
||||
explicit scope_fail(F&& func, bool active = true)
|
||||
noexcept(std::is_nothrow_constructible< data, typename detail::move_or_copy_construct_ref< F, Func >::type, unsigned int, bool >::value) try :
|
||||
m_data(static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func), boost::core::uncaught_exceptions(), active)
|
||||
noexcept(std::is_nothrow_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< F, Func >::type,
|
||||
unsigned int,
|
||||
bool,
|
||||
typename std::is_nothrow_constructible< Func, F >::type
|
||||
>::value) :
|
||||
m_data
|
||||
(
|
||||
static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func),
|
||||
boost::core::uncaught_exceptions(),
|
||||
active,
|
||||
typename std::is_nothrow_constructible< Func, F >::type()
|
||||
)
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (active)
|
||||
func();
|
||||
}
|
||||
|
||||
//! Move-constructs a scope guard, deactivates the original scope guard.
|
||||
template<
|
||||
bool Requires = std::is_constructible< data, typename detail::move_or_copy_construct_ref< Func >::type, unsigned int, bool >::value,
|
||||
bool Requires = std::is_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< Func >::type,
|
||||
unsigned int,
|
||||
bool,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< Func >::type >::type
|
||||
>::value,
|
||||
typename = typename std::enable_if< Requires >::type
|
||||
>
|
||||
scope_fail(scope_fail&& that) noexcept(std::is_nothrow_constructible< data, typename detail::move_or_copy_construct_ref< Func >::type, unsigned int, bool >::value) :
|
||||
m_data(static_cast< typename detail::move_or_copy_construct_ref< Func >::type >(that.m_data.get()), that.m_data.m_uncaught_count, that.m_data.m_active)
|
||||
scope_fail(scope_fail&& that)
|
||||
noexcept(std::is_nothrow_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< Func >::type,
|
||||
unsigned int,
|
||||
bool,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< Func >::type >::type
|
||||
>::value) :
|
||||
m_data
|
||||
(
|
||||
static_cast< typename detail::move_or_copy_construct_ref< Func >::type >(that.m_data.get()),
|
||||
that.m_data.m_uncaught_count,
|
||||
that.m_data.m_active,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< Func >::type >::type()
|
||||
)
|
||||
{
|
||||
that.m_data.m_active = false;
|
||||
}
|
||||
|
||||
@@ -55,25 +55,55 @@ template< typename Func >
|
||||
class scope_final
|
||||
{
|
||||
private:
|
||||
Func m_func;
|
||||
struct data
|
||||
{
|
||||
Func m_func;
|
||||
|
||||
template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
|
||||
explicit data(F&& func, std::true_type) noexcept :
|
||||
m_func(static_cast< F&& >(func))
|
||||
{
|
||||
}
|
||||
|
||||
template< typename F, typename = typename std::enable_if< std::is_constructible< Func, F >::value >::type >
|
||||
explicit data(F&& func, std::false_type) try :
|
||||
m_func(static_cast< F&& >(func))
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
func();
|
||||
}
|
||||
};
|
||||
|
||||
data m_data;
|
||||
|
||||
public:
|
||||
//! Constructs a scope final guard with a given callable function object.
|
||||
template<
|
||||
typename F,
|
||||
typename = typename std::enable_if< detail::conjunction<
|
||||
std::is_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >,
|
||||
std::is_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< F, Func >::type,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >::type
|
||||
>,
|
||||
detail::is_not_like_scope_final< F >
|
||||
>::value >::type
|
||||
>
|
||||
scope_final(F&& func) noexcept(std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >::value) try :
|
||||
m_func(static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func))
|
||||
scope_final(F&& func)
|
||||
noexcept(std::is_nothrow_constructible<
|
||||
data,
|
||||
typename detail::move_or_copy_construct_ref< F, Func >::type,
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >::type
|
||||
>::value) :
|
||||
m_data
|
||||
(
|
||||
static_cast< typename detail::move_or_copy_construct_ref< F, Func >::type >(func),
|
||||
typename std::is_nothrow_constructible< Func, typename detail::move_or_copy_construct_ref< F, Func >::type >::type()
|
||||
)
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
func();
|
||||
}
|
||||
|
||||
scope_final(scope_final const&) = delete;
|
||||
scope_final& operator= (scope_final const&) = delete;
|
||||
@@ -81,7 +111,7 @@ public:
|
||||
//! Invokes the wrapped callable function object and destroys the callable.
|
||||
~scope_final() noexcept(noexcept(std::declval< Func& >()()))
|
||||
{
|
||||
m_func();
|
||||
m_data.m_func();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -114,29 +114,31 @@ template< typename Resource, typename Traits >
|
||||
struct has_deallocated_state : public has_deallocated_state_impl< Resource, Traits >::type { };
|
||||
|
||||
template< typename Resource, typename Traits, bool = has_custom_default< Resource, Traits >::value >
|
||||
struct resource_holder :
|
||||
class resource_holder :
|
||||
public detail::compact_storage< typename wrap_reference< Resource >::type >
|
||||
{
|
||||
public:
|
||||
typedef Resource resource_type;
|
||||
typedef typename wrap_reference< Resource >::type internal_resource_type;
|
||||
typedef Traits traits_type;
|
||||
typedef detail::compact_storage< internal_resource_type > resource_base;
|
||||
|
||||
public:
|
||||
template<
|
||||
bool Requires = std::is_default_constructible< resource_type >::value,
|
||||
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< resource_type >::value) :
|
||||
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< resource_type, R >::value >::type
|
||||
typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
|
||||
>
|
||||
explicit resource_holder(R&& res)
|
||||
noexcept(std::is_nothrow_constructible< resource_type, R >::value) :
|
||||
noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
|
||||
resource_base(static_cast< R&& >(res))
|
||||
{
|
||||
}
|
||||
@@ -144,18 +146,12 @@ struct resource_holder :
|
||||
template<
|
||||
typename R,
|
||||
typename D,
|
||||
typename = typename std::enable_if< std::is_constructible< resource_type, R >::value >::type
|
||||
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< resource_type, R >::value) try :
|
||||
resource_base(static_cast< R&& >(res))
|
||||
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())
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (allocated)
|
||||
del(static_cast< R&& >(res));
|
||||
}
|
||||
|
||||
resource_type& get() noexcept
|
||||
{
|
||||
@@ -176,21 +172,41 @@ struct resource_holder :
|
||||
{
|
||||
return resource_base::get();
|
||||
}
|
||||
|
||||
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(static_cast< R&& >(res))
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (allocated)
|
||||
del(static_cast< R&& >(res));
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Resource, typename Traits >
|
||||
struct resource_holder< Resource, Traits, true > :
|
||||
class resource_holder< Resource, Traits, true > :
|
||||
public detail::compact_storage< typename wrap_reference< Resource >::type >
|
||||
{
|
||||
public:
|
||||
typedef Resource resource_type;
|
||||
typedef typename wrap_reference< Resource >::type internal_resource_type;
|
||||
typedef Traits traits_type;
|
||||
typedef detail::compact_storage< internal_resource_type > resource_base;
|
||||
|
||||
public:
|
||||
constexpr resource_holder()
|
||||
noexcept(detail::conjunction<
|
||||
std::integral_constant< bool, noexcept(traits_type::make_default()) >,
|
||||
std::is_nothrow_constructible< resource_type, decltype(traits_type::make_default()) >
|
||||
std::is_nothrow_constructible< internal_resource_type, decltype(traits_type::make_default()) >
|
||||
>::value) :
|
||||
resource_base(traits_type::make_default())
|
||||
{
|
||||
@@ -198,10 +214,10 @@ struct resource_holder< Resource, Traits, true > :
|
||||
|
||||
template<
|
||||
typename R,
|
||||
typename = typename std::enable_if< std::is_constructible< resource_type, R >::value >::type
|
||||
typename = typename std::enable_if< std::is_constructible< internal_resource_type, R >::value >::type
|
||||
>
|
||||
explicit resource_holder(R&& res)
|
||||
noexcept(std::is_nothrow_constructible< resource_type, R >::value) :
|
||||
noexcept(std::is_nothrow_constructible< internal_resource_type, R >::value) :
|
||||
resource_base(static_cast< R&& >(res))
|
||||
{
|
||||
}
|
||||
@@ -209,18 +225,12 @@ struct resource_holder< Resource, Traits, true > :
|
||||
template<
|
||||
typename R,
|
||||
typename D,
|
||||
typename = typename std::enable_if< std::is_constructible< resource_type, R >::value >::type
|
||||
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< resource_type, R >::value) try :
|
||||
resource_base(static_cast< R&& >(res))
|
||||
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< internal_resource_type, R >::type())
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (allocated)
|
||||
del(static_cast< R&& >(res));
|
||||
}
|
||||
|
||||
resource_type& get() noexcept
|
||||
{
|
||||
@@ -241,10 +251,28 @@ struct resource_holder< Resource, Traits, true > :
|
||||
{
|
||||
return resource_base::get();
|
||||
}
|
||||
|
||||
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(static_cast< R&& >(res))
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (allocated)
|
||||
del(static_cast< R&& >(res));
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Resource, typename Deleter >
|
||||
struct deleter_holder :
|
||||
class deleter_holder :
|
||||
public detail::compact_storage< typename wrap_reference< Deleter >::type >
|
||||
{
|
||||
public:
|
||||
@@ -253,29 +281,24 @@ public:
|
||||
typedef typename wrap_reference< deleter_type >::type internal_deleter_type;
|
||||
typedef detail::compact_storage< internal_deleter_type > deleter_base;
|
||||
|
||||
public:
|
||||
template<
|
||||
bool Requires = std::is_default_constructible< deleter_type >::value,
|
||||
bool Requires = std::is_default_constructible< internal_deleter_type >::value,
|
||||
typename = typename std::enable_if< Requires >::type
|
||||
>
|
||||
constexpr deleter_holder() noexcept(std::is_nothrow_default_constructible< deleter_type >::value) :
|
||||
constexpr deleter_holder() noexcept(std::is_nothrow_default_constructible< internal_deleter_type >::value) :
|
||||
deleter_base()
|
||||
{
|
||||
}
|
||||
|
||||
template<
|
||||
typename D,
|
||||
typename = typename std::enable_if< std::is_constructible< deleter_type, D >::value >::type
|
||||
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< deleter_type, D >::value) try :
|
||||
deleter_base(static_cast< D&& >(del))
|
||||
explicit deleter_holder(D&& del, resource_type& res, bool allocated) noexcept(std::is_constructible< internal_deleter_type, D >::value) :
|
||||
deleter_holder(static_cast< D&& >(del), res, allocated, typename std::is_constructible< internal_deleter_type, D >::type())
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (BOOST_LIKELY(allocated))
|
||||
del(res);
|
||||
}
|
||||
|
||||
deleter_type& get() noexcept
|
||||
{
|
||||
@@ -296,6 +319,24 @@ public:
|
||||
{
|
||||
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(static_cast< D&& >(del))
|
||||
{
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (BOOST_LIKELY(allocated))
|
||||
del(res);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Resource, typename Traits, bool = detail::conjunction< has_deallocated_state< Resource, Traits >, has_custom_default< Resource, Traits > >::value >
|
||||
@@ -354,22 +395,13 @@ public:
|
||||
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) try :
|
||||
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()), resource_holder::get(),
|
||||
!std::is_nothrow_move_constructible< internal_resource_type >::value && that.m_allocated), // don't deallocate if the resource was copied
|
||||
m_allocated(that.m_allocated)
|
||||
>::value) :
|
||||
unique_resource_data
|
||||
(
|
||||
static_cast< unique_resource_data&& >(that),
|
||||
typename std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >::type()
|
||||
)
|
||||
{
|
||||
that.m_allocated = false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_IF_CONSTEXPR (std::is_nothrow_move_constructible< internal_resource_type >::value)
|
||||
{
|
||||
// The resource was moved to this object, and the deleter constructor failed with an exception.
|
||||
// The deleter holder has invoked the deleter already, so the move source is no longer valid.
|
||||
that.m_allocated = false;
|
||||
}
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -475,6 +507,33 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
unique_resource_data(unique_resource_data&& that, std::true_type)
|
||||
noexcept(std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::value) :
|
||||
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()), resource_holder::get(), false),
|
||||
m_allocated(that.m_allocated)
|
||||
{
|
||||
that.m_allocated = false;
|
||||
}
|
||||
|
||||
unique_resource_data(unique_resource_data&& that, 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< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter()), resource_holder::get(),
|
||||
std::is_nothrow_constructible< internal_resource_type, resource_type&& >::value && that.m_allocated), // don't deallocate if the resource was copy-constructed
|
||||
m_allocated(that.m_allocated)
|
||||
{
|
||||
that.m_allocated = false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_IF_CONSTEXPR (std::is_nothrow_constructible< internal_resource_type, resource_type&& >::value)
|
||||
{
|
||||
// The resource was moved to this object, and the deleter constructor failed with an exception.
|
||||
// The deleter holder has invoked the deleter already, so the move source is no longer valid.
|
||||
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)
|
||||
{
|
||||
@@ -556,21 +615,13 @@ public:
|
||||
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) try :
|
||||
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()), resource_holder::get(),
|
||||
!std::is_nothrow_move_constructible< internal_resource_type >::value && that.is_allocated()) // don't deallocate if the resource was copied
|
||||
>::value) :
|
||||
unique_resource_data
|
||||
(
|
||||
static_cast< unique_resource_data&& >(that),
|
||||
typename std::is_nothrow_constructible< internal_deleter_type, typename detail::move_or_copy_construct_ref< deleter_type >::type >::type()
|
||||
)
|
||||
{
|
||||
that.set_deallocated();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_IF_CONSTEXPR (std::is_nothrow_move_constructible< internal_resource_type >::value)
|
||||
{
|
||||
// The resource was moved to this object, and the deleter constructor failed with an exception.
|
||||
// The deleter holder has invoked the deleter already, so the move source is no longer valid.
|
||||
that.set_deallocated();
|
||||
}
|
||||
}
|
||||
|
||||
template<
|
||||
@@ -674,6 +725,31 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
unique_resource_data(unique_resource_data&& that, std::true_type)
|
||||
noexcept(std::is_nothrow_constructible< internal_resource_type, typename detail::move_or_copy_construct_ref< resource_type >::type >::value) :
|
||||
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()), resource_holder::get(), false)
|
||||
{
|
||||
that.set_deallocated();
|
||||
}
|
||||
|
||||
unique_resource_data(unique_resource_data&& that, 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< typename detail::move_or_copy_construct_ref< deleter_type >::type >(that.get_deleter()), resource_holder::get(),
|
||||
std::is_nothrow_constructible< internal_resource_type, resource_type&& >::value && that.is_allocated()) // don't deallocate if the resource was copy-constructed
|
||||
{
|
||||
that.set_deallocated();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_IF_CONSTEXPR (std::is_nothrow_constructible< internal_resource_type, resource_type&& >::value)
|
||||
{
|
||||
// The resource was moved to this object, and the deleter constructor failed with an exception.
|
||||
// The deleter holder has invoked the deleter already, so the move source is no longer valid.
|
||||
that.set_deallocated();
|
||||
}
|
||||
}
|
||||
|
||||
template<
|
||||
typename R,
|
||||
typename D,
|
||||
@@ -834,8 +910,8 @@ public:
|
||||
template<
|
||||
typename R,
|
||||
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< deleter_type >::type, bool >,
|
||||
std::is_nothrow_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, bool >,
|
||||
detail::disjunction< detail::negation< std::is_reference< resource_type > >, std::is_reference< R > > // prevent binding lvalue-reference resource to an rvalue
|
||||
>::value >::type
|
||||
>
|
||||
@@ -846,7 +922,12 @@ public:
|
||||
typename detail::move_or_copy_construct_ref< deleter_type >::type,
|
||||
bool
|
||||
>::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()), true)
|
||||
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()),
|
||||
true
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -866,7 +947,12 @@ public:
|
||||
typename detail::move_or_copy_construct_ref< D, deleter_type >::type,
|
||||
bool
|
||||
>::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), true)
|
||||
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),
|
||||
true
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -995,7 +1081,12 @@ private:
|
||||
typename detail::move_or_copy_construct_ref< D, deleter_type >::type,
|
||||
bool
|
||||
>::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), allocated)
|
||||
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),
|
||||
allocated
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user