::value
&& std::is_nothrow_move_constructible::value), int> = 0
>
unique_resource(unique_resource&& other) noexcept(std::is_nothrow_move_constructible::value
&& std::is_nothrow_move_constructible::value)
: m_resource(std::forward(other.m_resource)),
m_deleter(std::forward(other.m_deleter)),
m_execute_on_destruction(std::exchange(other.m_execute_on_destruction, false))
{
}
template::value
|| !std::is_nothrow_move_constructible::value), int> = 0
>
unique_resource(unique_resource&& other) noexcept(std::is_nothrow_move_constructible::value
&& std::is_nothrow_move_constructible::value)
: m_resource(other.m_resource),
m_deleter(other.m_deleter),
m_execute_on_destruction(std::exchange(other.m_execute_on_destruction, false))
{
}
unique_resource(const unique_resource&) = delete;
~unique_resource()
{
reset();
}
void reset()
{
if( m_execute_on_destruction == true )
{
m_execute_on_destruction = false;
get_deleter()(m_resource);
}
}
template
void reset(RR&& r)
{
reset();
m_resource = move_assign_if_noexcept(r);
m_execute_on_destruction = true;
}
void release()
{
m_execute_on_destruction = false;
}
const R& get() const noexcept
{
return m_resource;
}
template::value && std::is_nothrow_copy_constructible::value
&& ( std::is_class>::value
|| std::is_union>::value ), int> = 0
>
RR operator->() const noexcept
{
return m_resource;
}
template::value, int> = 0>
std::add_lvalue_reference_t> operator*() const noexcept
{
return *get();
}
const D& get_deleter() const noexcept
{
return m_deleter;
}
template::value || std::is_nothrow_copy_assignable::value)
&& (std::is_nothrow_copy_assignable::value || std::is_nothrow_copy_assignable::value), int> = 0
>
unique_resource& operator=(unique_resource&& other)
{
if( this != &other )
{
reset();
m_resource = std::forward(other.m_resource);
m_deleter = std::forward(other.m_deleter);
m_execute_on_destruction = std::exchange(other.m_execute_on_destruction, false);
}
return *this;
}
unique_resource& operator=(const unique_resource&) = delete;
private:
R m_resource;
D m_deleter;
bool m_execute_on_destruction;
};
template
unique_resource, std::decay_t> make_unique_resource(R&& r, D&& d)
noexcept(std::is_nothrow_constructible, R>::value
&& std::is_nothrow_constructible, D>::value)
{
return unique_resource, std::decay_t>{std::forward(r), std::forward(d)};
}
template
unique_resource> make_unique_resource(std::reference_wrapper r, D d)
noexcept(std::is_nothrow_constructible, D>::value)
{
return unique_resource>(r.get(), std::forward(d));
}
template
unique_resource, std::decay_t> make_unique_resource_checked(R&& r, const S& invalid, D&& d)
noexcept(std::is_nothrow_constructible, R>::value
&& std::is_nothrow_constructible, D>::value)
{
const bool mustRelease{r == invalid};
auto ur = make_unique_resource(r, d);
if( mustRelease == true )
{
ur.release();
}
return ur;
}
}
| |