diff --git a/Include/auROXTL/auTemplateMeta.hpp b/Include/auROXTL/auTemplateMeta.hpp index 2ec5f301..583d2c48 100644 --- a/Include/auROXTL/auTemplateMeta.hpp +++ b/Include/auROXTL/auTemplateMeta.hpp @@ -108,6 +108,29 @@ inline constexpr bool AuIsReference_v = true; template inline constexpr bool AuIsReference_v = true; +template +struct AuIsLValueReference : AuFalseType +{}; + +template +struct AuIsLValueReference : AuTrueType +{}; + +template +inline constexpr bool AuIsLValueReference_v = AuIsLValueReference::value; + + +template +struct AuIsRValueReference : AuFalseType +{}; + +template +struct AuIsRValueReference : AuTrueType +{}; + +template +inline constexpr bool AuIsRValueReference_v = AuIsRValueReference::value; + template struct AuRemovePointer { diff --git a/Include/auROXTL/auTupleUtils.hpp b/Include/auROXTL/auTupleUtils.hpp index 4e225e0b..23e06629 100644 --- a/Include/auROXTL/auTupleUtils.hpp +++ b/Include/auROXTL/auTupleUtils.hpp @@ -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 @@ -68,51 +68,109 @@ static auto AuTupleApply(F &&f, Tuple &&t) namespace __audetail { - template - static auto AuTuplePopFrontImpl(const Tuple &tuple, AuIndexSequence) - { - return AURORA_RUNTIME_MAKE_TUPLE(AuGet<1 + Is>(tuple)...); - } - - template + template static auto AuTuplePopImpl(const Tuple &tuple, AuIndexSequence) { - return AURORA_RUNTIME_MAKE_TUPLE(AuGet(tuple)...); + return AURORA_RUNTIME_MAKE_TUPLE(AuGet(tuple)...); } } -template -static auto AuTuplePopFront(const Tuple &tuple) +template +static auto AuTuplePopFront(const AuTuple &tuple) { - return __audetail::AuTuplePopFrontImpl(tuple, AuMakeIndexSequence::value - 1>()); + return __audetail::AuTuplePopImpl<0>(tuple, AuMakeIndexSequence::value - 1>()); } -template -static auto AuTuplePopBack(const Tuple &tuple) +template +static auto AuTuplePopBack(const AuTuple &tuple) { - return __audetail::AuTuplePopImpl(tuple, AuMakeIndexSequence::value - 1>()); + return __audetail::AuTuplePopImpl<1>(tuple, AuMakeIndexSequence::value - 1>()); } -template -static auto AuTuplePushFront(const Tuple &tuple, const T &t) +template +static auto AuTuplePushFront(const AuTuple &tuple, const T &t) { return AURORA_RUNTIME_TUPLE_CAT(AURORA_RUNTIME_MAKE_TUPLE(t), tuple); } -template -static auto AuTuplePushFront(const Tuple &tuple, T &&t) +template +static auto AuTuplePushFront(const AuTuple &tuple, T &&t) { return AURORA_RUNTIME_TUPLE_CAT(AURORA_RUNTIME_MAKE_TUPLE(t), tuple); } -template -static auto AuTuplePushBack(const Tuple &tuple, const T &t) +template +static auto AuTuplePushBack(const AuTuple &tuple, const T &t) { return AURORA_RUNTIME_TUPLE_CAT(tuple, AURORA_RUNTIME_MAKE_TUPLE(t)); } -template -static auto AuTuplePushBack(const Tuple &tuple, T &&t) +template +static auto AuTuplePushBack(const AuTuple &tuple, T &&t) { return AURORA_RUNTIME_TUPLE_CAT(tuple, AURORA_RUNTIME_MAKE_TUPLE(t)); +} + +template +static auto AuTupleTakeRange(const AuTuple &tuple) +{ + return __audetail::AuTuplePopImpl(tuple, AuMakeIndexSequence()); +} + +template +static void AuTupleForEach(const Tuple &tuple, const Invokable &callback) +{ + AURORA_RUNTIME_APPLY([callback](auto& ...x) + { + (..., callback(x)); + }, tuple); +} + +template +static constexpr AuTuple AuTupleTie(Args& ... args) +{ + return AuTuple(args...); +} + +template +static constexpr AuTuple AuTupleForward(Args&& ... args) +{ + return AuTuple(AuForward(args)...); +} + +// Stolen: https://codereview.stackexchange.com/questions/193420/apply-a-function-to-each-element-of-a-tuple-map-a-tuple +namespace __audetail +{ + template + static auto AuTupleTransformImpl(const Fn &fn, Argument &&argument, AuIndexSequence) + { + if constexpr (sizeof...(Ns) == 0) + { + return AuTuple<>(); + } + else if constexpr (AuIsSame_v(argument))), void>) + { + (fn(AuGet(argument)), ...); + return; + } + else if constexpr (AuIsLValueReference_v(argument)))>) + { + return AuTupleTie(fn(AuGet(argument))...); + } + else if constexpr (AuIsRValueReference_v(argument)))>) + { + return AuTupleForward(fn(AuGet(argument))...); + } + else + { + return AuTuple(fn(AuGet(argument))...); + } + } +} + +template +static auto AuTupleTransform(const AuTuple &tuple, const Invokable &translate) +{ + return __audetail::AuTupleTransformImpl(translate, tuple, + AuMakeIndexSequence()); } \ No newline at end of file