Merge pull request #4 from BlackMATov/dev

Dev
This commit is contained in:
2023-03-01 16:49:04 +07:00
committed by GitHub

View File

@@ -11,21 +11,19 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
namespace defer_hpp namespace defer_hpp::impl
{
namespace impl
{ {
template < typename F, typename... Args > template < typename F, typename... Args >
class base_defer_t { class defer_impl {
public: public:
base_defer_t() = delete; defer_impl() = delete;
base_defer_t(base_defer_t&&) = delete; defer_impl(defer_impl&&) = delete;
base_defer_t(const base_defer_t&) = delete; defer_impl(const defer_impl&) = delete;
base_defer_t& operator=(base_defer_t&&) = delete; defer_impl& operator=(defer_impl&&) = delete;
base_defer_t& operator=(const base_defer_t&) = delete; defer_impl& operator=(const defer_impl&) = delete;
template < typename UF > template < typename UF >
explicit base_defer_t(UF&& f, std::tuple<Args...>&& args) explicit defer_impl(UF&& f, std::tuple<Args...>&& args)
: f_{std::forward<UF>(f)} : f_{std::forward<UF>(f)}
, args_{std::move(args)} {} , args_{std::move(args)} {}
@@ -34,7 +32,7 @@ namespace defer_hpp
} }
protected: protected:
~base_defer_t() noexcept { ~defer_impl() noexcept {
if ( !dismissed_ ) { if ( !dismissed_ ) {
std::apply(std::move(f_), std::move(args_)); std::apply(std::move(f_), std::move(args_));
} }
@@ -47,39 +45,39 @@ namespace defer_hpp
}; };
} }
namespace impl namespace defer_hpp
{ {
template < typename F, typename... Args > template < typename F, typename... Args >
class defer_t final : public base_defer_t<F, Args...> { class defer final : public impl::defer_impl<F, Args...> {
public: public:
defer_t() = delete; defer() = delete;
defer_t(defer_t&&) = delete; defer(defer&&) = delete;
defer_t(const defer_t&) = delete; defer(const defer&) = delete;
defer_t& operator=(defer_t&&) = delete; defer& operator=(defer&&) = delete;
defer_t& operator=(const defer_t&) = delete; defer& operator=(const defer&) = delete;
template < typename UF > template < typename UF >
explicit defer_t(UF&& f, std::tuple<Args...>&& args) explicit defer(UF&& f, std::tuple<Args...>&& args)
: base_defer_t<F, Args...>{std::forward<UF>(f), std::move(args)} {} : impl::defer_impl<F, Args...>{std::forward<UF>(f), std::move(args)} {}
~defer_t() noexcept = default; ~defer() noexcept = default;
}; };
template < typename F, typename... Args > template < typename F, typename... Args >
class error_defer_t final : public base_defer_t<F, Args...> { class error_defer final : public impl::defer_impl<F, Args...> {
public: public:
error_defer_t() = delete; error_defer() = delete;
error_defer_t(error_defer_t&&) = delete; error_defer(error_defer&&) = delete;
error_defer_t(const error_defer_t&) = delete; error_defer(const error_defer&) = delete;
error_defer_t& operator=(error_defer_t&&) = delete; error_defer& operator=(error_defer&&) = delete;
error_defer_t& operator=(const error_defer_t&) = delete; error_defer& operator=(const error_defer&) = delete;
template < typename UF > template < typename UF >
explicit error_defer_t(UF&& f, std::tuple<Args...>&& args) explicit error_defer(UF&& f, std::tuple<Args...>&& args)
: base_defer_t<F, Args...>{std::forward<UF>(f), std::move(args)} : impl::defer_impl<F, Args...>{std::forward<UF>(f), std::move(args)}
, exceptions_{std::uncaught_exceptions()} {} , exceptions_{std::uncaught_exceptions()} {}
~error_defer_t() noexcept { ~error_defer() noexcept {
if ( exceptions_ == std::uncaught_exceptions() ) { if ( exceptions_ == std::uncaught_exceptions() ) {
this->dismiss(); this->dismiss();
} }
@@ -90,20 +88,20 @@ namespace defer_hpp
}; };
template < typename F, typename... Args > template < typename F, typename... Args >
class return_defer_t final : public base_defer_t<F, Args...> { class return_defer final : public impl::defer_impl<F, Args...> {
public: public:
return_defer_t() = delete; return_defer() = delete;
return_defer_t(return_defer_t&&) = delete; return_defer(return_defer&&) = delete;
return_defer_t(const return_defer_t&) = delete; return_defer(const return_defer&) = delete;
return_defer_t& operator=(return_defer_t&&) = delete; return_defer& operator=(return_defer&&) = delete;
return_defer_t& operator=(const return_defer_t&) = delete; return_defer& operator=(const return_defer&) = delete;
template < typename UF > template < typename UF >
explicit return_defer_t(UF&& f, std::tuple<Args...>&& args) explicit return_defer(UF&& f, std::tuple<Args...>&& args)
: base_defer_t<F, Args...>{std::forward<UF>(f), std::move(args)} : impl::defer_impl<F, Args...>{std::forward<UF>(f), std::move(args)}
, exceptions_{std::uncaught_exceptions()} {} , exceptions_{std::uncaught_exceptions()} {}
~return_defer_t() noexcept { ~return_defer() noexcept {
if ( exceptions_ != std::uncaught_exceptions() ) { if ( exceptions_ != std::uncaught_exceptions() ) {
this->dismiss(); this->dismiss();
} }
@@ -112,42 +110,41 @@ namespace defer_hpp
private: private:
int exceptions_{}; int exceptions_{};
}; };
}
template < typename F, typename... Args > template < typename F, typename... Args >
auto make_defer(F&& f, Args&&... args) { auto make_defer(F&& f, Args&&... args) {
using defer_t = impl::defer_t<std::decay_t<F>, std::decay_t<Args>...>; using defer_t = defer<std::decay_t<F>, std::decay_t<Args>...>;
return defer_t{std::forward<F>(f), std::make_tuple(std::forward<Args>(args)...)}; return defer_t{std::forward<F>(f), std::make_tuple(std::forward<Args>(args)...)};
} }
template < typename F, typename... Args > template < typename F, typename... Args >
auto make_error_defer(F&& f, Args&&... args) { auto make_error_defer(F&& f, Args&&... args) {
using defer_t = impl::error_defer_t<std::decay_t<F>, std::decay_t<Args>...>; using defer_t = error_defer<std::decay_t<F>, std::decay_t<Args>...>;
return defer_t{std::forward<F>(f), std::make_tuple(std::forward<Args>(args)...)}; return defer_t{std::forward<F>(f), std::make_tuple(std::forward<Args>(args)...)};
} }
template < typename F, typename... Args > template < typename F, typename... Args >
auto make_return_defer(F&& f, Args&&... args) { auto make_return_defer(F&& f, Args&&... args) {
using defer_t = impl::return_defer_t<std::decay_t<F>, std::decay_t<Args>...>; using defer_t = return_defer<std::decay_t<F>, std::decay_t<Args>...>;
return defer_t{std::forward<F>(f), std::make_tuple(std::forward<Args>(args)...)}; return defer_t{std::forward<F>(f), std::make_tuple(std::forward<Args>(args)...)};
} }
} }
#define DEFER_HPP_IMPL_PP_CAT(x, y) DEFER_HPP_IMPL_PP_CAT_I(x, y) #define DEFER_HPP_PP_CAT(x, y) DEFER_HPP_PP_CAT_I(x, y)
#define DEFER_HPP_IMPL_PP_CAT_I(x, y) x##y #define DEFER_HPP_PP_CAT_I(x, y) x##y
#ifdef __COUNTER__ #ifdef __COUNTER__
# define DEFER_HPP(...) \ # define DEFER_HPP(...) \
auto DEFER_HPP_IMPL_PP_CAT(defer_hpp_generated_defer_, __COUNTER__) { ::defer_hpp::make_defer(__VA_ARGS__) } auto DEFER_HPP_PP_CAT(defer_hpp_generated_defer_, __COUNTER__) { ::defer_hpp::make_defer(__VA_ARGS__) }
# define ERROR_DEFER_HPP(...) \ # define ERROR_DEFER_HPP(...) \
auto DEFER_HPP_IMPL_PP_CAT(defer_hpp_generated_error_defer_, __COUNTER__) { ::defer_hpp::make_error_defer(__VA_ARGS__) } auto DEFER_HPP_PP_CAT(defer_hpp_generated_error_defer_, __COUNTER__) { ::defer_hpp::make_error_defer(__VA_ARGS__) }
# define RETURN_DEFER_HPP(...) \ # define RETURN_DEFER_HPP(...) \
auto DEFER_HPP_IMPL_PP_CAT(defer_hpp_generated_return_defer_, __COUNTER__) { ::defer_hpp::make_return_defer(__VA_ARGS__) } auto DEFER_HPP_PP_CAT(defer_hpp_generated_return_defer_, __COUNTER__) { ::defer_hpp::make_return_defer(__VA_ARGS__) }
#else #else
# define DEFER_HPP(...) \ # define DEFER_HPP(...) \
auto DEFER_HPP_IMPL_PP_CAT(defer_hpp_generated_defer_, __LINE__) { ::defer_hpp::make_defer(__VA_ARGS__) } auto DEFER_HPP_PP_CAT(defer_hpp_generated_defer_, __LINE__) { ::defer_hpp::make_defer(__VA_ARGS__) }
# define ERROR_DEFER_HPP(...) \ # define ERROR_DEFER_HPP(...) \
auto DEFER_HPP_IMPL_PP_CAT(defer_hpp_generated_error_defer_, __LINE__) { ::defer_hpp::make_error_defer(__VA_ARGS__) } auto DEFER_HPP_PP_CAT(defer_hpp_generated_error_defer_, __LINE__) { ::defer_hpp::make_error_defer(__VA_ARGS__) }
# define RETURN_DEFER_HPP(...) \ # define RETURN_DEFER_HPP(...) \
auto DEFER_HPP_IMPL_PP_CAT(defer_hpp_generated_return_defer_, __LINE__) { ::defer_hpp::make_return_defer(__VA_ARGS__) } auto DEFER_HPP_PP_CAT(defer_hpp_generated_return_defer_, __LINE__) { ::defer_hpp::make_return_defer(__VA_ARGS__) }
#endif #endif