Allow shorthand completion for continuables

This commit is contained in:
Naios 2015-06-14 17:59:07 +02:00
parent d40f6d5c08
commit a2dd086c80
3 changed files with 146 additions and 107 deletions

View File

@ -23,7 +23,9 @@
namespace detail namespace detail
{ {
template<typename _Cain, typename _Proxy> /// The internal state of the continuable
/// which is used to save certain internal types.
template<typename... Args>
struct ContinuableState; struct ContinuableState;
template<typename... _Cain, typename _Proxy> template<typename... _Cain, typename _Proxy>
@ -31,16 +33,28 @@ namespace detail
{ {
}; };
typedef ContinuableState<std::tuple<>, void> EmptyContinuableState; typedef ContinuableState<std::tuple<>, void> DefaultContinuableState;
} // detail /// The unwrap which is used to extract continuable parameter types.
template<typename... Args>
struct continuable_unwrap;
template<typename _CTy, typename _State = detail::EmptyContinuableState> // First parameter is the state.
class Continuable; template<typename... _SArgs, typename... _CArgs>
struct continuable_unwrap<ContinuableState<_SArgs...>, _CArgs...>
namespace detail
{ {
typedef ContinuableState<_SArgs...> state_t;
typedef Callback<_CArgs...> callback_t;
};
// No state is given use an empty one.
template<typename... _CArgs>
struct continuable_unwrap<_CArgs...>
: public continuable_unwrap<DefaultContinuableState, _CArgs...> { };
/// Corrects void return types from functional types which should be Continuable<Callback<>> /// Corrects void return types from functional types which should be Continuable<Callback<>>
/*
template<typename _RTy> template<typename _RTy>
struct convert_void_to_continuable; struct convert_void_to_continuable;
@ -55,11 +69,22 @@ namespace detail
{ {
typedef Continuable<_CArgs...> type; typedef Continuable<_CArgs...> type;
}; };
} */
template<typename... _ATy, typename _State> // ContinuableImpl Forward definition
class Continuable<std::function<void(_ATy...)>, _State> template<typename _STy, typename _CTy>
class _ContinuableImpl;
template<typename... _STy, typename... _ATy>
class _ContinuableImpl<ContinuableState<_STy...>, std::function<void(_ATy...)>>
{ {
// Make all instances of _ContinuableImpl to a friend.
template<typename, typename>
friend class _ContinuableImpl;
typedef ContinuableState<_STy...> MyState;
typedef Callback<_ATy...> MyCallback;
public: public:
typedef std::function<void(Callback<_ATy...>&&)> ForwardFunction; typedef std::function<void(Callback<_ATy...>&&)> ForwardFunction;
@ -76,12 +101,12 @@ private:
public: public:
/// Deleted copy construct /// Deleted copy construct
template<typename _RCTy, typename _RState> template<typename _RState, typename _RCTy>
Continuable(Continuable<_RCTy, _RState> const&) = delete; _ContinuableImpl(_ContinuableImpl<_RState, _RCTy> const&) = delete;
/// Move construct /// Move construct
template<typename _RCTy, typename _RState> template<typename _RState, typename _RCTy>
Continuable(Continuable<_RCTy, _RState>&& right) _ContinuableImpl(_ContinuableImpl<_RState, _RCTy>&& right)
: _released(right._released) : _released(right._released)
{ {
right._released = true; right._released = true;
@ -89,11 +114,11 @@ public:
// Construct through a ForwardFunction // Construct through a ForwardFunction
template<typename _FTy> template<typename _FTy>
Continuable(_FTy&& callback_insert) _ContinuableImpl(_FTy&& callback_insert)
: _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { } : _callback_insert(std::forward<_FTy>(callback_insert)), _released(false) { }
/// Destructor which calls the dispatch chain if needed. /// Destructor which calls the dispatch chain if needed.
~Continuable() ~_ContinuableImpl()
{ {
if (!_released) if (!_released)
{ {
@ -103,12 +128,12 @@ public:
} }
/// Deleted copy assign /// Deleted copy assign
template<typename _RCTy, typename _RState> template<typename _RState, typename _RCTy>
Continuable& operator= (Continuable<_RCTy, _RState> const&) = delete; _ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy> const&) = delete;
/// Move construct assign /// Move construct assign
template<typename _RCTy, typename _RState> template<typename _RState, typename _RCTy>
Continuable& operator= (Continuable<_RCTy, _RState>&& right) _ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy>&& right)
{ {
_released = right._released; _released = right._released;
right._released = true; right._released = true;
@ -117,10 +142,10 @@ public:
// TODO Accept only correct callbacks // TODO Accept only correct callbacks
template<typename _CTy> template<typename _CTy>
Continuable<Callback<_ATy...>> then(_CTy&&) _ContinuableImpl<DefaultContinuableState, Callback<_ATy...>> then(_CTy&&)
{ {
// TODO Transmute the returned callback here. // TODO Transmute the returned callback here.
return Continuable<Callback<_ATy...>>(std::move(*this)); return _ContinuableImpl<DefaultContinuableState, Callback<_ATy...>>(std::move(*this));
} }
/* /*
@ -134,12 +159,20 @@ public:
*/ */
/// Invalidates the Continuable /// Invalidates the Continuable
Continuable& invalidate() _ContinuableImpl& invalidate()
{ {
_released = true; _released = true;
return *this; 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<typename... Args>
using Continuable = detail::_ContinuableImpl<
detail::DefaultContinuableState,
Callback<Args...>>;
namespace detail namespace detail
{ {
@ -150,10 +183,10 @@ namespace detail
struct ContinuableFactory<_FTy, _RTy, ::fu::identity<std::function<void(_ATy...)>&&>> struct ContinuableFactory<_FTy, _RTy, ::fu::identity<std::function<void(_ATy...)>&&>>
{ {
static auto CreateFrom(_FTy&& functional) static auto CreateFrom(_FTy&& functional)
-> Continuable<Callback<_ATy...>> -> Continuable<_ATy...>
{ {
return Continuable<Callback<_ATy...>>( return Continuable<_ATy...>(
typename Continuable<Callback<_ATy...>>::ForwardFunction(std::forward<_FTy>(functional))); typename Continuable<_ATy...>::ForwardFunction(std::forward<_FTy>(functional)));
} }
}; };

View File

@ -19,7 +19,7 @@ enum SpellCastResult
SPELL_FAILED_ALREADY_BEING_TAMED = 5 SPELL_FAILED_ALREADY_BEING_TAMED = 5
}; };
Continuable<Callback<SpellCastResult>> CastSpell(int id) Continuable<SpellCastResult> CastSpell(int id)
{ {
return make_continuable([=](Callback<SpellCastResult>&& callback) return make_continuable([=](Callback<SpellCastResult>&& callback)
{ {
@ -38,11 +38,17 @@ void test_unwrap(std::string const& msg)
int main(int /*argc*/, char** /*argv*/) int main(int /*argc*/, char** /*argv*/)
{ {
Continuable<bool> cb = make_continuable([](Callback<bool>&& callback)
{
callback(true);
});
test_unwrap<void()>("void()"); test_unwrap<void()>("void()");
test_unwrap<std::function<void()>>("std::function<void()>"); test_unwrap<std::function<void()>>("std::function<void()>");
test_unwrap<std::vector<std::string>>("std::vector<std::string>"); test_unwrap<std::vector<std::string>>("std::vector<std::string>");
make_continuable([=](Callback<>&& /*callback*/) make_continuable([=](Callback<>&&)
{ {
}); });
@ -50,7 +56,7 @@ int main(int /*argc*/, char** /*argv*/)
int i = 0; int i = 0;
++i; ++i;
auto lam = [=](Callback<SpellCastResult>&& /*callback*/) auto lam = [=](Callback<SpellCastResult>&&)
{ {
// on success call the callback with SPELL_FAILED_SUCCESS // on success call the callback with SPELL_FAILED_SUCCESS
// callback(SPELL_FAILED_SUCCESS); // callback(SPELL_FAILED_SUCCESS);
@ -76,8 +82,8 @@ int main(int /*argc*/, char** /*argv*/)
typedef Continuable<bool> cont123; typedef Continuable<bool> cont123;
typedef Continuable<Callback<bool>> myty1; typedef Continuable<bool> myty1;
typedef Continuable<Callback<bool>, float> myty2; typedef Continuable<bool, float> myty2;
// Continuable<Callback<SpellCastResult>> spell // Continuable<Callback<SpellCastResult>> spell
CastSpell(63362) CastSpell(63362)
@ -107,9 +113,9 @@ int main(int /*argc*/, char** /*argv*/)
typedef fu::requires_functional_constructible<std::function<void()>>::type test_assert1; typedef fu::requires_functional_constructible<std::function<void()>>::type test_assert1;
// typedef fu::requires_functional_constructible<std::vector<int>>::type test_assert2; // typedef fu::requires_functional_constructible<std::vector<int>>::type test_assert2;
detail::convert_void_to_continuable<void>::type* _test5 = nullptr; // detail::convert_void_to_continuable<void>::type* _test5 = nullptr;
detail::convert_void_to_continuable<Continuable<Callback<SpellCastResult>>>::type* _test6 = nullptr; // detail::convert_void_to_continuable<Continuable<Callback<SpellCastResult>>>::type* _test6 = nullptr;
// auto cba2 = make_continuable(myvec); // auto cba2 = make_continuable(myvec);