diff --git a/dep/googletest/googletest b/dep/googletest/googletest index ecd5308..3447fc3 160000 --- a/dep/googletest/googletest +++ b/dep/googletest/googletest @@ -1 +1 @@ -Subproject commit ecd530865cefdfa7dea58e84f6aa1b548950363d +Subproject commit 3447fc31b4eea1fbcb86fa0e2f5d9ed9f38776bf diff --git a/include/continuable/continuable.hpp b/include/continuable/continuable.hpp index 6e4adaa..cec322b 100644 --- a/include/continuable/continuable.hpp +++ b/include/continuable/continuable.hpp @@ -127,7 +127,7 @@ template struct deduce_to_void : std::common_type { }; template -using always_void_t = typename deduce_to_void::type; +using void_t = typename deduce_to_void::type; struct SelfDispatcher { template @@ -136,19 +136,21 @@ struct SelfDispatcher { } }; -template +template struct Identity { }; template class ContinuableBase; -template -void emptyContinuation(T&& callback) { - std::forward(callback)(); +inline auto emptyContinuation() { + return [](auto&& callback) { + std::forward(callback)(); + }; } -template -void emptyCallback(Args&&... /*arguments*/) { } +inline auto emptyCallback() { + return [](auto&&...) { }; +} template auto applyTuple(std::integer_sequence, T&& tuple, F&& function) { @@ -189,14 +191,14 @@ public: return *this; } - Ownership operator&& (Ownership right) const { + Ownership operator&& (Ownership right) const noexcept { return Ownership(hasOwnership() && right.hasOwnership()); } bool hasOwnership() const noexcept { return isOwning; } - void invalidate() { + void invalidate() noexcept { isOwning = false; } @@ -223,43 +225,61 @@ struct ArgumentsHint : std::false_type { }; using AbsentArgumentsHint = ArgumentsHint; +using EmptyArgumentsHint = ArgumentsHint<>; + template -struct GetArgumentsHint; +struct UnwrapArguments; template -struct GetArgumentsHint +struct UnwrapArguments : std::common_type> { }; /// Mutable function pointers template -struct GetArgumentsHint - : GetArgumentsHint { }; +struct UnwrapArguments + : UnwrapArguments { }; /// Const function pointers template -struct GetArgumentsHint - : GetArgumentsHint { }; +struct UnwrapArguments + : UnwrapArguments { }; /// Mutable class method pointers template -struct GetArgumentsHint - : GetArgumentsHint { }; +struct UnwrapArguments + : UnwrapArguments { }; /// Const class method pointers template -struct GetArgumentsHint - : GetArgumentsHint { }; +struct UnwrapArguments + : UnwrapArguments { }; /// Mutable volatile class method pointers template -struct GetArgumentsHint - : GetArgumentsHint { }; +struct UnwrapArguments + : UnwrapArguments { }; /// Const volatile class method pointers template -struct GetArgumentsHint - : GetArgumentsHint { }; +struct UnwrapArguments + : UnwrapArguments { }; +template +using unwrap_functional_t = std::conditional_t< + std::is_function::value, + UnwrapArguments, + UnwrapArguments +>; + +template +using unwrap_continuation_t = typename unwrap_functional_t< + typename unwrap_functional_t::type::only_argument_type +>::type; + +template +using unwrap_callback_t = AbsentArgumentsHint; + +/* template> struct InferArgumentsFromType : AbsentArgumentsHint { }; +*/ + template -using InferArgumentsFrom = typename InferArgumentsFromType::type; +using InferArgumentsFrom = AbsentArgumentsHint; // typename InferArgumentsFromType::type; /* template @@ -327,7 +349,7 @@ struct CallbackResultDecorator { static auto decorate(Callback&& callback) { return [callback = std::forward(callback)](auto&&... args) { callback(std::forward(args)...); - return emptyContinuation; + return emptyContinuation(); }; } }; @@ -382,11 +404,11 @@ auto appendCallback(Continuation&& continuation, } template -void invokeContinuation(Data data) { +void invokeUndecorated(Data data) { // Check whether the ownership is acquired and start the continuation call if (data.ownership.hasOwnership()) { // Pass an empty callback to the continuation to invoke it - std::move(data.continuation)(emptyCallback); + std::move(data.continuation)(emptyCallback()); } } @@ -456,15 +478,15 @@ public: : data(std::move(data_)) { } /// Return a r-value reference to the data - template + template auto undecorate()&& { - return Undecorator::template undecorate(std::move(data)); + return Undecorator::template undecorate(std::move(data)); } /// Return a copy of the data - template + template auto undecorate() const& { - return Undecorator::template undecorate(data); + return Undecorator::template undecorate(data); } private: @@ -495,24 +517,26 @@ public: template static void requiresUndecorateable() { - static_assert(is_undecorateable::value, + /*static_assert(is_undecorateable::value, "Can't retrieve the signature of the given callback. " "Consider to pass an untemplated function or functor " - "to the `then` method invocation to fix this."); + "to the `then` method invocation to fix this.");*/ } /// Return a r-value reference to the data - template + template void undecorate()&& { - requiresUndecorateable(); - return undecorateCombined(std::move(combined)); + /// TODO + // requiresUndecorateable<>(); + // return undecorateCombined(std::move(combined)); } - template + template /// Return a copy of the data void undecorate() const& { - requiresUndecorateable(); - return undecorateCombined(combined); + /// TODO + // requiresUndecorateable(); + // return undecorateCombined(combined); } template @@ -540,6 +564,11 @@ auto make_continuable(Continuation&& continuation, })); } +template +auto add_type_hint(T&& continuable) { + return std::forward(continuable); +} + template auto thenImpl(Undecorated undecorated, Callback&& callback) { auto next = appendCallback(std::move(undecorated.continuation), @@ -596,20 +625,23 @@ public: ~ContinuableBase() { // Undecorate/materialize the decoration - // invokeContinuation(std::move(decoration).template undecorate()); + invokeUndecorated(std::move(decoration) + .template undecorate()); } ContinuableBase(ContinuableBase&&) = default; ContinuableBase(ContinuableBase const&) = default; template auto then(Callback&& callback)&& { - return thenImpl(std::move(decoration).template undecorate(), + using Hint = unwrap_callback_t; + return thenImpl(std::move(decoration).template undecorate(), std::forward(callback)); } template auto then(Callback&& callback) const& { - return thenImpl(decoration.template undecorate(), + using Hint = unwrap_callback_t; + return thenImpl(decoration.template undecorate(), std::forward(callback)); } diff --git a/incubator.cpp b/incubator.cpp index 736bd47..f3d1709 100644 --- a/incubator.cpp +++ b/incubator.cpp @@ -3,6 +3,7 @@ #include "continuable/continuable.hpp" + template using continuable = decltype(make_continuable(std::declval>)); @@ -12,7 +13,56 @@ static auto makeTestContinuation() { }); } +static auto dnsResolve(std::string) { + return make_continuable([](auto&& callback) { + callback(""); + }); +} + +static auto httpRequestToIp(std::string) { + return make_continuable([](auto&& callback) { + callback(""); + }); +} + +template +static auto flatten(T&& factory) { + return [factory = std::forward(factory)](auto&&... args) { + return factory(std::forward(args)...); + }; +} + +/*static auto httpRequest(std::string url) { + return dnsResolve(url) + .then(flatten(httpRequestToIp)) + .then([](std::string result) { + + }); +}*/ + +struct Debugable { + int i = 5; + + template + void operator() (C&& c) { + std::forward(c)(true); + } +}; + +static auto moveTo() { + /*return make_continuable([](auto&& callback) { + callback(true); + });*/ + + return make_continuable(Debugable{}); +} + int main(int, char**) { + + Debugable deb; + + // moveTo().then([](bool) {}); + // continuable c; auto dispatcher = SelfDispatcher{}; @@ -47,14 +97,11 @@ int main(int, char**) { res += val; }) .then([] { - - - return makeTestContinuation(); }) .then(makeTestContinuation()) .then([] (std::string arg) { - + arg.clear(); }); return res; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 961d8e9..2858ada 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,6 @@ add_executable(continuable-tests - ${CMAKE_CURRENT_LIST_DIR}/test-chaining.cpp) + ${CMAKE_CURRENT_LIST_DIR}/test-chaining.cpp + ${CMAKE_CURRENT_LIST_DIR}/test-unwrap.cpp) target_link_libraries(continuable-tests PRIVATE diff --git a/test/test-unwrap.cpp b/test/test-unwrap.cpp new file mode 100644 index 0000000..e56c405 --- /dev/null +++ b/test/test-unwrap.cpp @@ -0,0 +1,107 @@ +/** +* Copyright 2016 Denis Blank +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include + +#include "gtest/gtest.h" +#include "continuable/continuable.hpp" + +/// Contains helper classes to retrieve the arguments a callback +/// is called with when passing it to the given function. +namespace unwrap { + +} // namespace unwrap + + +/*template> +struct is_compiling + : std::false_type { }; + +template +struct is_compiling()(0))> +> : std::true_type { };*/ + +/* +template +struct CanUnwrap + +template +using CanUnwrapT = +*/ + +template +using is_argument_hint = Identity< + typename unwrap_continuation_t::argument_type, + Identity +>; + +#define EXPECT_ARGUMENTS(FUNCTIONAL, ...) \ + \ + auto functional = FUNCTIONAL; \ + using id = Identity<__VA_ARGS__>; \ + id iiii{}; \ + Identity> argst; /*\ + auto result = is_argument_hint< \ + decltype(functional), __VA_ARGS__ \ + >::value; \ + EXPECT_TRUE(result); \*/ + + +TEST(ContinuableUnwrapTests, FunctionsAreUnwrappable) { + + auto fn = [](std::function) { + + }; + + using tt = typename unwrap_continuation_t::argument_type; + + using tttt = is_argument_hint; + + // auto t = tttt::value; + + // EXPECT_ARGUMENTS(fn, int, int); + + // tt arg; + + // auto tp = typeid(arg).name(); + + /* + auto op = &decltype(fn)::operator(); + + using opt = decltype(op); + + using unwrp = typename UnwrapArguments::type::only_argument_type; + + using cu = unwrap_functional_t::type::only_argument_type; + + // using unwrp2 = typename UnwrapArguments::type; + + auto u = unwrp{}; + + ; + + int i = 0; + + // auto t = unwrap_functional; + */ + + /*EXPECT_ARGUMENTS();*/ + + int i = 0; + (void)i; +}