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

@ -62,24 +62,24 @@ namespace detail
template<typename _CTy, typename... Args> template<typename _CTy, typename... Args>
struct WeakProxyFactory<_CTy, std::weak_ptr<std::function<void(Args...)>>> struct WeakProxyFactory<_CTy, std::weak_ptr<std::function<void(Args...)>>>
{ {
static Callback<Args...> CreateProxy(_CTy&& weak) static Callback<Args...> CreateProxy(_CTy&& weak)
{ {
return [=](Args&&... args) return [=](Args&&... args)
{ {
if (auto const callback = weak.lock()) if (auto const callback = weak.lock())
(*callback)(std::forward<Args>(args)...); (*callback)(std::forward<Args>(args)...);
}; };
} }
}; };
template<typename _CTy, typename... Args> template<typename _CTy, typename... Args>
struct WeakProxyFactory<_CTy, std::shared_ptr<std::function<void(Args...)>>> struct WeakProxyFactory<_CTy, std::shared_ptr<std::function<void(Args...)>>>
{ {
static Callback<Args...> CreateProxy(_CTy&& shared) static Callback<Args...> CreateProxy(_CTy&& shared)
{ {
return WeakProxyFactory<std::weak_ptr<std::function<void(Args...)>>&&, return WeakProxyFactory<std::weak_ptr<std::function<void(Args...)>>&&,
std::weak_ptr<std::function<void(Args...)>>>::CreateProxy(std::forward<_CTy>(shared)); std::weak_ptr<std::function<void(Args...)>>>::CreateProxy(std::forward<_CTy>(shared));
} }
}; };
} // detail } // detail

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...>
{
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...> { };
namespace detail
{
/// 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,91 +69,110 @@ namespace detail
{ {
typedef Continuable<_CArgs...> type; typedef Continuable<_CArgs...> type;
}; };
}
template<typename... _ATy, typename _State>
class Continuable<std::function<void(_ATy...)>, _State>
{
public:
typedef std::function<void(Callback<_ATy...>&&)> 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<typename _RCTy, typename _RState>
Continuable(Continuable<_RCTy, _RState> const&) = delete;
/// Move construct
template<typename _RCTy, typename _RState>
Continuable(Continuable<_RCTy, _RState>&& right)
: _released(right._released)
{
right._released = true;
}
// Construct through a ForwardFunction
template<typename _FTy>
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<typename _RCTy, typename _RState>
Continuable& operator= (Continuable<_RCTy, _RState> const&) = delete;
/// Move construct assign
template<typename _RCTy, typename _RState>
Continuable& operator= (Continuable<_RCTy, _RState>&& right)
{
_released = right._released;
right._released = true;
return *this;
}
// TODO Accept only correct callbacks
template<typename _CTy>
Continuable<Callback<_ATy...>> then(_CTy&&)
{
// TODO Transmute the returned callback here.
return Continuable<Callback<_ATy...>>(std::move(*this));
}
/*
// TODO Accept only correct callbacks
template<typename... _CTy>
Continuable<Callback<_ATy...>> all(_CTy&&...)
{
// TODO Transmute the returned callback here.
return Continuable<Callback<_ATy...>>(std::move(*this));
}
*/ */
/// Invalidates the Continuable // ContinuableImpl Forward definition
Continuable& invalidate() template<typename _STy, typename _CTy>
class _ContinuableImpl;
template<typename... _STy, typename... _ATy>
class _ContinuableImpl<ContinuableState<_STy...>, std::function<void(_ATy...)>>
{ {
_released = true; // Make all instances of _ContinuableImpl to a friend.
return *this; template<typename, typename>
} friend class _ContinuableImpl;
};
typedef ContinuableState<_STy...> MyState;
typedef Callback<_ATy...> MyCallback;
public:
typedef std::function<void(Callback<_ATy...>&&)> 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<typename _RState, typename _RCTy>
_ContinuableImpl(_ContinuableImpl<_RState, _RCTy> const&) = delete;
/// Move construct
template<typename _RState, typename _RCTy>
_ContinuableImpl(_ContinuableImpl<_RState, _RCTy>&& right)
: _released(right._released)
{
right._released = true;
}
// Construct through a ForwardFunction
template<typename _FTy>
_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<typename _RState, typename _RCTy>
_ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy> const&) = delete;
/// Move construct assign
template<typename _RState, typename _RCTy>
_ContinuableImpl& operator= (_ContinuableImpl<_RState, _RCTy>&& right)
{
_released = right._released;
right._released = true;
return *this;
}
// TODO Accept only correct callbacks
template<typename _CTy>
_ContinuableImpl<DefaultContinuableState, Callback<_ATy...>> then(_CTy&&)
{
// TODO Transmute the returned callback here.
return _ContinuableImpl<DefaultContinuableState, Callback<_ATy...>>(std::move(*this));
}
/*
// TODO Accept only correct callbacks
template<typename... _CTy>
Continuable<Callback<_ATy...>> all(_CTy&&...)
{
// TODO Transmute the returned callback here.
return Continuable<Callback<_ATy...>>(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<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);