Skip to content

Commit

Permalink
Implement apply_traits
Browse files Browse the repository at this point in the history
  • Loading branch information
jfalcou authored May 29, 2024
1 parent 80b9217 commit c590834
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
24 changes: 24 additions & 0 deletions include/kumi/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,30 @@ namespace kumi
//================================================================================================
}

namespace kumi
{
template< template<typename...> typename Traits
, product_type Tuple
, typename Seq = std::make_index_sequence<size<Tuple>::value>
>
struct apply_traits;

template< template<typename...> typename Traits
, product_type Tuple
, std::size_t... Is
>
requires( requires {typename Traits<element_t<Is,Tuple>...>::type;})
struct apply_traits<Traits, Tuple, std::index_sequence<Is...>>
{
using type = typename Traits<element_t<Is,Tuple>...>::type;
};

template< template<typename...> typename Traits
, product_type Tuple
>
using apply_traits_t = typename apply_traits<Traits, Tuple>::type;
}

#include <kumi/algorithm.hpp>

#undef KUMI_FWD
Expand Down
21 changes: 21 additions & 0 deletions standalone/kumi/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,27 @@ namespace kumi
}
}
namespace kumi
{
template< template<typename...> typename Traits
, product_type Tuple
, typename Seq = std::make_index_sequence<size<Tuple>::value>
>
struct apply_traits;
template< template<typename...> typename Traits
, product_type Tuple
, std::size_t... Is
>
requires( requires {typename Traits<element_t<Is,Tuple>...>::type;})
struct apply_traits<Traits, Tuple, std::index_sequence<Is...>>
{
using type = typename Traits<element_t<Is,Tuple>...>::type;
};
template< template<typename...> typename Traits
, product_type Tuple
>
using apply_traits_t = typename apply_traits<Traits, Tuple>::type;
}
namespace kumi
{
}
namespace kumi
Expand Down
65 changes: 65 additions & 0 deletions test/unit/apply_traits.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//==================================================================================================
/*
KUMI - Compact Tuple Tools
Copyright : KUMI Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include "kumi/utils/concepts.hpp"
#include <concepts>
#include <type_traits>
#define TTS_MAIN
#include <kumi/tuple.hpp>
#include <tts/tts.hpp>

template<typename... T>
struct nary_traits : std::integral_constant<std::size_t, std::max({sizeof(T)...})>
{};

TTS_CASE("Check apply_traits behavior")
{
TTS_TYPE_IS ( (kumi::apply_traits_t < nary_traits
, kumi::tuple<int const, char, void*, float, double&, volatile short>
>)
, (std::integral_constant<std::size_t, 8>)
);
};

template<kumi::product_type T>
kumi::apply_traits_t<nary_traits, T> f(T const&)
{
return {};
}

template<kumi::product_type T>
kumi::apply_traits_t<std::add_pointer, T> g(T const&)
{
return {};
}

template<typename... T>
requires( std::is_floating_point_v<T> && ...)
struct strict_traits
{
using type = bool;
};

template<kumi::product_type T>
kumi::apply_traits_t<strict_traits, T> h(T const&)
{
return true;
}

TTS_CASE("Check apply_traits SFINAE compliance")
{
kumi::tuple<char,short,double> t;
kumi::tuple<float,double,float,double> u;

// wrong # of arguments to traits
TTS_EXPECT_COMPILES(t, { f(t); } );
TTS_EXPECT_NOT_COMPILES(t, { g(t); } );

// Unsupported types within tuple
TTS_EXPECT_COMPILES(u, { h(u); } );
TTS_EXPECT_NOT_COMPILES(t, { h(t); } );
};

0 comments on commit c590834

Please sign in to comment.