From: Radoslaw Zarzynski Date: Thu, 12 Sep 2019 12:34:01 +0000 (+0200) Subject: crimson: decouple errorator from unthrowable_wrapper::instance. X-Git-Tag: v15.1.0~801^2~38 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a0c71e0825b89bc60a80a6b6b085f63c6cbccfe6;p=ceph.git crimson: decouple errorator from unthrowable_wrapper::instance. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index 2f52bd8215f6..411a3b979128 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -29,12 +29,6 @@ struct unthrowable_wrapper { static constexpr unthrowable_wrapper instance{}; template friend const T& make_error(); - // comparison operator for the static_assert in future's ctor. - template <_impl::ct_error OtherErrorV> - constexpr bool operator==(const unthrowable_wrapper&) const { - return OtherErrorV == ErrorV; - } - private: // can be used only to initialize the `instance` member explicit unthrowable_wrapper() = default; @@ -45,7 +39,7 @@ template [[nodiscard]] const T& make_error() { } // TODO: let `exception` use other type than `ct_error`. -template <_impl::ct_error V> +template class exception { exception() = default; public: @@ -65,9 +59,9 @@ public: errfunc(std::forward(errfunc)) { } - template <_impl::ct_error ErrorV> - void operator()(const unthrowable_wrapper& e) { - static_assert(std::is_invocable::value, + template + void handle() { + static_assert(std::is_invocable::value, "provided Error Visitor is not exhaustive"); // In C++ throwing an exception isn't the sole way to signal // error with it. This approach nicely fits cold, infrequent cases @@ -88,15 +82,15 @@ public: // It should be available both in GCC and Clang but a fallback // (based on `std::rethrow_exception()` and `catch`) can be made // to handle other platforms if necessary. - if (type_info == typeid(exception)) { + if (type_info == typeid(exception)) { // set `state::invalid` in internals of `seastar::future` to not // call `report_failed_future()` during `operator=()`. std::move(result).get_exception(); constexpr bool explicitly_discarded = std::is_invocable_r< - struct ignore_marker_t&&, ErrorVisitorT, decltype(e)>::value; + struct ignore_marker_t&&, ErrorVisitorT, ErrorT>::value; if constexpr (!explicitly_discarded) { - result = std::forward(errfunc)(e); + result = std::forward(errfunc)(ErrorT::instance); } } } @@ -223,17 +217,17 @@ struct errorator { // per type created on start-up. template <_impl::ct_error ErrorV> future(const unthrowable_wrapper& e) - : base_t(seastar::make_exception_future(exception{})) { + : base_t(seastar::make_exception_future(exception>{})) { // this is `fold expression` of C++17 - static_assert((... || (e == WrappedAllowedErrorsT::instance)), + static_assert((... || (std::is_same_v, + WrappedAllowedErrorsT>)), "disallowed ct_error"); } template auto safe_then(ValueFuncT&& valfunc, ErrorVisitorT&& errfunc) { - static_assert((... && std::is_invocable_v< - ErrorVisitorT, - decltype(WrappedAllowedErrorsT::instance)>), + static_assert((... && std::is_invocable_v), "provided Error Visitor is not exhaustive"); using value_func_result_t = std::invoke_result_t; @@ -247,7 +241,7 @@ struct errorator { using return_errorator_t = make_errorator_t< value_func_errorator_t, std::decay_t>...>; + ErrorVisitorT, WrappedAllowedErrorsT>>...>; // OK, now we know about all errors next continuation must take // care about. If Visitor handled everything and the Value Func // doesn't return any, we'll finish with errorator<>::future @@ -271,7 +265,7 @@ struct errorator { std::forward(errfunc), std::move(future).get_exception() ); - (maybe_handle_error(WrappedAllowedErrorsT::instance) , ...); + (maybe_handle_error.template handle() , ...); return plainify(std::move(maybe_handle_error).get_result()); } else { return plainify(futurator_t::apply(std::forward(valfunc), @@ -297,19 +291,21 @@ struct errorator { // the visitor that forwards handling of all errors to next continuation struct pass_further { - template <_impl::ct_error ErrorV> - const auto& operator()(const unthrowable_wrapper& e) { - static_assert((... || (e == WrappedAllowedErrorsT::instance)), - "passing further disallowed ct_error"); - return ::crimson::make_error>(); + template + decltype(auto) operator()(ErrorT&& e) { + using decayed_t = std::decay_t; + static_assert((... || std::is_same_v), + "passing further disallowed ErrorT"); + return std::forward(e); } }; struct discard_all { - template <_impl::ct_error ErrorV> - auto operator()(const unthrowable_wrapper& e) { - static_assert((... || (e == WrappedAllowedErrorsT::instance)), - "discarding disallowed ct_error"); + template + decltype(auto) operator()(ErrorT&&) { + static_assert((... || std::is_same_v>), + "discarding disallowed ErrorT"); return ignore_marker_t{}; } }; @@ -323,7 +319,7 @@ struct errorator { template struct is_carried { static constexpr bool value = \ - ((WrappedAllowedErrorsT::instance == ErrorT::instance) || ...); + ((std::is_same_v) || ...); }; template static constexpr bool is_carried_v = is_carried::value;