Make it possible to apply transformations through pipes

This commit is contained in:
Denis Blank 2018-02-10 01:37:38 +01:00
parent e4ef3ccefb
commit 951155bc34
4 changed files with 51 additions and 10 deletions

View File

@ -392,6 +392,22 @@ public:
return std::move(*this).then(std::forward<T>(right)); return std::move(*this).then(std::forward<T>(right));
} }
/// The pipe operator | is an alias for the continuable::apply method.
///
/// \param transform The transformer which is applied.
///
/// \returns See the corresponding continuable_base::apply method for the
/// explanation of the return type.
///
/// \note You may create your own transformation through
/// calling make_transformation.
///
/// \since 3.0.0
template <typename T>
auto operator|(detail::types::transform<T> transform) && {
return std::move(*this).apply(std::move(transform));
}
/// Invokes both continuable_base objects parallel and calls the /// Invokes both continuable_base objects parallel and calls the
/// callback with the result of both continuable_base objects. /// callback with the result of both continuable_base objects.
/// ///

View File

@ -32,8 +32,23 @@
#define CONTINUABLE_TRANSFORMS_HPP_INCLUDED #define CONTINUABLE_TRANSFORMS_HPP_INCLUDED
#include <continuable/detail/transforms.hpp> #include <continuable/detail/transforms.hpp>
#include <continuable/detail/types.hpp>
namespace cti { namespace cti {
/// A callable tag object which marks a wrapped callable object
/// as continuable transformation which enables some useful overloads.
///
/// \since 3.0.0
using detail::types::transform;
/// Wraps the given callable object into a transform class.
///
/// \since 3.0.0
template <typename T>
auto make_transform(T&& callable) {
return transform<std::decay_t<T>>(std::forward<T>(callable));
}
/// The namespace transforms declares callable objects that transform /// The namespace transforms declares callable objects that transform
/// any continuable_base to an object or to a continuable_base itself. /// any continuable_base to an object or to a continuable_base itself.
/// ///
@ -61,10 +76,10 @@ namespace transforms {
/// ///
/// \since 2.0.0 /// \since 2.0.0
inline auto futurize() { inline auto futurize() {
return [](auto&& continuable) { return make_transform([](auto&& continuable) {
using detail::transforms::as_future; using detail::transforms::as_future;
return as_future(std::forward<decltype(continuable)>(continuable)); return as_future(std::forward<decltype(continuable)>(continuable));
}; });
} }
/// Returns a transform that if applied to a continuable, it will ignores all /// Returns a transform that if applied to a continuable, it will ignores all
@ -77,9 +92,9 @@ inline auto futurize() {
/// ///
/// \since 2.0.0 /// \since 2.0.0
inline auto flatten() { inline auto flatten() {
return [](auto&& continuable) { return make_transform([](auto&& continuable) {
return std::forward<decltype(continuable)>(continuable).fail([](auto&&) {}); return std::forward<decltype(continuable)>(continuable).fail([](auto&&) {});
}; });
} }
} // namespace transforms } // namespace transforms
} // namespace cti } // namespace cti

View File

@ -31,6 +31,8 @@
#ifndef CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED #ifndef CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED
#define CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED #define CONTINUABLE_DETAIL_TYPES_HPP_INCLUDED
#include <utility>
#include <continuable/detail/features.hpp> #include <continuable/detail/features.hpp>
#ifndef CONTINUABLE_WITH_CUSTOM_ERROR_TYPE #ifndef CONTINUABLE_WITH_CUSTOM_ERROR_TYPE
@ -65,6 +67,16 @@ struct this_thread_executor_tag {};
/// A tag which is used to continue with an error /// A tag which is used to continue with an error
struct dispatch_error_tag {}; struct dispatch_error_tag {};
/// Marks a given callable object as transformation
template <typename T>
class transform : T {
public:
explicit transform(T callable) : T(std::move(callable)) {
}
using T::operator();
};
} // namespace types } // namespace types
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti

View File

@ -56,12 +56,10 @@ TYPED_TEST(single_dimension_tests, are_convertible_to_futures) {
{ {
auto canary = std::make_tuple(0xFD, 0xF5); auto canary = std::make_tuple(0xFD, 0xF5);
auto future = this->supply() auto future = this->supply().then([&] {
.then([&] { // ...
// ... return canary;
return canary; }) | cti::transforms::futurize();
})
.apply(cti::transforms::futurize());
ASSERT_TRUE(is_ready(future)); ASSERT_TRUE(is_ready(future));
EXPECT_EQ(future.get(), canary); EXPECT_EQ(future.get(), canary);