diff --git a/NextGen.cpp b/NextGen.cpp index 2d908dd..a7912e8 100644 --- a/NextGen.cpp +++ b/NextGen.cpp @@ -108,6 +108,7 @@ auto appendHandlerToContinuation(Continuation&& cont, Handler&& handler) { }; } */ +#include #include #include #include @@ -141,25 +142,28 @@ auto applyTuple(std::integer_sequence, T&& tuple, F&& function) { class Ownership { public: Ownership() { } + explicit Ownership(bool isOwning_) : isOwning(isOwning_) { } Ownership(Ownership const&) = default; explicit Ownership(Ownership&& right) noexcept - : isOwningThis(std::exchange(right.isOwningThis, false)) { }; + : isOwning(std::exchange(right.isOwning, false)) { }; Ownership& operator = (Ownership const&) = default; Ownership& operator = (Ownership&& right) noexcept { - isOwningThis = std::exchange(right.isOwningThis, false); + isOwning = std::exchange(right.isOwning, false); return *this; } + Ownership operator&& (Ownership right) const { + return Ownership(hasOwnership() && right.hasOwnership()); + } + bool hasOwnership() const noexcept { - return isOwningThis; + return isOwning; } - void invalidate() { - isOwningThis = false; + isOwning = false; } - private: - bool isOwningThis{ true }; + bool isOwning{ true }; }; /// Decorates single values @@ -220,7 +224,7 @@ struct CallbackResultDecorator> { /// Create the proxy callback that is responsible for invoking /// the real callback and passing the next continuation into -/// to the result of the callback. +/// the result of the following callback. template auto createProxyCallback(Callback&& callback, Next&& next) { @@ -304,10 +308,12 @@ public: using Config = typename Data::Config; /// Return a r-value reference to the data + template Data&& undecorate()&& { return std::move(data); } /// Return a copy of the data + template Data undecorate() const& { return data; } @@ -316,6 +322,42 @@ private: Data data; }; +template +class LazyCombineDecoration { +public: + // TODO + explicit LazyCombineDecoration(Ownership ownership_, Combined combined_) + : ownership(std::move(ownership_)), combined(std::move(combined_)) { } + + // using Config = typename Data::Config; + + /// Return a r-value reference to the data + template + void undecorate()&& { + } + template + /// Return a copy of the data + void undecorate() const& { + } + + template + auto merge(RightLazyCombine&& right) { + + } + +private: + Ownership ownership; + Combined combined; +}; + +template +struct is_lazy_combined + : std::false_type { }; + +template +struct is_lazy_combined> + : std::true_type { }; + template auto make_continuable(Continuation&& continuation, Dispatcher&& dispatcher = SelfDispatcher{}) noexcept { @@ -356,6 +398,27 @@ auto postImpl(Data data ,NewDispatcher&& newDispatcher) { })); } +template +auto convertToLazyCombine(std::true_type /*is_lazy_combined*/, + Decoration&& decoration) { + return std::forward(decoration); +} + +template +auto convertToLazyCombine(std::false_type /*is_lazy_combined*/, + Decoration&& decoration) { + return LazyCombineDecoration>{}; +} + +template +auto combineImpl(LeftDecoration&& leftDecoration, + RightDecoration&& rightDecoration) { + return convertToLazyCombine(is_lazy_combined>{}, + std::forward(leftDecoration)) + .add(convertToLazyCombine(is_lazy_combined>{}, + std::forward(rightDecoration))); + } + template class ContinuableBase { template @@ -367,33 +430,53 @@ public: ~ContinuableBase() { // Undecorate/materialize the decoration - invokeContinuation(std::move(decoration).undecorate()); + invokeContinuation(std::move(decoration).template undecorate()); } ContinuableBase(ContinuableBase&&) = default; ContinuableBase(ContinuableBase const&) = default; template auto then(Callback&& callback)&& { - return thenImpl(std::move(decoration).undecorate(), + return thenImpl(std::move(decoration).template undecorate(), std::forward(callback)); } template auto then(Callback&& callback) const& { - return thenImpl(decoration.undecorate(), + return thenImpl(decoration.undecorate(), std::forward(callback)); } - template + /*template auto post(NewDispatcher&& newDispatcher)&& { - return postImpl(std::move(decoration).undecorate(), + return postImpl(std::move(decoration).template undecorate(), std::forward(newDispatcher)); } template auto post(NewDispatcher&& newDispatcher) const& { - return postImpl(decoration.undecorate(), + return postImpl(decoration.template undecorate(), std::forward(newDispatcher)); + }*/ + + template + auto operator&& (ContinuableBase&& right)&& { + return combineImpl(std::move(decoration), std::move(right.decoration)); + } + + template + auto operator&& (ContinuableBase const& right)&& { + return combineImpl(std::move(decoration), right.decoration); + } + + template + auto operator&& (ContinuableBase&& right) const& { + return combineImpl(decoration, std::move(right.decoration)); + } + + template + auto operator&& (ContinuableBase const& right) const& { + return combineImpl(decoration, right.decoration); } private: @@ -405,20 +488,50 @@ private: }; static auto makeTestContinuation() { - return make_continuable([](auto&& callback) { + return make_continuable([i = std::make_unique(0)](auto&& callback) { callback("47"); }); } +struct Inspector { + template + auto operator() (Args...) { + return std::common_type>{}; + } +}; + +template +struct FailIfWrongArgs { + template + auto operator() (Args...) + -> std::enable_if_t { } +}; + int main(int, char**) { auto dispatcher = SelfDispatcher{}; + auto unwrap = [](auto&& callback) { + + callback("47"); + }; + + /*auto unwrapper = [](auto&&... args) { + return std::common_type>{}; + };*/ + + using T = decltype(unwrap(FailIfWrongArgs<0>{})); + + // using T = decltype(unwrap(std::declval())); + // T t{}; + + // auto combined = makeTestContinuation() && makeTestContinuation(); + int res = 0; makeTestContinuation() - .post(dispatcher) .then([](std::string /*str*/) { return std::make_tuple(47, 46, 45); }) + // .post(dispatcher) .then([](int val1, int val2, int val3) { return val1 + val2 + val3; })