From d27d1e915bc8313a8929406e0259ff105ea6e773 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Sun, 21 Jun 2015 15:12:25 +0200 Subject: [PATCH] Move continuable out of detail scope --- include/Continuable.h | 391 +++++++++++++++++++++--------------------- 1 file changed, 194 insertions(+), 197 deletions(-) diff --git a/include/Continuable.h b/include/Continuable.h index c4e26d5..c37fd14 100644 --- a/include/Continuable.h +++ b/include/Continuable.h @@ -36,12 +36,12 @@ void debug(std::string const& m) } /// Debug end +// Continuable forward declaration. +template +class Continuable; + namespace detail { - // Continuable forward declaration. - template - class Continuable; - // convert_void_to_continuable forward declaration. /// Corrects void return types from functional types which should be /// Continuable> @@ -119,197 +119,6 @@ namespace detail } }; - template - class Continuable - { - // Make all templates of Continuable to a friend. - template - friend class Continuable; - - public: - typedef Callback<_ATy...> CallbackFunction; - 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; - - template - void invoke(_CTy&& callback) - { - if (!_released) - { - // Invalidate this - _released = true; - - // Invoke this - _callback_insert(std::forward<_CTy>(callback)); - } - } - - // Pack a continuable into the continuable returning functional type. - template - static auto box_continuable(_CTy&& continuable) - -> typename std::enable_if::type>::value, - std::function::type(_ATy...)>>::type - { - // Trick C++11 lambda capture rules for non copyable but moveable continuables. - std::shared_ptr::type> shared_continuable = - std::make_shared::type>(std::forward<_CTy>(continuable)); - - // Create a fake function which returns the value on invoke. - return [shared_continuable](_ATy...) - { - return std::move(*shared_continuable); - }; - } - - // Do nothing if already a non continuable type - template - static auto box_continuable(_CTy&& continuable) - -> typename std::enable_if::type>::value, - typename std::decay<_CTy>::type>::type - { - return continuable; - } - - public: - /// Deleted copy construct - Continuable(Continuable const&) = delete; - - /// Move construct - Continuable(Continuable&& right) - : _released(right._released), _callback_insert(std::move(right._callback_insert)) - { - right._released = true; - } - - // Construct through a ForwardFunction - template - Continuable(_FTy&& callback_insert) - : _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { } - - template - Continuable(_FTy&& callback_insert, Continuable<_RATy...>&& right) - : _callback_insert(std::forward<_FTy>(callback_insert)), _released(right._released) - { - right._released = true; - } - - /// Destructor which calls the dispatch chain if needed. - ~Continuable() - { - // Dispatch everything. - if (!_released) - { - // Set released to true to prevent multiple calls - _released = true; - - // Invoke everything with an empty callback - _callback_insert(create_empty_callback::create()); - } - } - - /// Deleted copy assign - Continuable& operator= (Continuable const&) = delete; - - /// Move construct assign - Continuable& operator= (Continuable&& right) - { - _released = right._released; - right._released = true; - - _callback_insert = std::move(right._callback_insert); - return *this; - } - - /// Waits for this continuable and invokes the given callback. - template - auto then(_CTy&& functional) - -> typename std::enable_if::type>::value, - typename unary_chainer_t<_CTy>::result_t>::type - { - // Transfer the insert function to the local scope. - // Also use it as an r-value reference to try to get move semantics with c++11 lambdas. - ForwardFunction&& callback = std::move(_callback_insert); - - return typename unary_chainer_t<_CTy>::result_t( - [functional, callback](typename unary_chainer_t<_CTy>::callback_t&& call_next) - { - callback([functional, call_next](_ATy&&... args) mutable - { - // Invoke the next callback - unary_chainer_t<_CTy>::base::invoke(functional, std::forward<_ATy>(args)...) - .invoke(std::move(call_next)); - }); - - }, std::move(*this)); - } - - /// Waits for this continuable and continues with the given one. - template - auto then(_CTy&& continuable) - -> typename std::enable_if::type>::value, - typename std::decay<_CTy>::type>::type - { - static_assert(std::is_rvalue_reference<_CTy&&>::value, - "Given continuable must be passed as r-value!"); - - return then(box_continuable(std::forward<_CTy>(continuable))); - } - - template - Continuable& _wrap_all(_CTy&&...) - { - typedef multiple_all_chainer<_CTy...> type; - - return *this; - } - - /// Placeholder - template - auto all(_CTy&&... functionals) - -> Continuable& - { - return *this; - } - - /// Placeholder - template - Continuable& some(size_t const count, _CTy&&...) - { - return *this; - } - - /// Placeholder - template - auto any(_CTy&&... functionals) - -> Continuable& // FIXME gcc build &-> decltype(some(1, std::declval<_CTy>()...)) - { - // Equivalent to invoke `some` with count 1. - return some(1, std::forward<_CTy>(functionals)...); - } - - /* - /// Validates the Continuable - inline Continuable& Validate() - { - _released = false; - return *this; - } - - /// Invalidates the Continuable - inline Continuable& Invalidate() - { - _released = true; - return *this; - } - */ - }; - template<> struct convert_void_to_continuable { @@ -366,8 +175,196 @@ namespace detail } // detail -template -using Continuable = detail::Continuable; +template +class Continuable +{ + // Make all templates of Continuable to a friend. + template + friend class Continuable; + +public: + typedef Callback<_ATy...> CallbackFunction; + 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; + + template + void invoke(_CTy&& callback) + { + if (!_released) + { + // Invalidate this + _released = true; + + // Invoke this + _callback_insert(std::forward<_CTy>(callback)); + } + } + + // Pack a continuable into the continuable returning functional type. + template + static auto box_continuable(_CTy&& continuable) + -> typename std::enable_if::type>::value, + std::function::type(_ATy...)>>::type + { + // Trick C++11 lambda capture rules for non copyable but moveable continuables. + std::shared_ptr::type> shared_continuable = + std::make_shared::type>(std::forward<_CTy>(continuable)); + + // Create a fake function which returns the value on invoke. + return [shared_continuable](_ATy...) + { + return std::move(*shared_continuable); + }; + } + + // Do nothing if already a non continuable type + template + static auto box_continuable(_CTy&& continuable) + -> typename std::enable_if::type>::value, + typename std::decay<_CTy>::type>::type + { + return continuable; + } + +public: + /// Deleted copy construct + Continuable(Continuable const&) = delete; + + /// Move construct + Continuable(Continuable&& right) + : _released(right._released), _callback_insert(std::move(right._callback_insert)) + { + right._released = true; + } + + // Construct through a ForwardFunction + template + Continuable(_FTy&& callback_insert) + : _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { } + + template + Continuable(_FTy&& callback_insert, Continuable<_RATy...>&& right) + : _callback_insert(std::forward<_FTy>(callback_insert)), _released(right._released) + { + right._released = true; + } + + /// Destructor which calls the dispatch chain if needed. + ~Continuable() + { + // Dispatch everything. + if (!_released) + { + // Set released to true to prevent multiple calls + _released = true; + + // Invoke everything with an empty callback + _callback_insert(detail::create_empty_callback::create()); + } + } + + /// Deleted copy assign + Continuable& operator= (Continuable const&) = delete; + + /// Move construct assign + Continuable& operator= (Continuable&& right) + { + _released = right._released; + right._released = true; + + _callback_insert = std::move(right._callback_insert); + return *this; + } + + /// Waits for this continuable and invokes the given callback. + template + auto then(_CTy&& functional) + -> typename std::enable_if::type>::value, + typename detail::unary_chainer_t<_CTy>::result_t>::type + { + // Transfer the insert function to the local scope. + // Also use it as an r-value reference to try to get move semantics with c++11 lambdas. + ForwardFunction&& callback = std::move(_callback_insert); + + return typename detail::unary_chainer_t<_CTy>::result_t( + [functional, callback](typename detail::unary_chainer_t<_CTy>::callback_t&& call_next) + { + callback([functional, call_next](_ATy&&... args) mutable + { + // Invoke the next callback + detail::unary_chainer_t<_CTy>::base::invoke(functional, std::forward<_ATy>(args)...) + .invoke(std::move(call_next)); + }); + + }, std::move(*this)); + } + + /// Waits for this continuable and continues with the given one. + template + auto then(_CTy&& continuable) + -> typename std::enable_if::type>::value, + typename std::decay<_CTy>::type>::type + { + static_assert(std::is_rvalue_reference<_CTy&&>::value, + "Given continuable must be passed as r-value!"); + + return then(box_continuable(std::forward<_CTy>(continuable))); + } + + template + Continuable& _wrap_all(_CTy&&...) + { + typedef multiple_all_chainer<_CTy...> type; + + return *this; + } + + /// Placeholder + template + auto all(_CTy&&... functionals) + -> Continuable& + { + return *this; + } + + /// Placeholder + template + Continuable& some(size_t const count, _CTy&&...) + { + return *this; + } + + /// Placeholder + template + auto any(_CTy&&... functionals) + -> Continuable& // FIXME gcc build &-> decltype(some(1, std::declval<_CTy>()...)) + { + // Equivalent to invoke `some` with count 1. + return some(1, std::forward<_CTy>(functionals)...); + } + + /* + /// Validates the Continuable + inline Continuable& Validate() + { + _released = false; + return *this; + } + + /// Invalidates the Continuable + inline Continuable& Invalidate() + { + _released = true; + return *this; + } + */ +}; /// Wraps a functional object which expects a r-value callback as argument into a continuable. /// The callable is invoked when the continuable shall continue.