mirror of
https://github.com/Naios/continuable.git
synced 2025-12-08 01:36:46 +08:00
Implement sequences and function invocation from tuples
This commit is contained in:
parent
44e96ac52b
commit
959bc87d00
@ -30,10 +30,32 @@
|
||||
|
||||
namespace fu
|
||||
{
|
||||
/// Identity class which is used to carry parameter packs.
|
||||
/// Identity class which is used to carry parameter packs of types.
|
||||
template<typename... Args>
|
||||
struct identity { };
|
||||
|
||||
/// Sequence class which is used to carry parameter packs of unsigned integers.
|
||||
template<size_t...>
|
||||
struct sequence { };
|
||||
|
||||
/// The Sequence generator generates a sequence of numbers with the given size.
|
||||
template<size_t...>
|
||||
struct sequence_generator;
|
||||
|
||||
template<size_t... Stack>
|
||||
struct sequence_generator<0, Stack...>
|
||||
{
|
||||
typedef sequence<Stack...> type;
|
||||
};
|
||||
|
||||
template<size_t Position, size_t... Stack>
|
||||
struct sequence_generator<Position, Stack...>
|
||||
: public sequence_generator<Position - 1, Position - 1, Stack...> { };
|
||||
|
||||
/// Sequence generator alias
|
||||
template<size_t Size>
|
||||
using sequence_of_t = typename sequence_generator<Size>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Function>
|
||||
@ -55,6 +77,11 @@ namespace fu
|
||||
typedef _RTy(*function_ptr)(_ATy...);
|
||||
};
|
||||
|
||||
/// Pack in fu::identity
|
||||
template<typename _RTy, typename... _ATy>
|
||||
struct unwrap_function_impl<identity<_RTy, _ATy...>>
|
||||
: unwrap_function_impl<_RTy(_ATy...)> { };
|
||||
|
||||
/// STL: std::function
|
||||
template<typename _RTy, typename... _ATy>
|
||||
struct unwrap_function_impl<std::function<_RTy(_ATy...)>>
|
||||
@ -85,11 +112,6 @@ namespace fu
|
||||
struct unwrap_function_impl<_RTy(_CTy::*)(_ATy...)>
|
||||
: unwrap_function_impl<_RTy(_ATy...)> { };
|
||||
|
||||
/// Pack in fu::identity
|
||||
template<typename _RTy, typename... _ATy>
|
||||
struct unwrap_function_impl<identity<_RTy, _ATy...>>
|
||||
: unwrap_function_impl<_RTy(_ATy...)> { };
|
||||
|
||||
/// Unwrap through pointer of functor.
|
||||
template<typename Function>
|
||||
static auto select_best_unwrap_unary_arg(int)
|
||||
@ -188,6 +210,38 @@ namespace fu
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
/// Implementation of invoke_with_tuple
|
||||
template<typename Sequence>
|
||||
struct invoker;
|
||||
|
||||
template<size_t... Sequence>
|
||||
struct invoker<sequence<Sequence...>>
|
||||
{
|
||||
template<typename _FTy, typename _TTy>
|
||||
static auto invoke(_FTy&& functional, _TTy&& tuple)
|
||||
-> ::fu::return_type_of_t<typename std::decay<_FTy>::type>
|
||||
{
|
||||
return std::forward<_FTy>(functional)(std::get<Sequence>(std::forward<_TTy>(tuple))...);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Invokes a function type with the given tuple arguments.
|
||||
template<typename _FTy, typename _TTy>
|
||||
inline auto invoke_with_tuple(_FTy&& functional, _TTy&& tuple)
|
||||
-> return_type_of_t<typename std::decay<_FTy>::type>
|
||||
{
|
||||
return detail::invoker<
|
||||
sequence_of_t<
|
||||
std::tuple_size<
|
||||
typename std::decay<_TTy>::type
|
||||
>::value
|
||||
>
|
||||
>::invoke(std::forward<_FTy>(functional), std::forward<_TTy>(tuple));
|
||||
}
|
||||
|
||||
} // fu
|
||||
|
||||
#endif // _FUNCTIONAL_UNWRAP_HPP_
|
||||
|
||||
56
test.cpp
56
test.cpp
@ -82,6 +82,8 @@ Continuable<std::unique_ptr<int>&&> MoveTest()
|
||||
});
|
||||
}
|
||||
|
||||
typedef std::unique_ptr<int> Moveable;
|
||||
|
||||
void testMoveAbleNormal(std::function<void(std::unique_ptr<int>&&)> callback)
|
||||
{
|
||||
std::unique_ptr<int> ptr(new int(5));
|
||||
@ -93,6 +95,43 @@ void test_unwrap(std::string const& msg)
|
||||
{
|
||||
std::cout << msg << " is unwrappable: " << (fu::is_unwrappable<T...>::value ? "true" : "false") << std::endl;
|
||||
}
|
||||
/*
|
||||
template<size_t N>
|
||||
struct Apply {
|
||||
template<typename F, typename T, typename... A>
|
||||
static inline auto apply(F && f, T && t, A &&... a)
|
||||
-> decltype(Apply<N-1>::apply(
|
||||
::std::forward<F>(f), ::std::forward<T>(t),
|
||||
::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
|
||||
))
|
||||
{
|
||||
return Apply<N-1>::apply(::std::forward<F>(f), ::std::forward<T>(t),
|
||||
::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Apply<0> {
|
||||
template<typename F, typename T, typename... A>
|
||||
static inline auto apply(F && f, T &&, A &&... a)
|
||||
-> decltype(::std::forward<F>(f)(::std::forward<A>(a)...))
|
||||
{
|
||||
return ::std::forward<F>(f)(::std::forward<A>(a)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F, typename T>
|
||||
inline auto apply(F && f, T && t)
|
||||
-> decltype(Apply< ::std::tuple_size<
|
||||
typename ::std::decay<T>::type
|
||||
>::value>::apply(::std::forward<F>(f), ::std::forward<T>(t)))
|
||||
{
|
||||
return Apply< ::std::tuple_size<
|
||||
typename ::std::decay<T>::type
|
||||
>::value>::apply(::std::forward<F>(f), ::std::forward<T>(t));
|
||||
}
|
||||
*/
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
{
|
||||
@ -281,6 +320,23 @@ int main(int /*argc*/, char** /*argv*/)
|
||||
|
||||
std::tuple<int, std::vector<int>> tup;
|
||||
|
||||
Moveable moveable(new int(7));
|
||||
|
||||
auto myargs = std::make_tuple(7, std::vector<int>({ 1, 2, 3 }), std::move(moveable));
|
||||
|
||||
std::function<int(int, std::vector<int>, Moveable&&)> lam = [](int given_i, std::vector<int> given_vec, Moveable&& moveable)
|
||||
{
|
||||
Moveable other = std::move(moveable);
|
||||
|
||||
++given_i;
|
||||
return 1;
|
||||
};
|
||||
|
||||
fu::invoke_with_tuple(lam, std::move(myargs));
|
||||
|
||||
fu::sequence_generator<2>::type seqtype;
|
||||
fu::sequence_generator<1>::type zero_seqtype;
|
||||
|
||||
std::cout << "ok" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user