@@ -272,6 +272,114 @@ struct MergeProperties<std::tuple<LHSPropertyTs...>,
272
272
using type = typename PrependTuple<min, merge_tails>::type;
273
273
};
274
274
275
+ // ******************************************************************************
276
+ // Property value tooling
277
+ // ******************************************************************************
278
+
279
+ // Simple helpers for containing primitive types as template arguments.
280
+ template <size_t ... Sizes> struct SizeList {};
281
+ template <char ... Sizes> struct CharList {};
282
+
283
+ // Helper for converting characters to a constexpr string.
284
+ template <char ... Chars> struct CharsToStr {
285
+ static inline constexpr const char value[] = {Chars..., ' \0 ' };
286
+ };
287
+
288
+ // Helper for converting a list of size_t values to a comma-separated string
289
+ // representation. This is done by extracting the digit one-by-one and when
290
+ // finishing a value, the parsed result is added to a separate list of
291
+ // "parsed" characters with the delimiter.
292
+ template <typename List, typename ParsedList, char ... Chars>
293
+ struct SizeListToStrHelper ;
294
+
295
+ // Specialization for when we are in the process of converting a non-zero value
296
+ // (Value). Chars will have the already converted digits of the original value
297
+ // being converted. Instantiation of this will convert the least significant
298
+ // digit in Value.
299
+ // Example:
300
+ // - Current: SizeListToStrHelper<SizeList<12>, CharList<'1', '0', ','>, '3'>
301
+ // - Next: SizeListToStrHelper<SizeList<1>, CharList<'1', '0', ','>, '2', '3'>
302
+ // - Outermost: SizeListToStrHelper<SizeList<10,123>, CharList<>>
303
+ // - Final: SizeListToStrHelper<SizeList<0>,
304
+ // CharList<'1', '0', ','>, '1', '2', '3'>>
305
+ // - Result string: "10,123"
306
+ template <size_t Value, size_t ... Values, char ... ParsedChars, char ... Chars>
307
+ struct SizeListToStrHelper <SizeList<Value, Values...>, CharList<ParsedChars...>,
308
+ Chars...>
309
+ : SizeListToStrHelper<SizeList<Value / 10 , Values...>,
310
+ CharList<ParsedChars...>, ' 0' + (Value % 10 ),
311
+ Chars...> {};
312
+
313
+ // Specialization for when we have reached 0 in the current value we are
314
+ // converting. In this case we are done with converting the current value and
315
+ // we insert the converted digits from Chars into ParsedChars.
316
+ // Example:
317
+ // - Current: SizeListToStrHelper<SizeList<0,123>, CharList<>, '1', '0'>
318
+ // - Next: SizeListToStrHelper<SizeList<123>, CharList<'1', '0', ','>>
319
+ // - Outermost: SizeListToStrHelper<SizeList<10,123>, CharList<>>
320
+ // - Final: SizeListToStrHelper<SizeList<0>,
321
+ // CharList<'1', '0', ','>, '1', '2', '3'>>
322
+ // - Result string: "10,123"
323
+ template <size_t ... Values, char ... ParsedChars, char ... Chars>
324
+ struct SizeListToStrHelper <SizeList<0 , Values...>, CharList<ParsedChars...>,
325
+ Chars...>
326
+ : SizeListToStrHelper<SizeList<Values...>,
327
+ CharList<ParsedChars..., Chars..., ' ,' >> {};
328
+
329
+ // Specialization for the special case where the value we are converting is 0
330
+ // but the list of converted digits is empty. This means there was a 0 value in
331
+ // the list and we can add it to ParsedChars directly.
332
+ // Example:
333
+ // - Current: SizeListToStrHelper<SizeList<0,123>, CharList<>>
334
+ // - Next: SizeListToStrHelper<SizeList<123>, CharList<'0', ','>>
335
+ // - Outermost: SizeListToStrHelper<SizeList<0,123>, CharList<>>
336
+ // - Final: SizeListToStrHelper<SizeList<0>,
337
+ // CharList<'0', ','>, '1', '2', '3'>>
338
+ // - Result string: "0,123"
339
+ template <size_t ... Values, char ... ParsedChars>
340
+ struct SizeListToStrHelper <SizeList<0 , Values...>, CharList<ParsedChars...>>
341
+ : SizeListToStrHelper<SizeList<Values...>,
342
+ CharList<ParsedChars..., ' 0' , ' ,' >> {};
343
+
344
+ // Specialization for when we have reached 0 in the current value we are
345
+ // converting and there a no more values to parse. In this case we are done with
346
+ // converting the current value and we insert the converted digits from Chars
347
+ // into ParsedChars. We do not add a ',' as it is the end of the list.
348
+ // Example:
349
+ // - Current: SizeListToStrHelper<SizeList<0>, CharList<'1', '0', ','>, '1',
350
+ // '2', '3'>>
351
+ // - Next: None.
352
+ // - Outermost: SizeListToStrHelper<SizeList<10,123>, CharList<>>
353
+ // - Final: SizeListToStrHelper<SizeList<0>,
354
+ // CharList<'1', '0', ','>, '1', '2', '3'>>
355
+ // - Result string: "10,123"
356
+ template <char ... ParsedChars, char ... Chars>
357
+ struct SizeListToStrHelper <SizeList<0 >, CharList<ParsedChars...>, Chars...>
358
+ : CharsToStr<ParsedChars..., Chars...> {};
359
+
360
+ // Specialization for when we have reached 0 in the current value we are
361
+ // converting and there a no more values to parse, but the list of converted
362
+ // digits is empty. This means the last value in the list was a 0 so we can add
363
+ // that to the ParsedChars and finish.
364
+ // Example:
365
+ // - Current: SizeListToStrHelper<SizeList<0>, CharList<'1', '0', ','>>>
366
+ // - Next: None.
367
+ // - Outermost: SizeListToStrHelper<SizeList<10,0>, CharList<>>
368
+ // - Final: SizeListToStrHelper<SizeList<0>, CharList<>, '1', '0'>>
369
+ // - Result string: "10,0"
370
+ template <char ... ParsedChars>
371
+ struct SizeListToStrHelper <SizeList<0 >, CharList<ParsedChars...>>
372
+ : CharsToStr<ParsedChars..., ' 0' > {};
373
+
374
+ // Specialization for the empty list of values to convert. This results in an
375
+ // empty string.
376
+ template <>
377
+ struct SizeListToStrHelper <SizeList<>, CharList<>> : CharsToStr<> {};
378
+
379
+ // Converts size_t values to a comma-separated string representation.
380
+ template <size_t ... Sizes>
381
+ struct SizeListToStr : SizeListToStrHelper<SizeList<Sizes...>, CharList<>> {};
382
+
275
383
} // namespace detail
276
384
} // namespace experimental
277
385
} // namespace oneapi
0 commit comments