22
22
# error "This file requires MDSPAN_ENABLE_P3663=ON"
23
23
#endif
24
24
25
+ namespace my_test {
26
+
27
+ template <class First , class Second >
28
+ struct my_aggregate_pair {
29
+ First first;
30
+ Second second;
31
+ };
32
+
33
+ // Not an aggregate, to force use of the tuple protocol.
34
+ template <class First , class Second >
35
+ class my_nonaggregate_pair {
36
+ public:
37
+ constexpr my_nonaggregate_pair (First first, Second second)
38
+ : first_(first), second_(second)
39
+ {}
40
+
41
+ template <std::size_t Index, class Self >
42
+ constexpr decltype (auto ) get(this Self&& self) {
43
+ if constexpr (Index == 0 ) {
44
+ return self.first_ ;
45
+ }
46
+ else if constexpr (Index == 1 ) {
47
+ return self.second_ ;
48
+ }
49
+ else {
50
+ static_assert (false , " Invalid index" );
51
+ }
52
+ }
53
+
54
+ private:
55
+ First first_;
56
+ Second second_;
57
+ };
58
+
59
+ } // namespace my_test
60
+
61
+ template <class First , class Second >
62
+ struct std ::tuple_size<my_test::my_nonaggregate_pair<First, Second>>
63
+ : std::integral_constant<std::size_t , 2 > {};
64
+
65
+ template <std::size_t Index, class First , class Second >
66
+ struct std ::tuple_element<Index, my_test::my_nonaggregate_pair<First, Second>> {
67
+ static_assert (false , " Invalid index" );
68
+ };
69
+
70
+ template <class First , class Second >
71
+ struct std ::tuple_element<0 , my_test::my_nonaggregate_pair<First, Second>> {
72
+ using type = First;
73
+ };
74
+
75
+ template <class First , class Second >
76
+ struct std ::tuple_element<1 , my_test::my_nonaggregate_pair<First, Second>> {
77
+ using type = Second;
78
+ };
79
+
25
80
namespace {
26
81
27
82
template <class T >
@@ -44,6 +99,14 @@ constexpr bool slice_equal(const Left&, Kokkos::full_extent_t) {
44
99
return std::is_convertible_v<Left, Kokkos::full_extent_t >;
45
100
}
46
101
102
+ template <class OffsetType , class ExtentType , class StrideType >
103
+ constexpr bool slice_equal (
104
+ const Kokkos::strided_slice<OffsetType, ExtentType, StrideType>& left,
105
+ const Kokkos::strided_slice<OffsetType, ExtentType, StrideType>& right)
106
+ {
107
+ return left.offset == right.offset && left.extent == right.extent && left.stride == right.stride ;
108
+ }
109
+
47
110
template <class ExpectedResult , class InputExtents , class ... Slices>
48
111
void
49
112
test_canonicalize_slices (
@@ -92,4 +155,26 @@ TEST(CanonicalizeSlices, Rank1_integer_static) {
92
155
test_canonicalize_slices (expected_slices, exts, slice0);
93
156
}
94
157
158
+ TEST (CanonicalizeSlices, Rank1_aggregate_pair) {
159
+ constexpr auto slice0 = my_test::my_aggregate_pair<int , int >{7 , 11 };
160
+ constexpr auto expected_slices = std::tuple{Kokkos::strided_slice{
161
+ .offset = size_t (7u ),
162
+ .extent = (size_t (11u ) - size_t (7u )),
163
+ .stride = std::cw<size_t (1u )>
164
+ }};
165
+ constexpr auto exts = Kokkos::extents<size_t , 13 >{};
166
+ test_canonicalize_slices (expected_slices, exts, slice0);
167
+ }
168
+
169
+ TEST (CanonicalizeSlices, Rank1_nonaggregate_pair) {
170
+ constexpr auto slice0 = my_test::my_nonaggregate_pair<int , int >(7 , 11 );
171
+ constexpr auto expected_slices = std::tuple{Kokkos::strided_slice{
172
+ .offset = size_t (7u ),
173
+ .extent = (size_t (11u ) - size_t (7u )),
174
+ .stride = std::cw<size_t (1u )>
175
+ }};
176
+ constexpr auto exts = Kokkos::extents<size_t , 13 >{};
177
+ test_canonicalize_slices (expected_slices, exts, slice0);
178
+ }
179
+
95
180
} // namespace (anonymous)
0 commit comments