clover: Switch platform objects to the new model.
[mesa.git] / src / gallium / state_trackers / clover / core / property.hpp
1 //
2 // Copyright 2013 Francisco Jerez
3 //
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:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
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.
21 //
22
23 #ifndef CLOVER_CORE_PROPERTY_HPP
24 #define CLOVER_CORE_PROPERTY_HPP
25
26 #include <map>
27
28 #include "util/range.hpp"
29 #include "util/algorithm.hpp"
30
31 namespace clover {
32 class property_buffer;
33
34 namespace detail {
35 template<typename T>
36 class property_scalar {
37 public:
38 property_scalar(property_buffer &buf) : buf(buf) {
39 }
40
41 inline property_scalar &
42 operator=(const T &x);
43
44 private:
45 property_buffer &buf;
46 };
47
48 template<typename T>
49 class property_vector {
50 public:
51 property_vector(property_buffer &buf) : buf(buf) {
52 }
53
54 template<typename S>
55 inline property_vector &
56 operator=(const S &v);
57
58 private:
59 property_buffer &buf;
60 };
61
62 template<typename T>
63 class property_matrix {
64 public:
65 property_matrix(property_buffer &buf) : buf(buf) {
66 }
67
68 template<typename S>
69 inline property_matrix &
70 operator=(const S &v);
71
72 private:
73 property_buffer &buf;
74 };
75
76 class property_string {
77 public:
78 property_string(property_buffer &buf) : buf(buf) {
79 }
80
81 inline property_string &
82 operator=(const std::string &v);
83
84 private:
85 property_buffer &buf;
86 };
87 };
88
89 ///
90 /// Return value buffer used by the CL property query functions.
91 ///
92 class property_buffer {
93 public:
94 property_buffer(void *r_buf, size_t size, size_t *r_size) :
95 r_buf(r_buf), size(size), r_size(r_size) {
96 }
97
98 template<typename T>
99 detail::property_scalar<T>
100 as_scalar() {
101 return { *this };
102 }
103
104 template<typename T>
105 detail::property_vector<T>
106 as_vector() {
107 return { *this };
108 }
109
110 template<typename T>
111 detail::property_matrix<T>
112 as_matrix() {
113 return { *this };
114 }
115
116 detail::property_string
117 as_string() {
118 return { *this };
119 }
120
121 template<typename T>
122 iterator_range<T *>
123 allocate(size_t n) {
124 if (r_buf && size < n * sizeof(T))
125 throw error(CL_INVALID_VALUE);
126
127 if (r_size)
128 *r_size = n * sizeof(T);
129
130 if (r_buf)
131 return range((T *)r_buf, n);
132 else
133 return { };
134 }
135
136 private:
137 void *const r_buf;
138 const size_t size;
139 size_t *const r_size;
140 };
141
142 namespace detail {
143 template<typename T>
144 inline property_scalar<T> &
145 property_scalar<T>::operator=(const T &x) {
146 auto r = buf.allocate<T>(1);
147
148 if (!r.empty())
149 r.front() = x;
150
151 return *this;
152 }
153
154 template<typename T>
155 template<typename S>
156 inline property_vector<T> &
157 property_vector<T>::operator=(const S &v) {
158 auto r = buf.allocate<T>(v.size());
159
160 if (!r.empty())
161 copy(v, r.begin());
162
163 return *this;
164 }
165
166 template<typename T>
167 template<typename S>
168 inline property_matrix<T> &
169 property_matrix<T>::operator=(const S &v) {
170 auto r = buf.allocate<T *>(v.size());
171
172 if (!r.empty())
173 for_each([](typename S::value_type src, T *dst) {
174 if (dst)
175 copy(src, dst);
176 }, v, r);
177
178 return *this;
179 }
180
181 inline property_string &
182 property_string::operator=(const std::string &v) {
183 auto r = buf.allocate<char>(v.size() + 1);
184
185 if (!r.empty())
186 copy(range(v.begin(), r.size()), r.begin());
187
188 return *this;
189 }
190 };
191 }
192
193 #endif