DPC++ Runtime
Runtime libraries for oneAPI DPC++
property_list_base.hpp
Go to the documentation of this file.
1 //==------- property_list_base.hpp --- Base for SYCL property lists --------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
11 #include <sycl/detail/pi.h> // for PI_ERROR_INVALID_VALUE
12 #include <sycl/detail/property_helper.hpp> // for DataLessPropKind, Propert...
13 #include <sycl/exception.hpp> // for invalid_object_error
14 
15 #include <algorithm> // for iter_swap
16 #include <bitset> // for bitset
17 #include <memory> // for shared_ptr, __shared_ptr_...
18 #include <type_traits> // for enable_if_t
19 #include <utility> // for move
20 #include <vector> // for vector
21 
22 namespace sycl {
23 inline namespace _V1 {
24 namespace detail {
26 protected:
27  explicit PropertyListBase(
28  std::bitset<DataLessPropKind::DataLessPropKindSize> DataLessProps)
29  : MDataLessProps(DataLessProps) {}
31  std::bitset<DataLessPropKind::DataLessPropKindSize> DataLessProps,
32  std::vector<std::shared_ptr<PropertyWithDataBase>> PropsWithData)
33  : MDataLessProps(DataLessProps),
34  MPropsWithData(std::move(PropsWithData)) {}
35  void ctorHelper() {}
36 
37  template <typename... PropsT, class PropT>
38  typename std::enable_if_t<std::is_base_of_v<DataLessPropertyBase, PropT>>
39  ctorHelper(PropT &, PropsT... Props) {
40  const int PropKind = static_cast<int>(PropT::getKind());
41  MDataLessProps[PropKind] = true;
42  ctorHelper(Props...);
43  }
44 
45  template <typename... PropsT, class PropT>
46  typename std::enable_if_t<std::is_base_of_v<PropertyWithDataBase, PropT>>
47  ctorHelper(PropT &Prop, PropsT... Props) {
48  MPropsWithData.emplace_back(new PropT(Prop));
49  ctorHelper(Props...);
50  }
51 
52  // Compile-time-constant properties are simply skipped
53  template <typename... PropsT, class PropT>
54  typename std::enable_if_t<!std::is_base_of_v<PropertyWithDataBase, PropT> &&
55  !std::is_base_of_v<DataLessPropertyBase, PropT>>
56  ctorHelper(PropT &, PropsT... Props) {
57  ctorHelper(Props...);
58  }
59 
60  template <typename PropT>
61  typename std::enable_if_t<std::is_base_of_v<DataLessPropertyBase, PropT>,
62  bool>
64  const int PropKind = static_cast<int>(PropT::getKind());
66  return false;
67  return MDataLessProps[PropKind];
68  }
69 
70  template <typename PropT>
71  typename std::enable_if_t<std::is_base_of_v<PropertyWithDataBase, PropT>,
72  bool>
74  const int PropKind = static_cast<int>(PropT::getKind());
75  for (const std::shared_ptr<PropertyWithDataBase> &Prop : MPropsWithData)
76  if (Prop->isSame(PropKind))
77  return true;
78  return false;
79  }
80 
81  template <typename PropT>
82  typename std::enable_if_t<std::is_base_of_v<DataLessPropertyBase, PropT>,
83  PropT>
85  // In case of simple property we can just construct it
86  return PropT{};
87  }
88 
89  template <typename PropT>
90  typename std::enable_if_t<std::is_base_of_v<PropertyWithDataBase, PropT>,
91  PropT>
93  const int PropKind = static_cast<int>(PropT::getKind());
95  throw sycl::invalid_object_error("The property is not found",
96  PI_ERROR_INVALID_VALUE);
97 
98  for (const std::shared_ptr<PropertyWithDataBase> &Prop : MPropsWithData)
99  if (Prop->isSame(PropKind))
100  return *static_cast<PropT *>(Prop.get());
101 
102  throw sycl::invalid_object_error("The property is not found",
103  PI_ERROR_INVALID_VALUE);
104  }
105 
107  const std::vector<std::shared_ptr<PropertyWithDataBase>> &PropsWithData) {
108  for (auto &Prop : PropsWithData) {
112  MPropsWithData.push_back(Prop);
113  break;
114  }
115  }
116  }
117 
119  auto It = MPropsWithData.begin();
120  for (; It != MPropsWithData.end(); ++It) {
121  if ((*It)->isSame(Kind))
122  break;
123  }
124  if (It != MPropsWithData.end()) {
125  std::iter_swap(It, MPropsWithData.end() - 1);
126  MPropsWithData.pop_back();
127  }
128  }
129 
130  // Stores enabled/disabled for simple properties
131  std::bitset<DataLessPropKind::DataLessPropKindSize> MDataLessProps;
132  // Stores shared_ptrs to complex properties
133  std::vector<std::shared_ptr<PropertyWithDataBase>> MPropsWithData;
134 };
135 } // namespace detail
136 } // namespace _V1
137 } // namespace sycl
PropertyListBase(std::bitset< DataLessPropKind::DataLessPropKindSize > DataLessProps)
std::enable_if_t< std::is_base_of_v< PropertyWithDataBase, PropT >, PropT > get_property_helper() const
std::enable_if_t< std::is_base_of_v< DataLessPropertyBase, PropT >, PropT > get_property_helper() const
PropertyListBase(std::bitset< DataLessPropKind::DataLessPropKindSize > DataLessProps, std::vector< std::shared_ptr< PropertyWithDataBase >> PropsWithData)
std::enable_if_t< std::is_base_of_v< PropertyWithDataBase, PropT > > ctorHelper(PropT &Prop, PropsT... Props)
std::vector< std::shared_ptr< PropertyWithDataBase > > MPropsWithData
std::enable_if_t<!std::is_base_of_v< PropertyWithDataBase, PropT > &&!std::is_base_of_v< DataLessPropertyBase, PropT > > ctorHelper(PropT &, PropsT... Props)
void delete_accessor_property_helper(const PropWithDataKind &Kind)
std::enable_if_t< std::is_base_of_v< PropertyWithDataBase, PropT >, bool > has_property_helper() const noexcept
std::enable_if_t< std::is_base_of_v< DataLessPropertyBase, PropT >, bool > has_property_helper() const noexcept
std::enable_if_t< std::is_base_of_v< DataLessPropertyBase, PropT > > ctorHelper(PropT &, PropsT... Props)
void add_or_replace_accessor_properties_helper(const std::vector< std::shared_ptr< PropertyWithDataBase >> &PropsWithData)
std::bitset< DataLessPropKind::DataLessPropKindSize > MDataLessProps
Definition: access.hpp:18
_Abi const simd< _Tp, _Abi > & noexcept
Definition: simd.hpp:1324