| return std::forward<T>(value); | return std::forward<T>(value); | ||||
| } | } | ||||
| template<class T, class U> | |||||
| constexpr T&& cast(U&& u) | |||||
| { | |||||
| return static_cast<T&&>(const_cast<T&&>(u)); | |||||
| } | |||||
| // TODO: make class and fix noexcept's | // TODO: make class and fix noexcept's | ||||
| template<class T> | template<class T> | ||||
| struct Wrapper | struct Wrapper | ||||
| { | { | ||||
| template<class TT, class G, std::enable_if_t<std::is_constructible<T, TT>::value, int> = 0> | template<class TT, class G, std::enable_if_t<std::is_constructible<T, TT>::value, int> = 0> | ||||
| explicit Wrapper(TT&& value, G&& g) : Wrapper(static_cast<T&&>(value)) | |||||
| explicit Wrapper(TT&& value, G&& g) : Wrapper(cast<T&&>(value)) | |||||
| { | { | ||||
| g.release(); | g.release(); | ||||
| } | } | ||||
| return m_value; | return m_value; | ||||
| } | } | ||||
| void reset(T&& newValue) | |||||
| { | |||||
| m_value = move_assign_if_noexcept(newValue); | |||||
| } | |||||
| void reset(const T& newValue) | |||||
| { | |||||
| m_value = newValue; | |||||
| } | |||||
| private: | private: | ||||
| Wrapper(const T& value) : m_value(value) | Wrapper(const T& value) : m_value(value) | ||||
| template<class T> | template<class T> | ||||
| struct Wrapper<T&> | struct Wrapper<T&> | ||||
| { | { | ||||
| template<class TT, class G, std::enable_if_t<std::is_constructible<T, TT>::value, int> = 0> | |||||
| explicit Wrapper(TT&& value, G&& g) : Wrapper(static_cast<T&>(value)) | |||||
| template<class TT, class G, std::enable_if_t<std::is_convertible<TT, T&>::value, int> = 0> | |||||
| explicit Wrapper(TT&& value, G&& g) : m_value(cast<T&>(value)) | |||||
| { | { | ||||
| g.release(); | g.release(); | ||||
| } | } | ||||
| { | { | ||||
| auto se = make_scope_exit([this, &r] { get_deleter()(r); }); | auto se = make_scope_exit([this, &r] { get_deleter()(r); }); | ||||
| reset(); | reset(); | ||||
| m_resource = move_assign_if_noexcept(r); | |||||
| m_resource.reset(std::forward<RR>(r)); | |||||
| m_execute_on_destruction = true; | m_execute_on_destruction = true; | ||||
| se.release(); | se.release(); | ||||
| } | } | ||||
| } | } | ||||
| template<class RR = R, class DD = D, | |||||
| std::enable_if_t<(std::is_nothrow_move_assignable<RR>::value || std::is_nothrow_copy_assignable<RR>::value) | |||||
| && (std::is_nothrow_copy_assignable<DD>::value || std::is_nothrow_copy_assignable<DD>::value), int> = 0 | |||||
| > | |||||
| unique_resource& operator=(unique_resource&& other) | |||||
| { | |||||
| if( this != &other ) | |||||
| { | |||||
| reset(); | |||||
| m_resource = std::forward<RR>(other.m_resource); | |||||
| m_deleter = std::forward<DD>(other.m_deleter); | |||||
| m_execute_on_destruction = std::exchange(other.m_execute_on_destruction, false); | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| //template<class RR = R, class DD = D, | |||||
| //std::enable_if_t<(std::is_nothrow_move_assignable<RR>::value || std::is_nothrow_copy_assignable<RR>::value) | |||||
| //&& (std::is_nothrow_copy_assignable<DD>::value || std::is_nothrow_copy_assignable<DD>::value), int> = 0 | |||||
| //> | |||||
| //unique_resource& operator=(unique_resource&& other) | |||||
| //{ | |||||
| //if( this != &other ) | |||||
| //{ | |||||
| //reset(); | |||||
| //m_resource = std::forward<RR>(other.m_resource); | |||||
| //m_deleter = std::forward<DD>(other.m_deleter); | |||||
| //m_execute_on_destruction = std::exchange(other.m_execute_on_destruction, false); | |||||
| //} | |||||
| //return *this; | |||||
| //} | |||||
| // FIXME: Needs update | |||||
| unique_resource& operator=(unique_resource&&) = default; | |||||
| unique_resource& operator=(const unique_resource&) = delete; | unique_resource& operator=(const unique_resource&) = delete; | ||||