[+] AuTupleTakeRange, AuTupleTie, AuTupleForward, AuTupleForEach, AuTupleTransform
[+] AuIsLValueReference, AuIsRValueReference
This commit is contained in:
parent
edaa7a295a
commit
c0b0be52b1
@ -108,6 +108,29 @@ inline constexpr bool AuIsReference_v<T &> = true;
|
||||
template<class T>
|
||||
inline constexpr bool AuIsReference_v<T &&> = true;
|
||||
|
||||
template<class T>
|
||||
struct AuIsLValueReference : AuFalseType
|
||||
{};
|
||||
|
||||
template<class T>
|
||||
struct AuIsLValueReference<T &> : AuTrueType
|
||||
{};
|
||||
|
||||
template<class T>
|
||||
inline constexpr bool AuIsLValueReference_v = AuIsLValueReference<T>::value;
|
||||
|
||||
|
||||
template<class T>
|
||||
struct AuIsRValueReference : AuFalseType
|
||||
{};
|
||||
|
||||
template<class T>
|
||||
struct AuIsRValueReference<T &> : AuTrueType
|
||||
{};
|
||||
|
||||
template<class T>
|
||||
inline constexpr bool AuIsRValueReference_v = AuIsRValueReference<T>::value;
|
||||
|
||||
template<class T>
|
||||
struct AuRemovePointer
|
||||
{
|
||||
|
@ -13,27 +13,27 @@
|
||||
#include "auIntegerSequence.hpp"
|
||||
|
||||
#if !defined(AURORA_RUNTIME_MAKE_PAIR)
|
||||
#define AURORA_RUNTIME_MAKE_PAIR std::make_pair
|
||||
#define AURORA_RUNTIME_MAKE_PAIR std::make_pair
|
||||
#endif
|
||||
|
||||
#if !defined(AURORA_RUNTIME_MAKE_TUPLE)
|
||||
#define AURORA_RUNTIME_MAKE_TUPLE std::make_tuple
|
||||
#define AURORA_RUNTIME_MAKE_TUPLE std::make_tuple
|
||||
#endif
|
||||
|
||||
#if !defined(AURORA_RUNTIME_GET_TUPLE)
|
||||
#define AURORA_RUNTIME_GET_TUPLE std::get
|
||||
#define AURORA_RUNTIME_GET_TUPLE std::get
|
||||
#endif
|
||||
|
||||
#if !defined(AURORA_RUNTIME_TUPLE_CAT)
|
||||
#define AURORA_RUNTIME_TUPLE_CAT std::tuple_cat
|
||||
#define AURORA_RUNTIME_TUPLE_CAT std::tuple_cat
|
||||
#endif
|
||||
|
||||
#if !defined(AURORA_RUNTIME_TUPLE_SIZE)
|
||||
#define AURORA_RUNTIME_TUPLE_SIZE std::tuple_size
|
||||
#define AURORA_RUNTIME_TUPLE_SIZE std::tuple_size
|
||||
#endif
|
||||
|
||||
#if !defined(AURORA_RUNTIME_APPLY)
|
||||
#define AURORA_RUNTIME_APPLY std::apply
|
||||
#define AURORA_RUNTIME_APPLY std::apply
|
||||
#endif
|
||||
|
||||
template<typename... Args>
|
||||
@ -68,51 +68,109 @@ static auto AuTupleApply(F &&f, Tuple &&t)
|
||||
|
||||
namespace __audetail
|
||||
{
|
||||
template <class Tuple, AuUInt... Is>
|
||||
static auto AuTuplePopFrontImpl(const Tuple &tuple, AuIndexSequence<Is...>)
|
||||
{
|
||||
return AURORA_RUNTIME_MAKE_TUPLE(AuGet<1 + Is>(tuple)...);
|
||||
}
|
||||
|
||||
template <class Tuple, AuUInt... Is>
|
||||
template <AuUInt Offset, class Tuple, AuUInt... Is>
|
||||
static auto AuTuplePopImpl(const Tuple &tuple, AuIndexSequence<Is...>)
|
||||
{
|
||||
return AURORA_RUNTIME_MAKE_TUPLE(AuGet<Is>(tuple)...);
|
||||
return AURORA_RUNTIME_MAKE_TUPLE(AuGet<Is + Offset>(tuple)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tuple>
|
||||
static auto AuTuplePopFront(const Tuple &tuple)
|
||||
template <class... Ts>
|
||||
static auto AuTuplePopFront(const AuTuple<Ts...> &tuple)
|
||||
{
|
||||
return __audetail::AuTuplePopFrontImpl(tuple, AuMakeIndexSequence<AURORA_RUNTIME_TUPLE_SIZE<Tuple>::value - 1>());
|
||||
return __audetail::AuTuplePopImpl<0>(tuple, AuMakeIndexSequence<AURORA_RUNTIME_TUPLE_SIZE<tuple>::value - 1>());
|
||||
}
|
||||
|
||||
template <class Tuple>
|
||||
static auto AuTuplePopBack(const Tuple &tuple)
|
||||
template <class... Ts>
|
||||
static auto AuTuplePopBack(const AuTuple<Ts...> &tuple)
|
||||
{
|
||||
return __audetail::AuTuplePopImpl(tuple, AuMakeIndexSequence<AURORA_RUNTIME_TUPLE_SIZE<Tuple>::value - 1>());
|
||||
return __audetail::AuTuplePopImpl<1>(tuple, AuMakeIndexSequence<AURORA_RUNTIME_TUPLE_SIZE<tuple>::value - 1>());
|
||||
}
|
||||
|
||||
template <class Tuple, class T>
|
||||
static auto AuTuplePushFront(const Tuple &tuple, const T &t)
|
||||
template <class T, class... Ts>
|
||||
static auto AuTuplePushFront(const AuTuple<Ts...> &tuple, const T &t)
|
||||
{
|
||||
return AURORA_RUNTIME_TUPLE_CAT(AURORA_RUNTIME_MAKE_TUPLE(t), tuple);
|
||||
}
|
||||
|
||||
template <class Tuple, class T>
|
||||
static auto AuTuplePushFront(const Tuple &tuple, T &&t)
|
||||
template <class T, class... Ts>
|
||||
static auto AuTuplePushFront(const AuTuple<Ts...> &tuple, T &&t)
|
||||
{
|
||||
return AURORA_RUNTIME_TUPLE_CAT(AURORA_RUNTIME_MAKE_TUPLE(t), tuple);
|
||||
}
|
||||
|
||||
template <class Tuple, class T>
|
||||
static auto AuTuplePushBack(const Tuple &tuple, const T &t)
|
||||
template <class T, class... Ts>
|
||||
static auto AuTuplePushBack(const AuTuple<Ts...> &tuple, const T &t)
|
||||
{
|
||||
return AURORA_RUNTIME_TUPLE_CAT(tuple, AURORA_RUNTIME_MAKE_TUPLE(t));
|
||||
}
|
||||
|
||||
template <class Tuple, class T>
|
||||
static auto AuTuplePushBack(const Tuple &tuple, T &&t)
|
||||
template <class T, class... Ts>
|
||||
static auto AuTuplePushBack(const AuTuple<Ts...> &tuple, T &&t)
|
||||
{
|
||||
return AURORA_RUNTIME_TUPLE_CAT(tuple, AURORA_RUNTIME_MAKE_TUPLE(t));
|
||||
}
|
||||
|
||||
template <AuUInt Start, AuUInt Length, class... Ts>
|
||||
static auto AuTupleTakeRange(const AuTuple<Ts...> &tuple)
|
||||
{
|
||||
return __audetail::AuTuplePopImpl<Start>(tuple, AuMakeIndexSequence<Length - 1>());
|
||||
}
|
||||
|
||||
template <class Tuple, class Invokable>
|
||||
static void AuTupleForEach(const Tuple &tuple, const Invokable &callback)
|
||||
{
|
||||
AURORA_RUNTIME_APPLY([callback](auto& ...x)
|
||||
{
|
||||
(..., callback(x));
|
||||
}, tuple);
|
||||
}
|
||||
|
||||
template <class ... Args>
|
||||
static constexpr AuTuple<Args& ...> AuTupleTie(Args& ... args)
|
||||
{
|
||||
return AuTuple<Args&...>(args...);
|
||||
}
|
||||
|
||||
template <class ... Args>
|
||||
static constexpr AuTuple<Args&& ...> AuTupleForward(Args&& ... args)
|
||||
{
|
||||
return AuTuple<Args&&...>(AuForward<Args>(args)...);
|
||||
}
|
||||
|
||||
// Stolen: https://codereview.stackexchange.com/questions/193420/apply-a-function-to-each-element-of-a-tuple-map-a-tuple
|
||||
namespace __audetail
|
||||
{
|
||||
template <typename Fn, typename Argument, AuUInt... Ns>
|
||||
static auto AuTupleTransformImpl(const Fn &fn, Argument &&argument, AuIndexSequence<Ns...>)
|
||||
{
|
||||
if constexpr (sizeof...(Ns) == 0)
|
||||
{
|
||||
return AuTuple<>();
|
||||
}
|
||||
else if constexpr (AuIsSame_v<decltype(fn(AuGet<0>(argument))), void>)
|
||||
{
|
||||
(fn(AuGet<Ns>(argument)), ...);
|
||||
return;
|
||||
}
|
||||
else if constexpr (AuIsLValueReference_v<decltype(fn(AuGet<0>(argument)))>)
|
||||
{
|
||||
return AuTupleTie(fn(AuGet<Ns>(argument))...);
|
||||
}
|
||||
else if constexpr (AuIsRValueReference_v<decltype(fn(AuGet<0>(argument)))>)
|
||||
{
|
||||
return AuTupleForward(fn(AuGet<Ns>(argument))...);
|
||||
}
|
||||
else
|
||||
{
|
||||
return AuTuple(fn(AuGet<Ns>(argument))...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Invokable, typename... Ts>
|
||||
static auto AuTupleTransform(const AuTuple<Ts...> &tuple, const Invokable &translate)
|
||||
{
|
||||
return __audetail::AuTupleTransformImpl(translate, tuple,
|
||||
AuMakeIndexSequence<sizeof...(Ts)>());
|
||||
}
|
Loading…
Reference in New Issue
Block a user