@@ -28,64 +28,45 @@ namespace detail {
2828// Forward declaration for deterministic reductions.
2929template <typename BinaryOperation> struct DeterministicOperatorWrapper ;
3030
31- template <typename T, typename U> struct is_like : public std ::is_same<T, U> {};
32-
33- template < typename T, typename U>
34- constexpr bool is_like_v = is_like<T, U>::value;
35-
36- template < typename T, typename U>
37- struct is_like <DeterministicOperatorWrapper<T>, U> : std::is_same<T, U> {};
38-
39- template < typename T, typename U>
40- struct is_like <T, DeterministicOperatorWrapper<U>> : std::is_same<T, U> {} ;
31+ template <typename T, class BinaryOperation ,
32+ template < typename > class ... KnownOperation>
33+ using IsKnownOp = std::bool_constant<(
34+ (std::is_same_v<BinaryOperation, KnownOperation<T>> ||
35+ std::is_same_v<BinaryOperation, KnownOperation< void >> ||
36+ std::is_same_v<BinaryOperation,
37+ DeterministicOperatorWrapper<KnownOperation<T>>> ||
38+ std::is_same_v<BinaryOperation,
39+ DeterministicOperatorWrapper<KnownOperation< void >>>) ||
40+ ...)> ;
4141
4242template <typename T, class BinaryOperation >
43- using IsPlus = std::bool_constant<is_like_v<BinaryOperation, sycl::plus<T>> ||
44- is_like_v<BinaryOperation, sycl::plus<void >>>;
43+ using IsPlus = IsKnownOp<T, BinaryOperation, sycl::plus>;
4544
4645template <typename T, class BinaryOperation >
47- using IsMultiplies =
48- std::bool_constant<is_like_v<BinaryOperation, sycl::multiplies<T>> ||
49- is_like_v<BinaryOperation, sycl::multiplies<void >>>;
46+ using IsMultiplies = IsKnownOp<T, BinaryOperation, sycl::multiplies>;
5047
5148template <typename T, class BinaryOperation >
52- using IsMinimum =
53- std::bool_constant<is_like_v<BinaryOperation, sycl::minimum<T>> ||
54- is_like_v<BinaryOperation, sycl::minimum<void >>>;
49+ using IsMinimum = IsKnownOp<T, BinaryOperation, sycl::minimum>;
5550
5651template <typename T, class BinaryOperation >
57- using IsMaximum =
58- std::bool_constant<is_like_v<BinaryOperation, sycl::maximum<T>> ||
59- is_like_v<BinaryOperation, sycl::maximum<void >>>;
52+ using IsMaximum = IsKnownOp<T, BinaryOperation, sycl::maximum>;
6053
6154template <typename T, class BinaryOperation >
62- using IsBitAND =
63- std::bool_constant<is_like_v<BinaryOperation, sycl::bit_and<T>> ||
64- is_like_v<BinaryOperation, sycl::bit_and<void >>>;
55+ using IsBitAND = IsKnownOp<T, BinaryOperation, sycl::bit_and>;
6556
6657template <typename T, class BinaryOperation >
67- using IsBitOR =
68- std::bool_constant<is_like_v<BinaryOperation, sycl::bit_or<T>> ||
69- is_like_v<BinaryOperation, sycl::bit_or<void >>>;
58+ using IsBitOR = IsKnownOp<T, BinaryOperation, sycl::bit_or>;
7059
7160template <typename T, class BinaryOperation >
72- using IsBitXOR =
73- std::bool_constant<is_like_v<BinaryOperation, sycl::bit_xor<T>> ||
74- is_like_v<BinaryOperation, sycl::bit_xor<void >>>;
61+ using IsBitXOR = IsKnownOp<T, BinaryOperation, sycl::bit_xor>;
7562
7663template <typename T, class BinaryOperation >
7764using IsLogicalAND =
78- std::bool_constant<is_like_v<BinaryOperation, std::logical_and<T>> ||
79- is_like_v<BinaryOperation, std::logical_and<void >> ||
80- is_like_v<BinaryOperation, sycl::logical_and<T>> ||
81- is_like_v<BinaryOperation, sycl::logical_and<void >>>;
65+ IsKnownOp<T, BinaryOperation, std::logical_and, sycl::logical_and>;
8266
8367template <typename T, class BinaryOperation >
8468using IsLogicalOR =
85- std::bool_constant<is_like_v<BinaryOperation, std::logical_or<T>> ||
86- is_like_v<BinaryOperation, std::logical_or<void >> ||
87- is_like_v<BinaryOperation, sycl::logical_or<T>> ||
88- is_like_v<BinaryOperation, sycl::logical_or<void >>>;
69+ IsKnownOp<T, BinaryOperation, std::logical_or, sycl::logical_or>;
8970
9071// Use SFINAE so that the "true" branch could be implemented in
9172// include/sycl/stl_wrappers/complex that would only be available if STL's
0 commit comments