@@ -142,6 +142,10 @@ struct property_base : property_key_tag<property_key_t> {
142142 }
143143};
144144
145+ template <template <auto ...> typename property> struct property_key ;
146+ template <template <auto ...> typename property>
147+ using property_key_t = typename property_key<property>::type;
148+
145149template <typename ... property_tys>
146150inline constexpr bool property_names_are_unique = []() constexpr {
147151 if constexpr (sizeof ...(property_tys) == 0 ) {
@@ -177,14 +181,23 @@ inline constexpr bool properties_are_sorted = []() constexpr {
177181 }
178182}();
179183
180- template <typename property_key_t >
181- inline constexpr property_key_tag<property_key_t > key{};
184+ template <template <auto ...> typename property>
185+ constexpr auto key () {
186+ return property_key_tag<property_key_t <property>>{};
187+ }
188+ template <typename property>
189+ constexpr auto key () {
190+ return property_key_tag<property>{};
191+ }
182192} // namespace detail
183193
184194// Empty property list.
185195template <> class __SYCL_EBO properties<detail::properties_type_list<>, void > {
186196public:
187197 template <typename > static constexpr bool has_property () { return false ; }
198+ template <template <auto ...> typename > static constexpr bool has_property () {
199+ return false ;
200+ }
188201
189202 // TODO: How does this work without qualified name?
190203 template <typename other_property_t >
@@ -253,38 +266,54 @@ class __SYCL_EBO properties<
253266 constexpr properties (unsorted_property_tys... props)
254267 : unsorted_property_tys(props)... {}
255268
256- template <typename property_key_t > static constexpr bool has_property () {
257- return std::is_base_of_v<detail::property_key_tag<property_key_t >,
258- properties>;
269+ template <template <auto ...> typename property>
270+ static constexpr bool has_property () {
271+ return std::is_base_of_v<decltype (detail::key<property>()), properties>;
272+ }
273+
274+ template <typename property> static constexpr bool has_property () {
275+ return std::is_base_of_v<decltype (detail::key<property>()), properties>;
276+ }
277+
278+ // First, do return type SFINAE to choose between static/non-static. Second,
279+ // duplicate the code for non-templated properties (until we have "universal
280+ // template" in C++).
281+ template <template <auto ...> typename property>
282+ static constexpr auto get_property () -> std::enable_if_t<
283+ std::is_empty_v<decltype(std::declval<properties>().get_property_impl(
284+ detail::key<property>()))>,
285+ decltype(std::declval<properties>().get_property_impl(
286+ detail::key<property>()))> {
287+ return decltype (std::declval<properties>().get_property_impl (
288+ detail::key<property>())){};
289+ }
290+
291+ template <template <auto ...> typename property>
292+ constexpr auto get_property () const -> std::enable_if_t<
293+ !std::is_empty_v<decltype(std::declval<properties>().get_property_impl(
294+ detail::key<property>()))>,
295+ decltype(std::declval<properties>().get_property_impl(
296+ detail::key<property>()))> {
297+ return get_property_impl (detail::key<property>());
259298 }
260299
261- // Two methods below do the following (pseudocode):
262- //
263- // template <property_key_t>
264- // using ret_t = decltype(this->get_property_impl(key_tag<property_key_t>{}));
265- // static constexpr auto get_property() requires(is_empty_v<ret_t>) {
266- // return ret_t{};
267- // }
268- // constexpr auto get_property() const requires(!is_empty_v<ret_t>) {
269- // return get_property_impl(key_tag<property_key_t>{});
270- // }
271- template <typename property_key_t >
300+ template <typename property>
272301 static constexpr auto get_property () -> std::enable_if_t<
273302 std::is_empty_v<decltype(std::declval<properties>().get_property_impl(
274- detail::key<property_key_t > ))>,
303+ detail::key<property>() ))>,
275304 decltype(std::declval<properties>().get_property_impl(
276- detail::key<property_key_t > ))> {
305+ detail::key<property>() ))> {
277306 return decltype (std::declval<properties>().get_property_impl (
278- detail::key<property_key_t > )){};
307+ detail::key<property>() )){};
279308 }
280309
281- template <typename property_key_t >
310+ template <typename property >
282311 constexpr auto get_property () const -> std::enable_if_t<
283312 !std::is_empty_v<decltype(std::declval<properties>().get_property_impl(
284- detail::key<property_key_t > ))>,
313+ detail::key<property>() ))>,
285314 decltype(std::declval<properties>().get_property_impl(
286- detail::key<property_key_t > ))> {
287- return get_property_impl (detail::key<property_key_t > );
315+ detail::key<property>() ))> {
316+ return get_property_impl (detail::key<property>() );
288317 }
289318
290319 // TODO: Use more effective insert sort for single-property insertion.
@@ -322,6 +351,7 @@ properties(unsorted_property_tys...)
322351
323352using empty_properties_t = decltype (properties{});
324353
354+ // FIXME:
325355template <typename property_list_ty, typename ... allowed_property_keys>
326356struct all_properties_in : std::false_type {};
327357template <typename ... property_tys, typename ... allowed_property_keys>
0 commit comments