diff --git a/sycl/include/sycl/ext/oneapi/properties/new_properties.hpp b/sycl/include/sycl/ext/oneapi/properties/new_properties.hpp new file mode 100644 index 0000000000000..a71e46b35ec13 --- /dev/null +++ b/sycl/include/sycl/ext/oneapi/properties/new_properties.hpp @@ -0,0 +1,399 @@ +//==-------- new_properties.hpp --- SYCL extended property list ------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include +#include +#include + +#ifndef __SYCL_EBO +#include +#endif + +namespace sycl { +inline namespace _V1 { +namespace ext::oneapi::experimental { +namespace new_properties { +namespace detail { +template struct properties_type_list; + +// Is used to implement `is_property_v`. +struct property_key_tag_base {}; +} // namespace detail + +template +class __SYCL_EBO properties; + +template struct is_property_list : std::false_type {}; +template +struct is_property_list> : std::true_type {}; +template +inline constexpr bool is_property_list_v = is_property_list::value; + +template +inline constexpr bool is_property_v = + std::is_base_of_v && + !is_property_list_v; + +namespace detail { + +#if __has_builtin(__type_pack_element) +template +using nth_type_t = __type_pack_element; +#else +template struct nth_type { + using type = typename nth_type::type; +}; + +template struct nth_type<0, T, Ts...> { + using type = T; +}; + +template +using nth_type_t = typename nth_type::type; +#endif + +template struct properties_sorter; + +// Specialization to avoid zero-size array creation. +template <> struct properties_sorter> { + using type = properties_type_list<>; +}; + +template +struct properties_sorter, + property_tys...> { + static constexpr auto sorted_indices = []() constexpr { + int idx = 0; + int N = sizeof...(property_tys); + // std::sort isn't constexpr until C++20. Also, it's possible there will be + // a compiler builtin to sort types, in which case we should start using it. + std::array to_sort{std::pair{property_tys::property_name, idx++}...}; + auto swap_pair = [](auto &x, auto &y) constexpr { + auto tmp_first = x.first; + auto tmp_second = x.second; + x.first = y.first; + x.second = y.second; + y.first = tmp_first; + y.second = tmp_second; + }; + for (int i = 0; i < N; ++i) + for (int j = i; j < N; ++j) + if (to_sort[j].first < to_sort[i].first) + swap_pair(to_sort[i], to_sort[j]); + + std::array sorted_indices{}; + for (int i = 0; i < N; ++i) + sorted_indices[i] = to_sort[i].second; + + return sorted_indices; + }(); + + using type = properties_type_list< + nth_type_t...>; +}; + +// Need "universal template" +// (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2989r2.pdf) to +// simplify this to a single template and support mixed type/non-type template +// parameters in properties. +template struct property_key_non_template : property_key_tag_base {}; +template