2 // Copyright 2013 Francisco Jerez
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
23 #ifndef CLOVER_CORE_PROPERTY_HPP
24 #define CLOVER_CORE_PROPERTY_HPP
28 #include "util/range.hpp"
29 #include "util/algorithm.hpp"
32 class property_buffer;
36 class property_scalar {
38 property_scalar(property_buffer &buf) : buf(buf) {
41 inline property_scalar &
42 operator=(const T &x);
49 class property_vector {
51 property_vector(property_buffer &buf) : buf(buf) {
55 inline property_vector &
56 operator=(const S &v);
63 class property_matrix {
65 property_matrix(property_buffer &buf) : buf(buf) {
69 inline property_matrix &
70 operator=(const S &v);
76 class property_string {
78 property_string(property_buffer &buf) : buf(buf) {
81 inline property_string &
82 operator=(const std::string &v);
90 /// Return value buffer used by the CL property query functions.
92 class property_buffer {
94 property_buffer(void *r_buf, size_t size, size_t *r_size) :
95 r_buf(r_buf), size(size), r_size(r_size) {
99 detail::property_scalar<T>
105 detail::property_vector<T>
111 detail::property_matrix<T>
116 detail::property_string
124 if (r_buf && size < n * sizeof(T))
125 throw error(CL_INVALID_VALUE);
128 *r_size = n * sizeof(T);
131 return range((T *)r_buf, n);
139 size_t *const r_size;
144 inline property_scalar<T> &
145 property_scalar<T>::operator=(const T &x) {
146 auto r = buf.allocate<T>(1);
156 inline property_vector<T> &
157 property_vector<T>::operator=(const S &v) {
158 auto r = buf.allocate<T>(v.size());
168 inline property_matrix<T> &
169 property_matrix<T>::operator=(const S &v) {
170 auto r = buf.allocate<T *>(v.size());
173 for_each([](typename S::value_type src, T *dst) {
181 inline property_string &
182 property_string::operator=(const std::string &v) {
183 auto r = buf.allocate<char>(v.size() + 1);
186 copy(range(v.begin(), r.size()), r.begin());
193 class property_element {
195 property_element() : x() {
198 property_element(T x) : x(x) {
204 assert(sizeof(S) <= sizeof(T));
205 return reinterpret_cast<S>(x);
213 using property_list = std::map<D, property_element<D>>;
215 struct property_list_tag;
218 /// Create a clover::property_list object from a zero-terminated
219 /// CL property list.
221 template<typename T, typename D,
222 typename = typename std::enable_if<
223 std::is_same<T, property_list_tag>::value>::type>
225 obj(const D *d_props) {
226 property_list<D> props;
228 while (d_props && *d_props) {
229 auto key = *d_props++;
230 auto value = *d_props++;
232 if (props.count(key))
233 throw error(CL_INVALID_PROPERTY);
235 props.insert({ key, value });
242 /// Create a zero-terminated CL property list from a
243 /// clover::property_list object.
247 desc(const property_list<D> &props) {
248 std::vector<D> d_props;
250 for (auto &prop : props) {
251 d_props.push_back(prop.first);
252 d_props.push_back(prop.second.template as<D>());
255 d_props.push_back(0);