Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef SCOPE
- #define SCOPE
- #include <exception>
- #include <type_traits>
- namespace xstd
- {
- // scope_exit
- template <class EF>
- class scope_exit
- {
- EF ef_;
- bool execute_ = true;
- public:
- ~scope_exit();
- scope_exit(scope_exit&& rhs) noexcept;
- explicit scope_exit(EF f) noexcept;
- void release() noexcept;
- };
- template <class EF>
- inline
- scope_exit<EF>::~scope_exit()
- {
- if (execute_)
- ef_();
- }
- template <class EF>
- inline
- scope_exit<EF>::scope_exit(scope_exit&& rhs) noexcept
- : ef_(std::forward<EF>(rhs.ef_))
- , execute_(rhs.execute_)
- {
- rhs.release();
- }
- template <class EF>
- inline
- scope_exit<EF>::scope_exit(EF f) noexcept
- : ef_(std::forward<EF>(f))
- {
- }
- template <class EF>
- inline
- void
- scope_exit<EF>::release() noexcept
- {
- execute_ = false;
- }
- // make_scope_xxx
- template <class EF>
- inline
- scope_exit<EF>
- make_scope_exit(EF ef) noexcept
- {
- return scope_exit<EF>{std::move(ef)};
- }
- template <class EF>
- auto
- make_scope_fail(EF ef) noexcept
- {
- return make_scope_exit([ef = std::move(ef), ec = std::uncaught_exceptions()]
- {
- if (ec < std::uncaught_exceptions())
- ef();
- });
- }
- template <class EF>
- auto
- make_scope_success(EF ef) noexcept
- {
- return make_scope_exit([ef = std::move(ef), ec = std::uncaught_exceptions()]
- {
- if (!(ec < std::uncaught_exceptions()))
- ef();
- });
- }
- // unique_resource
- template<class R, class D>
- class unique_resource
- {
- R r_;
- D d_;
- bool execute_;
- public:
- ~unique_resource();
- unique_resource(unique_resource&& rhs) noexcept;
- unique_resource& operator=(unique_resource&& rhs) noexcept;
- unique_resource(R r, D d) noexcept;
- void reset();
- void reset(R r);
- R release() noexcept;
- R const& get() const noexcept;
- operator R const& () const noexcept;
- template <class Constraint = std::integral_constant<bool, std::is_pointer<R>::value &&
- (std::is_class<std::remove_pointer_t<R>>::value ||
- std::is_union<std::remove_pointer_t<R>>::value)>>
- std::enable_if_t<Constraint::value, R>
- operator->() const noexcept;
- template <class T = void, class Constraint = std::enable_if_t<std::is_void<T>::value &&
- std::is_pointer<R>::value>>
- decltype(auto)
- operator* () const noexcept;
- const D& get_deleter() const noexcept;
- };
- template<class R, class D>
- inline
- unique_resource<R, D>::~unique_resource()
- {
- reset();
- }
- template<class R, class D>
- inline
- unique_resource<R, D>::unique_resource(unique_resource&& rhs) noexcept
- : r_(std::move(rhs.r_))
- , d_(std::move(rhs.d_))
- , execute_(std::move(rhs.execute_))
- {
- rhs.release();
- }
- template<class R, class D>
- unique_resource<R, D>&
- unique_resource<R, D>::operator=(unique_resource&& rhs) noexcept
- {
- reset();
- r_ = std::move(rhs.r_);
- d_ = std::move(rhs.d_);
- execute_ = std::move(rhs.execute_);
- rhs.release();
- return *this;
- }
- template<class R, class D>
- inline
- unique_resource<R, D>::unique_resource(R r, D d) noexcept
- : r_(std::move(r))
- , d_(std::move(d))
- , execute_(true)
- {
- }
- template<class R, class D>
- inline
- void
- unique_resource<R, D>::reset()
- {
- if (execute_)
- {
- execute_ = false;
- d_(r_);
- }
- }
- template<class R, class D>
- inline
- void
- unique_resource<R, D>::reset(R r)
- {
- reset();
- r_ = std::move(r);
- execute_ = true;
- }
- template<class R, class D>
- inline
- R
- unique_resource<R, D>::release() noexcept
- {
- execute_ = false;
- return std::move(r_);
- }
- template<class R, class D>
- inline
- R const&
- unique_resource<R, D>::get() const noexcept
- {
- return r_;
- }
- template<class R, class D>
- inline
- unique_resource<R, D>::operator R const& () const noexcept
- {
- return r_;
- }
- template<class R, class D>
- template <class Constraint>
- inline
- std::enable_if_t<Constraint::value, R>
- unique_resource<R, D>::operator->() const noexcept
- {
- return r_;
- }
- template<class R, class D>
- template <class T, class Constraint>
- inline
- decltype(auto)
- unique_resource<R, D>::operator* () const noexcept
- {
- return *r_;
- }
- template<class R, class D>
- inline
- const D&
- unique_resource<R, D>::get_deleter() const noexcept
- {
- return d_;
- }
- template<class R,class D>
- inline
- unique_resource<R, D>
- make_unique_resource(R r, D d) noexcept
- {
- return unique_resource<R, D>{std::move(r), std::move(d)};
- }
- template<class R, class D, class RI = R>
- inline
- unique_resource<R, D>
- make_unique_resource_checked(R r, RI invalid, D d) noexcept
- {
- auto ur = unique_resource<R,D>(std::move(r), std::move(d));
- if (static_cast<bool>(r == invalid))
- ur.release();
- return ur;
- }
- } // namespace xstd
- #endif // SCOPE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement