diff --git a/fluent/Callback.h b/fluent/Callback.h index bfd47fe..343b6e0 100644 --- a/fluent/Callback.h +++ b/fluent/Callback.h @@ -62,24 +62,24 @@ namespace detail template struct WeakProxyFactory<_CTy, std::weak_ptr>> { - static Callback CreateProxy(_CTy&& weak) - { - return [=](Args&&... args) + static Callback CreateProxy(_CTy&& weak) + { + return [=](Args&&... args) { if (auto const callback = weak.lock()) (*callback)(std::forward(args)...); }; - } + } }; template struct WeakProxyFactory<_CTy, std::shared_ptr>> { - static Callback CreateProxy(_CTy&& shared) - { - return WeakProxyFactory>&&, + static Callback CreateProxy(_CTy&& shared) + { + return WeakProxyFactory>&&, std::weak_ptr>>::CreateProxy(std::forward<_CTy>(shared)); - } + } }; } // detail diff --git a/fluent/Continuable.h b/fluent/Continuable.h index a8990fb..fd6bea7 100644 --- a/fluent/Continuable.h +++ b/fluent/Continuable.h @@ -23,7 +23,9 @@ namespace detail { - template + /// The internal state of the continuable + /// which is used to save certain internal types. + template struct ContinuableState; template @@ -31,16 +33,28 @@ namespace detail { }; - typedef ContinuableState, void> EmptyContinuableState; + typedef ContinuableState, void> DefaultContinuableState; -} // detail + /// The unwrap which is used to extract continuable parameter types. + template + struct continuable_unwrap; -template -class Continuable; + // First parameter is the state. + template + struct continuable_unwrap, _CArgs...> + { + typedef ContinuableState<_SArgs...> state_t; + + typedef Callback<_CArgs...> callback_t; + }; + + // No state is given use an empty one. + template + struct continuable_unwrap<_CArgs...> + : public continuable_unwrap { }; -namespace detail -{ /// Corrects void return types from functional types which should be Continuable> + /* template struct convert_void_to_continuable; @@ -55,91 +69,110 @@ namespace detail { typedef Continuable<_CArgs...> type; }; -} - -template -class Continuable, _State> -{ -public: - typedef std::function&&)> ForwardFunction; - -private: - /// Functional which expects a callback that is inserted from the Continuable - /// to chain everything together - ForwardFunction _callback_insert; - - bool _released; - - void Dispatch() - { - } - -public: - /// Deleted copy construct - template - Continuable(Continuable<_RCTy, _RState> const&) = delete; - - /// Move construct - template - Continuable(Continuable<_RCTy, _RState>&& right) - : _released(right._released) - { - right._released = true; - } - - // Construct through a ForwardFunction - template - Continuable(_FTy&& callback_insert) - : _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { } - - /// Destructor which calls the dispatch chain if needed. - ~Continuable() - { - if (!_released) - { - _released = true; - Dispatch(); - } - } - - /// Deleted copy assign - template - Continuable& operator= (Continuable<_RCTy, _RState> const&) = delete; - - /// Move construct assign - template - Continuable& operator= (Continuable<_RCTy, _RState>&& right) - { - _released = right._released; - right._released = true; - return *this; - } - - // TODO Accept only correct callbacks - template - Continuable> then(_CTy&&) - { - // TODO Transmute the returned callback here. - return Continuable>(std::move(*this)); - } - - /* - // TODO Accept only correct callbacks - template - Continuable> all(_CTy&&...) - { - // TODO Transmute the returned callback here. - return Continuable>(std::move(*this)); - } */ - /// Invalidates the Continuable - Continuable& invalidate() + // ContinuableImpl Forward definition + template + class _ContinuableImpl; + + template + class _ContinuableImpl, std::function> { - _released = true; - return *this; - } -}; + // Make all instances of _ContinuableImpl to a friend. + template + friend class _ContinuableImpl; + + typedef ContinuableState<_STy...> MyState; + typedef Callback<_ATy...> MyCallback; + + public: + typedef std::function&&)> ForwardFunction; + + private: + /// Functional which expects a callback that is inserted from the Continuable + /// to chain everything together + ForwardFunction _callback_insert; + + bool _released; + + void Dispatch() + { + } + + public: + /// Deleted copy construct + template + _ContinuableImpl(_ContinuableImpl<_RState, _RCTy> const&) = delete; + + /// Move construct + template + _ContinuableImpl(_ContinuableImpl<_RState, _RCTy>&& right) + : _released(right._released) + { + right._released = true; + } + + // Construct through a ForwardFunction + template + _ContinuableImpl(_FTy&& callback_insert) + : _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { } + + /// Destructor which calls the dispatch chain if needed. + ~_ContinuableImpl() + { + if (!_released) + { + _released = true; + Dispatch(); + } + } + + /// Deleted copy assign + template + _ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy> const&) = delete; + + /// Move construct assign + template + _ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy>&& right) + { + _released = right._released; + right._released = true; + return *this; + } + + // TODO Accept only correct callbacks + template + _ContinuableImpl> then(_CTy&&) + { + // TODO Transmute the returned callback here. + return _ContinuableImpl>(std::move(*this)); + } + + /* + // TODO Accept only correct callbacks + template + Continuable> all(_CTy&&...) + { + // TODO Transmute the returned callback here. + return Continuable>(std::move(*this)); + } + */ + + /// Invalidates the Continuable + _ContinuableImpl& invalidate() + { + _released = true; + return *this; + } + }; +} + +/// A continuable provides useful methods to react on the result of callbacks +/// and allows to chain multiple callback calls to a chain. +template +using Continuable = detail::_ContinuableImpl< + detail::DefaultContinuableState, + Callback>; namespace detail { @@ -150,10 +183,10 @@ namespace detail struct ContinuableFactory<_FTy, _RTy, ::fu::identity&&>> { static auto CreateFrom(_FTy&& functional) - -> Continuable> + -> Continuable<_ATy...> { - return Continuable>( - typename Continuable>::ForwardFunction(std::forward<_FTy>(functional))); + return Continuable<_ATy...>( + typename Continuable<_ATy...>::ForwardFunction(std::forward<_FTy>(functional))); } }; diff --git a/test.cpp b/test.cpp index cd362f4..3b6df15 100644 --- a/test.cpp +++ b/test.cpp @@ -19,7 +19,7 @@ enum SpellCastResult SPELL_FAILED_ALREADY_BEING_TAMED = 5 }; -Continuable> CastSpell(int id) +Continuable CastSpell(int id) { return make_continuable([=](Callback&& callback) { @@ -38,11 +38,17 @@ void test_unwrap(std::string const& msg) int main(int /*argc*/, char** /*argv*/) { + Continuable cb = make_continuable([](Callback&& callback) + { + + callback(true); + }); + test_unwrap("void()"); test_unwrap>("std::function"); test_unwrap>("std::vector"); - make_continuable([=](Callback<>&& /*callback*/) + make_continuable([=](Callback<>&&) { }); @@ -50,7 +56,7 @@ int main(int /*argc*/, char** /*argv*/) int i = 0; ++i; - auto lam = [=](Callback&& /*callback*/) + auto lam = [=](Callback&&) { // on success call the callback with SPELL_FAILED_SUCCESS // callback(SPELL_FAILED_SUCCESS); @@ -76,8 +82,8 @@ int main(int /*argc*/, char** /*argv*/) typedef Continuable cont123; - typedef Continuable> myty1; - typedef Continuable, float> myty2; + typedef Continuable myty1; + typedef Continuable myty2; // Continuable> spell CastSpell(63362) @@ -107,9 +113,9 @@ int main(int /*argc*/, char** /*argv*/) typedef fu::requires_functional_constructible>::type test_assert1; // typedef fu::requires_functional_constructible>::type test_assert2; - detail::convert_void_to_continuable::type* _test5 = nullptr; + // detail::convert_void_to_continuable::type* _test5 = nullptr; - detail::convert_void_to_continuable>>::type* _test6 = nullptr; + // detail::convert_void_to_continuable>>::type* _test6 = nullptr; // auto cba2 = make_continuable(myvec);