diff --git a/src/crimson/common/errorator.h b/src/crimson/common/errorator.h index fbeeb39145f..a3c26a6128c 100644 --- a/src/crimson/common/errorator.h +++ b/src/crimson/common/errorator.h @@ -8,6 +8,7 @@ #include +#include "crimson/common/utility.h" #include "include/ceph_assert.h" namespace crimson::interruptible { @@ -667,6 +668,19 @@ private: errorator_type::pass_further{}); } + template + auto safe_then_unpack(ValueFunc&& value_func, + ErrorFuncs&&... error_funcs) { + return safe_then( + [value_func=std::move(value_func)] (ValueT&& tuple) mutable { + assert_moveable(value_func); + return std::apply(std::move(value_func), std::move(tuple)); + }, + std::forward(error_funcs)... + ); + } + template void then(Func&&) = delete; diff --git a/src/crimson/common/utility.h b/src/crimson/common/utility.h index 42c199a959d..6fc50bb1c1a 100644 --- a/src/crimson/common/utility.h +++ b/src/crimson/common/utility.h @@ -5,12 +5,16 @@ #include +namespace _impl { + template struct always_false : std::false_type {}; +}; + template void assert_moveable(T& t) { // It's fine } template void assert_moveable(const T& t) { - static_assert(always_false::value, "unable to move-out from T"); + static_assert(_impl::always_false::value, "unable to move-out from T"); }