|
10 | 10 |
|
11 | 11 | #include <sycl/detail/property_helper.hpp>
|
12 | 12 | #include <sycl/ext/oneapi/properties/property.hpp>
|
| 13 | +#include <sycl/detail/boost/mp11.hpp> |
13 | 14 |
|
14 | 15 | #include <tuple>
|
15 | 16 |
|
@@ -106,93 +107,20 @@ template <typename RHS> struct SelectNonVoid<void, RHS> {
|
106 | 107 | using type = RHS;
|
107 | 108 | };
|
108 | 109 |
|
109 |
| -// Merges two tuples by recursively extracting the type with the minimum |
110 |
| -// PropertyID in the two tuples and prepending it to the merging of the |
111 |
| -// remaining elements. |
112 |
| -template <typename T1, typename T2> struct Merge {}; |
113 |
| -template <typename... LTs> struct Merge<std::tuple<LTs...>, std::tuple<>> { |
114 |
| - using type = std::tuple<LTs...>; |
| 110 | +// Sort types accoring to their PropertyID. |
| 111 | +struct SortByPropertyId { |
| 112 | + template <typename T1, typename T2> |
| 113 | + using fn = sycl::detail::boost::mp11::mp_bool<(PropertyID<T1>::value < |
| 114 | + PropertyID<T2>::value)>; |
115 | 115 | };
|
116 |
| -template <typename... RTs> struct Merge<std::tuple<>, std::tuple<RTs...>> { |
117 |
| - using type = std::tuple<RTs...>; |
118 |
| -}; |
119 |
| -template <typename... LTs, typename... RTs> |
120 |
| -struct Merge<std::tuple<LTs...>, std::tuple<RTs...>> { |
121 |
| - using l_head = GetFirstType<LTs...>; |
122 |
| - using r_head = GetFirstType<RTs...>; |
123 |
| - static constexpr bool left_has_min = |
124 |
| - PropertyID<l_head>::value < PropertyID<r_head>::value; |
125 |
| - using l_split = HeadSplit<std::tuple<LTs...>, left_has_min>; |
126 |
| - using r_split = HeadSplit<std::tuple<RTs...>, !left_has_min>; |
127 |
| - using min = typename SelectNonVoid<typename l_split::htype, |
128 |
| - typename r_split::htype>::type; |
129 |
| - using merge_tails = |
130 |
| - typename Merge<typename l_split::ttype, typename r_split::ttype>::type; |
131 |
| - using type = typename PrependTuple<min, merge_tails>::type; |
132 |
| -}; |
133 |
| - |
134 |
| -// Creates pairs of tuples with a single element from a tuple with N elements. |
135 |
| -// Resulting tuple will have ceil(N/2) elements. |
136 |
| -template <typename...> struct CreateTuplePairs { |
137 |
| - using type = typename std::tuple<>; |
138 |
| -}; |
139 |
| -template <typename T> struct CreateTuplePairs<T> { |
140 |
| - using type = typename std::tuple<std::pair<std::tuple<T>, std::tuple<>>>; |
141 |
| -}; |
142 |
| -template <typename L, typename R, typename... Rest> |
143 |
| -struct CreateTuplePairs<L, R, Rest...> { |
144 |
| - using type = |
145 |
| - typename PrependTuple<std::pair<std::tuple<L>, std::tuple<R>>, |
146 |
| - typename CreateTuplePairs<Rest...>::type>::type; |
147 |
| -}; |
148 |
| - |
149 |
| -// Merges pairs of tuples and creates new pairs of the merged pairs. Let N be |
150 |
| -// the number of pairs in the supplied tuple, then the resulting tuple will |
151 |
| -// contain ceil(N/2) pairs of tuples. |
152 |
| -template <typename T> struct MergePairs { |
153 |
| - using type = std::tuple<>; |
154 |
| -}; |
155 |
| -template <typename... LTs, typename... RTs, typename... Rest> |
156 |
| -struct MergePairs< |
157 |
| - std::tuple<std::pair<std::tuple<LTs...>, std::tuple<RTs...>>, Rest...>> { |
158 |
| - using merged = typename Merge<std::tuple<LTs...>, std::tuple<RTs...>>::type; |
159 |
| - using type = std::tuple<std::pair<merged, std::tuple<>>>; |
160 |
| -}; |
161 |
| -template <typename... LLTs, typename... LRTs, typename... RLTs, |
162 |
| - typename... RRTs, typename... Rest> |
163 |
| -struct MergePairs< |
164 |
| - std::tuple<std::pair<std::tuple<LLTs...>, std::tuple<LRTs...>>, |
165 |
| - std::pair<std::tuple<RLTs...>, std::tuple<RRTs...>>, Rest...>> { |
166 |
| - using lmerged = |
167 |
| - typename Merge<std::tuple<LLTs...>, std::tuple<LRTs...>>::type; |
168 |
| - using rmerged = |
169 |
| - typename Merge<std::tuple<RLTs...>, std::tuple<RRTs...>>::type; |
170 |
| - using type = typename PrependTuple< |
171 |
| - std::pair<lmerged, rmerged>, |
172 |
| - typename MergePairs<std::tuple<Rest...>>::type>::type; |
173 |
| -}; |
174 |
| - |
175 |
| -// Recursively merges all pairs of tuples until only a single pair of tuples |
176 |
| -// is left, where the right element of the pair is an empty tuple. |
177 |
| -template <typename T> struct MergeAll {}; |
178 |
| -template <typename... Ts> struct MergeAll<std::tuple<Ts...>> { |
179 |
| - using type = std::tuple<Ts...>; |
180 |
| -}; |
181 |
| -template <typename... Ts> |
182 |
| -struct MergeAll<std::tuple<std::pair<std::tuple<Ts...>, std::tuple<>>>> { |
183 |
| - using type = std::tuple<Ts...>; |
184 |
| -}; |
185 |
| -template <typename T, typename... Ts> struct MergeAll<std::tuple<T, Ts...>> { |
186 |
| - using reduced = typename MergePairs<std::tuple<T, Ts...>>::type; |
187 |
| - using type = typename MergeAll<reduced>::type; |
188 |
| -}; |
189 |
| - |
190 |
| -// Performs merge-sort on types with PropertyID. |
191 | 116 | template <typename... Ts> struct Sorted {
|
192 | 117 | static_assert(detail::AllPropertyValues<std::tuple<Ts...>>::value,
|
193 | 118 | "Unrecognized property in property list.");
|
194 |
| - using split = typename CreateTuplePairs<Ts...>::type; |
195 |
| - using type = typename MergeAll<split>::type; |
| 119 | + using properties = sycl::detail::boost::mp11::mp_list<Ts...>; |
| 120 | + using sortedProperties = |
| 121 | + sycl::detail::boost::mp11::mp_sort_q<properties, SortByPropertyId>; |
| 122 | + using type = |
| 123 | + sycl::detail::boost::mp11::mp_rename<sortedProperties, std::tuple>; |
196 | 124 | };
|
197 | 125 |
|
198 | 126 | // Checks if the types in a tuple are sorted w.r.t. their PropertyID.
|
|
0 commit comments