diff --git a/.gitignore b/.gitignore index 883885d..4ab5f87 100644 --- a/.gitignore +++ b/.gitignore @@ -48,4 +48,8 @@ bld/ # Visual Studo 2015 cache/options directory .vs/ +# VSCode .vscode/ + +# TMP files generated from clang-format +*.TMP diff --git a/include/continuable/continuable-base.hpp b/include/continuable/continuable-base.hpp index 4eb930b..63d0305 100644 --- a/include/continuable/continuable-base.hpp +++ b/include/continuable/continuable-base.hpp @@ -92,6 +92,8 @@ template class continuable_base { /// \cond false + using ownership = detail::util::ownership; + template friend class continuable_base; friend struct detail::base::attorney; @@ -104,11 +106,11 @@ class continuable_base { // The continuation type or intermediate result Data data_; // The transferable state which represents the validity of the object - detail::util::ownership ownership_; + ownership ownership_; /// \endcond /// Constructor accepting the data object while erasing the annotation - explicit continuable_base(Data data, detail::util::ownership ownership) + explicit continuable_base(Data data, ownership ownership) : data_(std::move(data)), ownership_(std::move(ownership)) { } @@ -121,7 +123,8 @@ public: /// while erasing the annotation template , Data>::value>* = nullptr> - continuable_base(OData&& data) : data_(std::forward(data)) { + continuable_base(OData&& data) // NOLINT(misc-forwarding-reference-overload) + : data_(std::forward(data)) { } /// Constructor taking the data of other continuable_base objects @@ -131,7 +134,7 @@ public: /// the continuable by any object which is useful for type-erasure. template continuable_base(continuable_base&& other) - : continuable_base(std::move(other).finish().consume_data()) { + : continuable_base(std::move(other).finish().consume()) { } /// \cond false @@ -710,7 +713,7 @@ private: ownership_.release(); } - Data&& consume_data() && { + Data&& consume() && { assert_acquired(); release(); return std::move(data_); @@ -814,7 +817,7 @@ constexpr auto make_continuable(Continuation&& continuation) { "use make_continuable(...). Continuables with an exact " "signature may be created through make_continuable."); - return detail::base::attorney::create( + return detail::base::attorney::create_from( std::forward(continuation), detail::hints::extract(detail::traits::identity{}), detail::util::ownership{}); diff --git a/include/continuable/detail/connection/connection-all.hpp b/include/continuable/detail/connection/connection-all.hpp index abed3c1..3d10720 100644 --- a/include/continuable/detail/connection/connection-all.hpp +++ b/include/continuable/detail/connection/connection-all.hpp @@ -162,7 +162,7 @@ struct connection_finalizer { auto signature = aggregated::hint_of_data(); - return base::attorney::create( + return base::attorney::create_from( [result = std::move(result)](auto&& callback) mutable { using submitter_t = diff --git a/include/continuable/detail/connection/connection-any.hpp b/include/continuable/detail/connection/connection-any.hpp index 6a35176..25be4ac 100644 --- a/include/continuable/detail/connection/connection-any.hpp +++ b/include/continuable/detail/connection/connection-any.hpp @@ -174,7 +174,7 @@ struct connection_finalizer { traversal::container_category_of_t>{}, traits::identity>{})){}; - return base::attorney::create( + return base::attorney::create_from( [connection = std::forward(connection)](auto&& callback) mutable { diff --git a/include/continuable/detail/connection/connection-seq.hpp b/include/continuable/detail/connection/connection-seq.hpp index 7a5b06b..fa5ade3 100644 --- a/include/continuable/detail/connection/connection-seq.hpp +++ b/include/continuable/detail/connection/connection-seq.hpp @@ -142,7 +142,7 @@ struct connection_finalizer { auto signature = aggregated::hint_of_data(); - return base::attorney::create( + return base::attorney::create_from( [result = std::move(result)](auto&& callback) mutable { // The data from which the visitor is constructed in-place using data_t = diff --git a/include/continuable/detail/connection/connection.hpp b/include/continuable/detail/connection/connection.hpp index 13536f9..1fde0c8 100644 --- a/include/continuable/detail/connection/connection.hpp +++ b/include/continuable/detail/connection/connection.hpp @@ -92,7 +92,7 @@ auto normalize(Strategy /*strategy*/, continuable_base&& continuation) { // If we are in the given strategy we can just use the data of the continuable - return base::attorney::consume_data(std::move(continuation)); + return base::attorney::consume(std::move(continuation)); } /// Entry function for connecting two continuables with a given strategy. @@ -114,7 +114,7 @@ auto connect(Strategy strategy, continuable_base&& left, // Return a new continuable containing the tuple and holding // the current strategy as annotation. - return base::attorney::create(std::move(data), strategy, ownership_); + return base::attorney::create_from(std::move(data), strategy, ownership_); } /// All strategies should specialize this class in order to provide: @@ -130,7 +130,7 @@ auto finalize_connection(continuable_base&& continuation) { using finalizer = connection_finalizer; util::ownership ownership = base::attorney::ownership_of(continuation); - auto connection = base::attorney::consume_data(std::move(continuation)); + auto connection = base::attorney::consume(std::move(continuation)); // Return a new continuable which return finalizer::finalize(std::move(connection), std::move(ownership)); diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 5385bfb..9e02b98 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -52,7 +52,7 @@ namespace detail { /// /// Important methods are: /// - Creating a continuation from a callback taking functional -/// base::attorney::create(auto&& callback) +/// base::attorney::create_from(auto&& callback) /// -> base::continuation /// - Chaining a continuation together with a callback /// base::chain_continuation(base::continuation continuation, @@ -67,38 +67,38 @@ struct is_continuable : std::false_type {}; template struct is_continuable> : std::true_type {}; -/// Helper class to access private methods and members of -/// the continuable_base class. struct attorney { - /// Makes a continuation wrapper from the given argument - template - static auto create(T&& continuation, A /*hint*/, util::ownership ownership_) { - return continuable_base, std::decay_t>( - std::forward(continuation), ownership_); - } - - /// Invokes a continuation object in a reference correct way - template - static auto - invoke_continuation(continuable_base&& continuation, - Callback&& callback) noexcept { - auto materialized = std::move(continuation).finish(); - materialized.release(); - return materialized.data_(std::forward(callback)); - } - - template - static Data&& - consume_data(continuable_base&& continuation) { - return std::move(continuation).consume_data(); + /// Creates a continuable_base from the given continuation, annotation + /// and ownership. + template < + typename T, typename A, + typename Continuable = continuable_base, std::decay_t>> + static auto create_from(T&& continuation, A annotation, + util::ownership ownership) { + (void)annotation; + return Continuable(std::forward(continuation), ownership); } + /// Returns the ownership of the given continuable_base template static util::ownership ownership_of(Continuable&& continuation) noexcept { return continuation.ownership_; } + + template + static Data&& consume(continuable_base&& continuation) { + return std::move(continuation).consume(); + } }; +/// Invokes a continuation object in a reference correct way +template +void invoke_continuation(continuable_base&& continuation, + Callback&& callback) noexcept { + util::invoke(attorney::consume(std::move(continuation).finish()), + std::forward(callback)); +} + // Returns the invoker of a callback, the next callback // and the arguments of the previous continuation. // @@ -174,7 +174,7 @@ invoker_of(traits::identity>) { util::partial_invoke(std::forward(callback), std::forward(args)...); - attorney::invoke_continuation( + invoke_continuation( std::move(continuation_), std::forward(next_callback)); CONTINUABLE_BLOCK_TRY_END @@ -480,7 +480,7 @@ struct final_callback : util::non_copyable { } void set_exception(exception_t error) { - // NOLINTNEXTLINE(hicpp-move-const-arg) + // NOLINTNEXTLINE(hicpp-move-const-arg, performance-move-const-arg) std::move (*this)(exception_arg_t{}, std::move(error)); } }; @@ -533,7 +533,7 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback, auto ownership_ = attorney::ownership_of(continuation); continuation.freeze(); - return attorney::create( + return attorney::create_from( [continuation = std::forward(continuation), callback = std::forward(callback), executor = @@ -554,8 +554,7 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback, // Invoke the continuation with a proxy callback. // The proxy callback is responsible for passing // the result to the callback as well as decorating it. - attorney::invoke_continuation(std::move(continuation), - std::move(proxy)); + invoke_continuation(std::move(continuation), std::move(proxy)); }, next_hint, ownership_); } @@ -566,8 +565,8 @@ auto chain_continuation(Continuation&& continuation, Callback&& callback, /// - Continuation: continuation<[](auto&& callback) { callback("hi"); }> template void finalize_continuation(Continuation&& continuation) { - attorney::invoke_continuation(std::forward(continuation), - callbacks::final_callback{}); + invoke_continuation(std::forward(continuation), + callbacks::final_callback{}); } /// Workaround for GCC bug: