1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <iostream>
#include <concepts>
#include <type_traits>
template <class T, class... Ts>
struct any_same : std::disjunction<std::is_same<T,Ts>...> {};
template<typename T,typename First,typename...Ts>
constexpr size_t elmt_index()noexcept {
if constexpr ( std::is_same_v<T,First> ) {
return 0;
}
else if constexpr ( sizeof...(Ts) == 0 ) {
static_assert( sizeof(T)==0 , "T n'est pas dans la liste des Ts" );
}
else {
//static_assert( sizeof...(Ts) != 0 );
return 1 + elmt_index<T,Ts...>();
}
}
template<class... Ts> requires std::negation_v<any_same<Ts...>>
struct System {
template<typename T> requires any_same<T,Ts...>::value
struct Item {
static constexpr std::size_t index = elmt_index<T,Ts...>();
};
};
template<typename T,typename...Ts>
struct trait : std::false_type {};
template<typename T,typename...Ts>
requires requires { typename System<Ts...>::template Item<T>; } // cas où Item<T> existe dans System<Ts...>
struct trait<T,Ts...> : std::true_type {};
int main() {
System<int, float,char>::Item<float> x;
//System<float, float> y;
//System<int,float,char>::Item<double> z;
//size_t w = elmt_index<double, int>();
static_assert( trait<float, int,float,char>::value );
static_assert( ! trait<double, int,float,char>::value );
} |
Partager