From 31c5b82df8329db8ea11c505afc1601874bba91b Mon Sep 17 00:00:00 2001 From: Simeon Ehrig Date: Mon, 13 May 2024 19:55:33 +0200 Subject: [PATCH] implement alpaka::meta::isTuple, alpaka::meta::toTuple and alpaka::meta::toUniqueTypeTuple --- include/alpaka/meta/TypeListOps.hpp | 61 ++++++++++++++++++++++++++ test/unit/meta/src/TypeListOpsTest.cpp | 31 +++++++++++++ 2 files changed, 92 insertions(+) diff --git a/include/alpaka/meta/TypeListOps.hpp b/include/alpaka/meta/TypeListOps.hpp index 2d6bcfe7f45f..0214ea43133d 100644 --- a/include/alpaka/meta/TypeListOps.hpp +++ b/include/alpaka/meta/TypeListOps.hpp @@ -4,6 +4,7 @@ #pragma once +#include #include namespace alpaka::meta @@ -35,4 +36,64 @@ namespace alpaka::meta { static constexpr bool value = std::is_same_v || Contains, Value>::value; }; + + // copied from https://stackoverflow.com/a/51073558/22035743 + //! \brief check if the given type is a std::tuple + //! \tparam T possible std::tuple + template + struct IsTuple : std::false_type + { + }; + + template + struct IsTuple> : std::true_type + { + }; + + template + constexpr bool isTuple = IsTuple>::value; + + //! \brief The type of the struct is a std::tuple with the given types. If T is a std::tuple, the type of the + //! struct is the same type. + //! \tparam T possible std::tuple + template + struct toTuple + { + using type = std::tuple; + }; + + template + struct toTuple> + { + using type = std::tuple; + }; + + namespace detail + { + template + struct filterRedundantTupleTypes; + + template + struct filterRedundantTupleTypes, std::tuple> + { + using type = typename std::conditional< + alpaka::meta::Contains, InCar>::value, + typename filterRedundantTupleTypes, std::tuple>::type, + typename filterRedundantTupleTypes, std::tuple>::type>::type; + }; + + template + struct filterRedundantTupleTypes> + { + using type = Out; + }; + } // namespace detail + + // copied from + // https://stackoverflow.com/questions/55941964/how-to-filter-duplicate-types-from-tuple-c/55942130#55942130 + //! \brief remove all redundant types from std::tuple + //! \tparam T std::tuple + template>> + using toUniqueTypeTuple = typename detail::filterRedundantTupleTypes, T>::type; + } // namespace alpaka::meta diff --git a/test/unit/meta/src/TypeListOpsTest.cpp b/test/unit/meta/src/TypeListOpsTest.cpp index b15e77733cc2..806972914582 100644 --- a/test/unit/meta/src/TypeListOpsTest.cpp +++ b/test/unit/meta/src/TypeListOpsTest.cpp @@ -26,3 +26,34 @@ TEST_CASE("contains", "[meta]") STATIC_REQUIRE(alpaka::meta::Contains, float>::value); STATIC_REQUIRE(!alpaka::meta::Contains, char>::value); } + +TEST_CASE("isTuple", "[meta]") +{ + STATIC_REQUIRE(alpaka::meta::isTuple>); + STATIC_REQUIRE(alpaka::meta::isTuple>); + STATIC_REQUIRE_FALSE(alpaka::meta::isTuple); +} + +TEST_CASE("toTuple", "[meta]") +{ + STATIC_REQUIRE(std::is_same_v::type, std::tuple>); + STATIC_REQUIRE( + std::is_same_v::type, std::tuple>); + STATIC_REQUIRE(std::is_same_v>::type, std::tuple>); + STATIC_REQUIRE(std::is_same_v< + typename alpaka::meta::toTuple>::type, + std::tuple>); +} + +TEST_CASE("toUniqueTypeTuple", "[meta]") +{ + STATIC_REQUIRE(std::is_same_v>, std::tuple>); + STATIC_REQUIRE(std::is_same_v>, std::tuple>); + STATIC_REQUIRE(std::is_same_v>, std::tuple>); + STATIC_REQUIRE(std::is_same_v< + alpaka::meta::toUniqueTypeTuple>, + std::tuple>); + STATIC_REQUIRE(std::is_same_v< + alpaka::meta::toUniqueTypeTuple>, + std::tuple>); +}