Add the invoker for result<...>

This commit is contained in:
Denis Blank 2018-11-26 02:19:16 +01:00
parent ba9ff9fce0
commit 9955f9e469
4 changed files with 34 additions and 14 deletions

View File

@ -37,6 +37,7 @@
#include <continuable/detail/utility/flat-variant.hpp>
#include <continuable/detail/utility/result-trait.hpp>
#include <continuable/detail/utility/traits.hpp>
#include <continuable/detail/utility/util.hpp>
namespace cti {
/// \defgroup Result Result

View File

@ -39,6 +39,7 @@
#include <continuable/detail/core/hints.hpp>
#include <continuable/detail/core/types.hpp>
#include <continuable/detail/features.hpp>
#include <continuable/detail/utility/result-trait.hpp>
#include <continuable/detail/utility/traits.hpp>
#include <continuable/detail/utility/util.hpp>
@ -260,23 +261,23 @@ auto invoker_of(traits::identity<result<Args...>>) {
result<Args...> result =
util::partial_invoke(std::forward<decltype(callback)>(callback),
std::forward<decltype(args)>(args)...);
//
if (result.is_value()) {
// Workaround for MSVC not capturing the reference
// correctly inside the lambda.
using Next = decltype(next_callback);
traits::unpack(
[&](auto&&... types) {
/// TODO Add inplace resolution here
invoke_no_except(std::forward<Next>(next_callback),
std::forward<decltype(types)>(types)...);
},
std::move(result));
result_trait<Args...>::visit(
std::move(result), //
[&](auto&&... values) {
invoke_no_except(std::forward<Next>(next_callback),
std::forward<decltype(values)>(values)...);
});
} else if (result.is_exception()) {
// Forward the exception to the next available handler
invoke_no_except(
std::forward<decltype(next_callback)>(next_callback),
exception_arg_t{}, std::move(result).get_exception());
}
// Otherwise the result is empty and we are cancelling our
@ -300,11 +301,9 @@ inline auto sequenced_unpack_invoker() {
using Next = decltype(next_callback);
traits::unpack(
[&](auto&&... types) {
/// TODO Add inplace resolution here
[&](auto&&... values) {
invoke_no_except(std::forward<Next>(next_callback),
std::forward<decltype(types)>(types)...);
std::forward<decltype(values)>(values)...);
},
std::move(result));
CONTINUABLE_BLOCK_TRY_END

View File

@ -359,6 +359,9 @@ private:
#endif
}
detail::slot_t get_slot() const noexcept {
// Check for invalid values especially for memory corruption,
// the empty element is included.
assert(this->slot_ <= sizeof...(T));
return this->slot_;
}
bool is_slot(detail::slot_t const slot) const noexcept {

View File

@ -36,6 +36,7 @@
#include <utility>
#include <continuable/detail/core/hints.hpp>
#include <continuable/detail/utility/traits.hpp>
#include <continuable/detail/utility/util.hpp>
namespace cti {
namespace detail {
@ -52,6 +53,10 @@ struct result_trait<> {
static constexpr void unwrap(surrogate_t) {
}
template <typename Result, typename Mapper>
static void visit(Result&& /*result*/, Mapper&& /*mapper*/) {
}
};
template <typename T>
struct result_trait<T> {
@ -66,6 +71,12 @@ struct result_trait<T> {
static decltype(auto) unwrap(R&& unwrap) {
return std::forward<R>(unwrap);
}
template <typename Result, typename Mapper>
static auto visit(Result&& result, Mapper&& mapper) {
return util::invoke(std::forward<Mapper>(mapper),
std::forward<Result>(result).get_value());
}
};
template <typename First, typename Second, typename... Rest>
struct result_trait<First, Second, Rest...> {
@ -81,6 +92,12 @@ struct result_trait<First, Second, Rest...> {
static decltype(auto) unwrap(R&& unwrap) {
return std::forward<R>(unwrap);
}
template <typename Result, typename Mapper>
static auto visit(Result&& result, Mapper&& mapper) {
return traits::unpack(std::forward<Mapper>(mapper),
std::forward<Result>(result).get_value());
}
};
} // namespace detail
} // namespace cti