Skip to content

Commit 5d00337

Browse files
committed
Rewrite is() for variables and templates
Adjust to new style of using one function for a match and series of constexpr ifs. There is a possibility to extend is() for matching std::integer_sequence but unfortunatelly clang is not support it (gcc & msvc do). template <template <typename, typename, typename...> class C, typename X> constexpr auto is( X const& ) { if constexpr (specialization_of_template<X, C>) { return std::true_type{}; } else { return std::false_type{}; } } template <template <typename, auto...> class C, typename X> constexpr auto is( X const& ) { if constexpr (specialization_of_template_type_and_nttp<X, C>) { return std::true_type{}; } else { return std::false_type{}; } } Alternatively we can support more matches for gcc & msvc by providing: #if defined(__clang__) template <template <typename...> class C, typename X> #else // allow us to support std::integer_sequence on gcc and msvc template <template <typename, typename, typename...> class C, typename X> #endif constexpr auto is( X const& ) { if constexpr (specialization_of_template<X, C>) { return std::true_type{}; } else { return std::false_type{}; } } #if defined(__clang__) template <template <typename, auto> class C, typename X> #else // allow us to support std::integer_sequence on gcc and msvc template <template <typename, auto...> class C, typename X> #endif constexpr auto is( X const& ) { if constexpr (specialization_of_template_type_and_nttp<X, C>) { return std::true_type{}; } else { return std::false_type{}; } }
1 parent 5d53385 commit 5d00337

File tree

1 file changed

+35
-21
lines changed

1 file changed

+35
-21
lines changed

include/cpp2util.h

+35-21
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,34 @@ using argument_of_t = CPP2_TYPEOF(argument_of_helper(std::declval<T>()));
381381
template <typename T>
382382
using pointee_t = std::iter_value_t<T>;
383383

384+
template <template <typename...> class C, typename... Ts>
385+
constexpr auto specialization_of_template_helper(C< Ts...> const& ) -> std::true_type {
386+
return {};
387+
}
388+
389+
template <template <typename, auto...> class C, typename T, auto... Ns>
390+
requires (sizeof...(Ns) > 0)
391+
constexpr auto specialization_of_template_helper(C< T, Ns... > const& ) -> std::true_type {
392+
return {};
393+
}
394+
384395
//-----------------------------------------------------------------------
385396
//
386397
// Concepts
387398
//
388399
//-----------------------------------------------------------------------
389400
//
390401

402+
template <typename X, template<typename...> class C>
403+
concept specialization_of_template = requires (X x) {
404+
{ specialization_of_template_helper<C>(std::forward<X>(x)) } -> std::same_as<std::true_type>;
405+
};
406+
407+
template <typename X, template<typename,auto...> class C>
408+
concept specialization_of_template_type_and_nttp = requires (X x) {
409+
{ specialization_of_template_helper<C>(std::forward<X>(x)) } -> std::same_as<std::true_type>;
410+
};
411+
391412
template <typename X>
392413
concept dereferencable = requires (X x) { *x; };
393414

@@ -1214,31 +1235,24 @@ using empty = void;
12141235

12151236
// Templates
12161237
//
1217-
template <template <typename...> class C, typename... Ts>
1218-
constexpr auto is(C< Ts...> const& ) -> bool {
1219-
return true;
1220-
}
1221-
1222-
#if defined(_MSC_VER)
1223-
template <template <typename, typename...> class C, typename T>
1224-
constexpr auto is( T const& ) -> bool {
1225-
return false;
1238+
template <template <typename...> class C, typename X>
1239+
constexpr auto is( X&& ) {
1240+
if constexpr (specialization_of_template<X, C>) {
1241+
return std::true_type{};
12261242
}
1227-
#else
1228-
template <template <typename...> class C, typename T>
1229-
constexpr auto is( T const& ) -> bool {
1230-
return false;
1243+
else {
1244+
return std::false_type{};
12311245
}
1232-
#endif
1233-
1234-
template <template <typename,auto> class C, typename T, auto V>
1235-
constexpr auto is( C<T, V> const& ) -> bool {
1236-
return true;
12371246
}
12381247

1239-
template <template <typename,auto> class C, typename T>
1240-
constexpr auto is( T const& ) -> bool {
1241-
return false;
1248+
template <template <typename, auto> class C, typename X>
1249+
constexpr auto is( X&& ) {
1250+
if constexpr (specialization_of_template_type_and_nttp<X, C>) {
1251+
return std::true_type{};
1252+
}
1253+
else {
1254+
return std::false_type{};
1255+
}
12421256
}
12431257

12441258
// Types

0 commit comments

Comments
 (0)