GLSL Struct 1.4.0
glslstruct
Loading...
Searching...
No Matches
glsl_value.hpp
1/*
2 * glslstruct - a C++ library designed to easily represent GLSL's Uniform Buffer Objects (UBOs) and Shader Storage Buffer Objects (SSBOs) in C++.
3 *
4 * Licensed under the BSD 3-Clause License with Attribution Requirement.
5 * See the LICENSE file for details: https://github.com/MAIPA01/glslstruct/blob/main/LICENSE
6 *
7 * Copyright (c) 2025, Patryk Antosik (MAIPA01)
8 */
9
10#pragma once
11#ifndef _GLSL_STRUCT_GLSL_VALUE_HPP_
12 #define _GLSL_STRUCT_GLSL_VALUE_HPP_
13
14 #include <glslstruct/config.hpp>
15
17_GLSL_STRUCT_ERROR("This is only available for c++17 and greater!");
18 #else
19
20 #include <glslstruct/variable/glsl_variable.hpp>
21
22namespace glslstruct {
23 namespace utils {
24 /**
25 * @brief container for single values
26 * @ingroup utils
27 * @tparam T value type
28 */
29 template<class T>
30 struct single_value {
31 /// @brief value
32 const T value;
33
34 /// @brief default constructor
36 template<class Type = T,
37 std::enable_if_t<std::is_default_constructible_v<Type> && std::is_same_v<Type, T>, bool> = true>
38 #endif
39 single_value() _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<T>) : value() {
40 }
41
42 /// @brief constructor with value
43 explicit single_value(const T& value) : value(value) {}
44 };
45
46 /**
47 * @brief container for array values
48 * @ingroup utils
49 * @tparam T value type
50 * @tparam num array size
51 */
52 template<class T, size_t Num>
53 struct array_value {
54 /// @brief array value
55 const std::array<T, Num> value = {};
56
57 /// @brief static conversion from std::vector to std::array
58 static std::array<T, Num> init_value(const std::vector<T>& values) {
59 std::array<T, Num> temp;
60 std::copy_n(values.begin(), std::min(Num, values.size()), temp.begin());
61 return temp;
62 }
63
64 /// @brief static conversion from pointer and size to std::array
65 static std::array<T, Num> init_value(const T* values, const size_t size) {
66 if (values == nullptr) { return std::array<T, Num>(); }
67
68 std::array<T, Num> temp;
69 std::copy_n(values, std::min(Num, size), temp.begin());
70 return temp;
71 }
72
73 /// @brief static conversion from c-style array to std::array
74 static std::array<T, Num> init_value(const T (&values)[Num]) {
75 std::array<T, Num> temp;
76 std::copy_n(values, Num, temp.begin());
77 return temp;
78 }
79
81 /// @brief static conversion from std::span to std::array
82 static std::array<T, Num> init_value(const std::span<const T> values) {
83 std::array<T, Num> temp;
84 std::copy_n(values.begin(), std::min(Num, values.size()), temp.begin());
85 return temp;
86 }
87 #endif
88
89 /// @brief default constructor
91 template<class Type = T,
92 std::enable_if_t<std::is_default_constructible_v<Type> && std::is_same_v<Type, T>, bool> = true>
93 #endif
94 array_value() _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<T>) : value() {
95 }
96
97 /// @brief constructor with std::vector values
98 explicit array_value(const std::vector<T>& values) : value(init_value(values)) {}
99
100 /// @brief constructor with std::array values
101 explicit array_value(const std::array<T, Num>& values) : value(values) {}
102
103 /// @brief constructor with pointer to values and size
104 explicit array_value(const T* values, const size_t size) : value(init_value(values, size)) {}
105
106 /// @brief constructor with c-style array values
107 explicit array_value(const T (&values)[Num]) : value(init_value(values)) {}
108
110 /// @brief constructor with std::span values
111 explicit array_value(const std::span<const T> values) : value(init_value(values)) {}
112 #endif
113 };
114
115 /**
116 * @brief container for array of structs
117 * @ingroup utils
118 * @tparam T struct type
119 * @tparam num number of arrays
120 */
121 template<class T, size_t Num>
122 struct struct_array_value : public array_value<std::vector<std::byte>, Num> {
123 private:
124 /// @brief value type
125 using value_type = std::vector<std::byte>;
126 /// @brief type of array
127 using array_type = array_value<value_type, Num>;
128 /// @brief layout type
129 using layout_type = _GLSL_STRUCT_TYPENAME17 T::layout_type;
130
131 public:
132 /// @brief layout value
133 const layout_type layout;
134
135 /// @brief constructor with layout
136 explicit struct_array_value(const layout_type& layout) : array_type(), layout(layout) {}
137
138 /// @brief constructor with layout and std::vector values
139 struct_array_value(const layout_type& layout, const std::vector<value_type>& values)
140 : array_type(values), layout(layout) {}
141
142 /// @brief constructor with layout and std::array values
143 struct_array_value(const layout_type& layout, const std::array<value_type, Num>& values)
144 : array_type(values), layout(layout) {}
145
146 /// @brief constructor with layout and pointer to values and size
147 struct_array_value(const layout_type& layout, const value_type* values, size_t size)
148 : array_type(values, size), layout(layout) {}
149
150 /// @brief constructor with layout and c-style array values
151 struct_array_value(const layout_type& layout, const value_type (&values)[Num]) : array_type(values), layout(layout) {}
152
154 /// @brief constructor with layout and std::span values
155 struct_array_value(const layout_type& layout, const std::span<const value_type> values)
156 : array_type(values), layout(layout) {}
157 #endif
158 };
159 } // namespace utils
160
161 /**
162 * @brief container for values for easier initialization of structs
163 * @ingroup glslstruct
164 * @tparam T value type
165 * @tparam num number of elements in array (default is 0. if it is 0 then it is not array but a single value)
166 */
168 template<utils::glsl_simple_or_struct T, size_t Num>
169 #else
170 template<class T, size_t Num, std::enable_if_t<utils::is_glsl_simple_or_struct_v<T>, bool> >
171 #endif
172 struct glsl_value
173 : public std::conditional_t<mstd::is_eq_v<Num, 0>, utils::single_value<T>,
174 std::conditional_t<utils::is_glsl_simple_v<T>, utils::array_value<T, Num>, utils::struct_array_value<T, Num> > > {
175 private:
176 /// @brief base struct type
177 using base_struct = std::conditional_t<mstd::is_eq_v<Num, 0>, utils::single_value<T>,
178 std::conditional_t<utils::is_glsl_simple_v<T>, utils::array_value<T, Num>, utils::struct_array_value<T, Num> > >;
179
180 public:
181 /// @brief value type
182 using value_type = T;
183 /// @brief array size
184 static _GLSL_STRUCT_CONSTEXPR17 size_t array_size = Num;
185 /// @brief value indicating if value is array or single
186 static _GLSL_STRUCT_CONSTEXPR17 bool is_array = array_size > 0;
187 /// @brief value indicating if value_type is struct
188 static _GLSL_STRUCT_CONSTEXPR17 bool is_struct = utils::is_glsl_struct_v<value_type>;
189
190 #pragma region VARIABLES
191 /// @brief variable name
192 const std::string varName;
193 #pragma endregion
194
195 #pragma region DEFAULT_CONSTRUCTOR
196 /// @brief default constructor with variable name
198 template<class Type = value_type,
199 std::enable_if_t<(utils::is_glsl_simple_v<Type> && std::is_default_constructible_v<base_struct> &&
200 std::is_same_v<Type, value_type>),
201 bool> = true>
202 #endif
203 explicit glsl_value(const std::string_view name) _GLSL_STRUCT_REQUIRES(utils::is_glsl_simple_v<value_type>)
204 : base_struct(), varName(name) {
205 }
206
207 #pragma endregion
208
209 #pragma region SINGLE_VALUE_CONSTRUCTOR
210 /// @brief constructor with value of value_type type
212 template<class Type = value_type,
213 std::enable_if_t<(utils::is_glsl_simple_or_struct_v<Type> && std::is_same_v<Type, value_type> && !is_array), bool> =
214 true>
215 #endif
216 glsl_value(const std::string_view name,
217 const value_type& value) _GLSL_STRUCT_REQUIRES(utils::is_glsl_simple_or_struct_v<value_type> && !is_array)
218 : base_struct(value), varName(name) {
219 }
220
221 #pragma endregion
222
223 #pragma region ARRAY_CONSTRUCTORS
224 /// @brief constructor for array values with pointer to values and size
226 template<class Type = value_type,
227 std::enable_if_t<(utils::is_glsl_simple_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
228 #endif
229 glsl_value(const std::string_view name, const value_type* values,
230 const size_t size) _GLSL_STRUCT_REQUIRES(utils::is_glsl_simple_v<value_type>&& is_array)
231 : base_struct(values, size), varName(name) {
232 }
233
234 /// @brief constructor for array values with std::vector
236 template<class Type = value_type,
237 std::enable_if_t<(utils::is_glsl_simple_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
238 #endif
239 glsl_value(const std::string_view name,
240 const std::vector<value_type>& values) _GLSL_STRUCT_REQUIRES(utils::is_glsl_simple_v<value_type>&& is_array)
241 : base_struct(values), varName(name) {
242 }
243
244 /// @brief constructor for array values with std::array
246 template<class Type = value_type,
247 std::enable_if_t<(utils::is_glsl_simple_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
248 #endif
249 glsl_value(const std::string_view name,
250 const std::array<value_type, array_size>& values) _GLSL_STRUCT_REQUIRES(utils::is_glsl_simple_v<value_type>&& is_array)
251 : base_struct(values), varName(name) {
252 }
253
254 /// @brief constructor for array values with c-style array
256 template<class Type = value_type,
257 std::enable_if_t<(utils::is_glsl_simple_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
258 #endif
259 glsl_value(const std::string_view name,
260 const value_type (&values)[array_size]) _GLSL_STRUCT_REQUIRES(utils::is_glsl_simple_v<value_type>&& is_array)
261 : base_struct(values), varName(name) {
262 }
263
265 /// @brief constructor for array values with std::span
266 glsl_value(const std::string_view name,
267 const std::span<const value_type> values) _GLSL_STRUCT_REQUIRES(utils::is_glsl_simple_v<value_type>&& is_array)
268 : base_struct(values), varName(name) {}
269 #endif
270
271 #pragma endregion
272
273 #pragma region STRUCT_ARRAY_CONSTRUCTORS
274 /// @brief constructor for struct array values
276 template<utils::glsl_struct Type = value_type>
277 #else
278 template<class Type = value_type,
279 std::enable_if_t<(utils::is_glsl_struct_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
280 #endif
281 glsl_value(const std::string_view name, const _GLSL_STRUCT_TYPENAME17 Type::layout_type& layout) _GLSL_STRUCT_REQUIRES(
282 (utils::is_glsl_struct_v<value_type> && std::is_same_v<Type, value_type> && is_array)
283 )
284 : base_struct(layout), varName(name) {
285 }
286
287 /// @brief constructor for array values with std::vector
289 template<utils::glsl_struct Type = value_type>
290 #else
291 template<class Type = value_type,
292 std::enable_if_t<(utils::is_glsl_struct_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
293 #endif
294 glsl_value(
295 const std::string_view name, const _GLSL_STRUCT_TYPENAME17 Type::layout_type& layout,
296 const std::vector<std::vector<std::byte> >& values
297 ) _GLSL_STRUCT_REQUIRES((utils::is_glsl_struct_v<value_type> && std::is_same_v<Type, value_type> && is_array))
298 : base_struct(layout, values), varName(name) {
299 }
300
301 /// @brief constructor for array values with std::array
303 template<utils::glsl_struct Type = value_type>
304 #else
305 template<class Type = value_type,
306 std::enable_if_t<(utils::is_glsl_struct_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
307 #endif
308 glsl_value(
309 const std::string_view name, const _GLSL_STRUCT_TYPENAME17 Type::layout_type& layout,
310 const std::array<std::vector<std::byte>, array_size>& values
311 ) _GLSL_STRUCT_REQUIRES((utils::is_glsl_struct_v<value_type> && std::is_same_v<Type, value_type> && is_array))
312 : base_struct(layout, values), varName(name) {
313 }
314
315 /// @brief constructor for array values with pointer to values and size
317 template<utils::glsl_struct Type = value_type>
318 #else
319 template<class Type = value_type,
320 std::enable_if_t<(utils::is_glsl_struct_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
321 #endif
322 glsl_value(
323 const std::string_view name, const _GLSL_STRUCT_TYPENAME17 Type::layout_type& layout,
324 const std::vector<std::byte>* values, const size_t size
325 ) _GLSL_STRUCT_REQUIRES((utils::is_glsl_struct_v<value_type> && std::is_same_v<Type, value_type> && is_array))
326 : base_struct(layout, values, size), varName(name) {
327 }
328
329 /// @brief constructor for array values with c-style array values
331 template<utils::glsl_struct Type = value_type>
332 #else
333 template<class Type = value_type,
334 std::enable_if_t<(utils::is_glsl_struct_v<Type> && std::is_same_v<Type, value_type> && is_array), bool> = true>
335 #endif
336 glsl_value(const std::string_view name, const _GLSL_STRUCT_TYPENAME17 Type::layout_type& layout,
337 const std::vector<std::byte> (&values)[Num]) _GLSL_STRUCT_REQUIRES((utils::is_glsl_struct_v<value_type> &&
338 std::is_same_v<Type, value_type> && is_array))
339 : base_struct(layout, values), varName(name) {
340 }
341
343 /// @brief constructor for array values with std::span
344 template<utils::glsl_struct Type = value_type>
345 glsl_value(
346 const std::string_view name, const _GLSL_STRUCT_TYPENAME17 Type::layout_type& layout,
347 const std::span<const std::vector<std::byte> > values
348 ) _GLSL_STRUCT_REQUIRES((utils::is_glsl_struct_v<value_type> && std::is_same_v<Type, value_type> && is_array))
349 : base_struct(layout, values), varName(name) {}
350 #endif
351
352 #pragma endregion
353 };
354} // namespace glslstruct
355
356 #endif
357#endif
#define _GLSL_STRUCT_TYPENAME17
Definition config.hpp:216
#define _GLSL_STRUCT_HAS_CXX20
check if compiler has c++ version greater or equal to c++20 and if user enabled c++20 features using ...
Definition config.hpp:142
#define _GLSL_STRUCT_HAS_CXX17
check if compiler has c++ version greater or equal to c++17
Definition config.hpp:130
#define _GLSL_STRUCT_REQUIRES(condition)
requires keyword for c++20 and higher
Definition config.hpp:214
#define _GLSL_STRUCT_CONSTEXPR17
constexpr for c++17 and higher
Definition config.hpp:196