Skip to content

Commit

Permalink
implement alpaka::meta::isTuple, alpaka::meta::toTuple and alpaka::me…
Browse files Browse the repository at this point in the history
…ta::toUniqueTypeTuple
  • Loading branch information
SimeonEhrig committed May 14, 2024
1 parent f3664a1 commit 31c5b82
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
61 changes: 61 additions & 0 deletions include/alpaka/meta/TypeListOps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include <tuple>
#include <type_traits>

namespace alpaka::meta
Expand Down Expand Up @@ -35,4 +36,64 @@ namespace alpaka::meta
{
static constexpr bool value = std::is_same_v<Head, Value> || Contains<List<Tail...>, 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<typename T>
struct IsTuple : std::false_type
{
};

template<typename... U>
struct IsTuple<std::tuple<U...>> : std::true_type
{
};

template<typename T>
constexpr bool isTuple = IsTuple<std::decay_t<T>>::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<typename... T>
struct toTuple
{
using type = std::tuple<T...>;
};

template<typename... U>
struct toTuple<std::tuple<U...>>
{
using type = std::tuple<U...>;
};

namespace detail
{
template<typename Out, typename In>
struct filterRedundantTupleTypes;

template<typename... Out, typename InCar, typename... InCdr>
struct filterRedundantTupleTypes<std::tuple<Out...>, std::tuple<InCar, InCdr...>>
{
using type = typename std::conditional<
alpaka::meta::Contains<std::tuple<Out...>, InCar>::value,
typename filterRedundantTupleTypes<std::tuple<Out...>, std::tuple<InCdr...>>::type,
typename filterRedundantTupleTypes<std::tuple<Out..., InCar>, std::tuple<InCdr...>>::type>::type;
};

template<typename Out>
struct filterRedundantTupleTypes<Out, std::tuple<>>
{
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<typename T, typename = std::enable_if_t<alpaka::meta::isTuple<T>>>
using toUniqueTypeTuple = typename detail::filterRedundantTupleTypes<std::tuple<>, T>::type;

} // namespace alpaka::meta
31 changes: 31 additions & 0 deletions test/unit/meta/src/TypeListOpsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,34 @@ TEST_CASE("contains", "[meta]")
STATIC_REQUIRE(alpaka::meta::Contains<std::tuple<short, int, double, float>, float>::value);
STATIC_REQUIRE(!alpaka::meta::Contains<std::tuple<short, int, double, float>, char>::value);
}

TEST_CASE("isTuple", "[meta]")
{
STATIC_REQUIRE(alpaka::meta::isTuple<std::tuple<int>>);
STATIC_REQUIRE(alpaka::meta::isTuple<std::tuple<int, float>>);
STATIC_REQUIRE_FALSE(alpaka::meta::isTuple<int>);
}

TEST_CASE("toTuple", "[meta]")
{
STATIC_REQUIRE(std::is_same_v<typename alpaka::meta::toTuple<int>::type, std::tuple<int>>);
STATIC_REQUIRE(
std::is_same_v<typename alpaka::meta::toTuple<int, float, double>::type, std::tuple<int, float, double>>);
STATIC_REQUIRE(std::is_same_v<typename alpaka::meta::toTuple<std::tuple<int>>::type, std::tuple<int>>);
STATIC_REQUIRE(std::is_same_v<
typename alpaka::meta::toTuple<std::tuple<int, float, double>>::type,
std::tuple<int, float, double>>);
}

TEST_CASE("toUniqueTypeTuple", "[meta]")
{
STATIC_REQUIRE(std::is_same_v<alpaka::meta::toUniqueTypeTuple<std::tuple<int, int>>, std::tuple<int>>);
STATIC_REQUIRE(std::is_same_v<alpaka::meta::toUniqueTypeTuple<std::tuple<int>>, std::tuple<int>>);
STATIC_REQUIRE(std::is_same_v<alpaka::meta::toUniqueTypeTuple<std::tuple<int, int, int, int>>, std::tuple<int>>);
STATIC_REQUIRE(std::is_same_v<
alpaka::meta::toUniqueTypeTuple<std::tuple<int, double, float>>,
std::tuple<int, double, float>>);
STATIC_REQUIRE(std::is_same_v<
alpaka::meta::toUniqueTypeTuple<std::tuple<int, float, double, int, float>>,
std::tuple<int, float, double>>);
}

0 comments on commit 31c5b82

Please sign in to comment.