GLSL Struct 1.4.0
glslstruct
Loading...
Searching...
No Matches
base_parser.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_PARSER_HPP_
12 #define _GLSL_STRUCT_PARSER_HPP_
13
14 #include <glslstruct/config.hpp>
15
17_GLSL_STRUCT_ERROR("This is only available for c++17 and greater and when parser functionality is not disabled!");
18 #else
19
20 #include <glslstruct/struct/base_struct.hpp>
21
22namespace glslstruct {
23
24 namespace utils {
25 #pragma region BASE_PARSER_PATTERNS
26
27 /**
28 * @ingroup utils
29 * @brief all parser patterns in one struct
30 */
32 /// @brief pattern to get scalar data
33 static inline const auto scalarsPattern = pcre2cpp::regex(R"(^\s*+(?<scalar>(?>bool|double|float|u?int))\s*+$)");
34
35 /// @brief pattern to get vec data
36 static inline const auto vecPattern = pcre2cpp::regex(R"(^\s*+(?>(?<scalar>[idbuf])?vec(?<length>[2-4]))\s*+$)");
37
38 /// @brief pattern to get mat data
39 static inline const auto matPattern =
40 pcre2cpp::regex(R"(^\s*+(?>(?<scalar>[idbuf])?mat(?<cols>[2-4])(?>(?:x(?<rows>[2-4]))?))\s*+$)");
41
42 /// @brief pattern to get variable data
43 static inline const auto variablePattern = pcre2cpp::regex(
44 R"(^\s*+(?>(?<type>[a-zA-Z_]\w*+))\s++(?>(?<name>[a-zA-Z_]\w*+))\s*+(?>(?<array>\‍[\s*+(?<count>\d+)?\s*+\‍]))?\s*+(?>;?)\s*+$)"
45 );
46
47 /// @brief pattern to get multiple variables
48 static inline const auto multiVariablesPattern = pcre2cpp::regex(
49 R"((?>(?<=^|;))\s*+(?<var>[a-zA-Z_]\w*+\s++[a-zA-Z_]\w*+(?>(?:\s*+\‍[\s*+\d*+\s*+\‍])*+))\s*+(?:;|$))",
51 );
52
53 /// @brief pattern to get struct data
54 static inline const auto structPattern =
55 pcre2cpp::regex(R"(^\s*+(?>(?>struct)\s++(?>(?<name>[a-zA-Z_]\w*+))\s*+(?>\{(?<body>[^}]*+)\})\s*+;)\s*+$)");
56
57 /// @brief pattern to get multiple structs
58 static inline const auto multiStructsPattern = pcre2cpp::regex(
59 R"(\s*+(?<struct>(?>struct|layout\s*+\‍([^)]*+\‍)\s*+(?>uniform|(?:\w++\s++)?buffer))\s++(?>(?:[a-zA-Z_]\w*+))\s*+\{(?>[^}]*+)\}\s*+(?>(?:\w*+\s*+));\s*+))",
61 );
62 };
63
64 #pragma endregion
65
66 #pragma region UBO_PARSER_PATTERN
67 /**
68 * @ingroup utils
69 * @brief container for ubo parser pattern
70 */
72 template<glsl_layout Layout>
73 #else
74 template<class Layout, std::enable_if_t<is_glsl_layout_v<Layout>, bool> = true>
75 #endif
77 };
78
79 /**
80 * @ingroup utils
81 * @brief template overload of container for ubo parser pattern for std140 layout
82 */
83 template<>
85 /// @brief pattern for std140 ubo
86 static inline const auto pattern = pcre2cpp::regex(
87 R"(^\s*+layout\s*+\‍((?>(?:(?:std140|set\s*+=\s*+\d++)\s*+,\s*+)?)\s*+binding\s*+=\s*+\d++\s*+\‍)\s*+uniform\s*+(?<name>[a-zA-Z_]\w*+)\s*+\{(?<body>[^}]*+)\}\s*+(?>(?:[a-zA-Z_]\w*+)?)\s*+;\s*+$)"
88 );
89 };
90
92 /**
93 * @ingroup utils
94 * @brief concept for check if layout can be used as ubo
95 */
96 template<class Layout>
100
101 /**
102 * @ingroup utils
103 * @brief returns true if layout can be used as ubo
104 */
105 template<class Layout>
107
108 #else
109 /**
110 * @ingroup utils
111 * @brief struct checking if layout can be used as ubo
112 */
113 template<class Layout, class = void>
114 struct has_ubo_pattern : std::false_type {};
115
116 template<class Layout>
117 struct has_ubo_pattern<Layout,
119 : std::true_type {};
120
121 /**
122 * @ingroup utils
123 * @brief returns true if layout can be used as ubo
124 */
125 template<class Layout>
126 static _GLSL_STRUCT_CONSTEXPR17 bool has_ubo_pattern_v = has_ubo_pattern<Layout>::value;
127 #endif
128 #pragma endregion
129
130 #pragma region SSBO_PARSER_PATTERN
131 /**
132 * @ingroup utils
133 * @brief container for ssbo parser pattern
134 */
136 template<glsl_layout Layout>
137 #else
138 template<class Layout, std::enable_if_t<is_glsl_layout_v<Layout>, bool> = true>
139 #endif
141 };
142
143 /**
144 * @ingroup utils
145 * @brief template overload of container for ssbo parser pattern for std140 layout
146 */
147 template<>
149 static inline const auto pattern = pcre2cpp::regex(
150 R"(^\s*+layout\s*+\‍((?>std140(?>\s*+,\s*+set\s*+=\s*+\d++)?)\s*+,\s*+binding\s*+=\s*+\d++\s*+\‍)\s*+(?>(?:[a-zA-Z]++\s++)?buffer)\s++(?<name>[a-zA-Z_]\w*+)\s*+\{(?<body>[^}]*+)\}\s*+(?>(?:[a-zA-Z_]\w*+)?)\s*+;\s*+$)"
151 );
152 };
153
154 /**
155 * @ingroup utils
156 * @brief template overload of container for ssbo parser pattern for std430 layout
157 */
158 template<>
160 static inline const auto pattern = pcre2cpp::regex(
161 R"(^\s*+layout\s*+\‍((?>std430(?>\s*+,\s*+set\s*+=\s*+\d++)?)\s*+,\s*+binding\s*+=\s*+\d++\s*+\‍)\s*+(?>(?:[a-zA-Z]++\s++)?buffer)\s++(?<name>[a-zA-Z_]\w*+)\s*+\{(?<body>[^}]*+)\}\s*+(?>(?:[a-zA-Z_]\w*+)?)\s*+;\s*+$)"
162 );
163 };
164
165 /**
166 * @ingroup utils
167 * @brief template overload of container for ssbo parser pattern for scalar layout
168 */
169 template<>
171 static inline const auto pattern = pcre2cpp::regex(
172 R"(^\s*+layout\s*+\‍((?>scalar(?>\s*+,\s*+set\s*+=\s*+\d++)?)\s*+,\s*+binding\s*+=\s*+\d++\s*+\‍)\s*+(?>(?:[a-zA-Z]++\s++)?buffer)\s++(?<name>[a-zA-Z_]\w*+)\s*+\{(?<body>[^}]*+)\}\s*+(?>(?:[a-zA-Z_]\w*+)?)\s*+;\s*+$)"
173 );
174 };
175
177 /**
178 * @ingroup utils
179 * @brief concept for check if layout can be used as ssbo
180 */
181 template<class Layout>
185
186 /**
187 * @ingroup utils
188 * @brief returns true if layout can be used as ssbo
189 */
190 template<class Layout>
192
193 #else
194 /**
195 * @ingroup utils
196 * @brief struct checking if layout can be used as ssbo
197 */
198 template<class Layout, class = void>
199 struct has_ssbo_pattern : std::false_type {};
200
201 template<class Layout>
202 struct has_ssbo_pattern<
203 Layout,
205 > : std::true_type {};
206
207 /**
208 * @ingroup utils
209 * @brief returns true if layout can be used as ssbo
210 */
211 template<class Layout>
212 static _GLSL_STRUCT_CONSTEXPR17 bool has_ssbo_pattern_v = has_ssbo_pattern<Layout>::value;
213 #endif
214 #pragma endregion
215 } // namespace utils
216
217 /**
218 * @ingroup glslstruct
219 * @brief base template class of structs parser
220 * @tparam Layout layout type for parser
221 */
223 template<utils::glsl_layout Layout>
224 #else
225 template<class Layout, std::enable_if_t<utils::is_glsl_layout_v<Layout>, bool> = true>
226 #endif
228 private:
229 /// @brief layout type
231 /// @brief structure type
233
237
238 /// @brief returns true if given layout can be used by ubo
240 /// @brief returns true if given layout can be used by ssbo
242
243 /// @brief loaded and not converted to layouts structs bodies
245 /// @brief loaded and converted to layouts structs
247
248 #pragma region GENERAL_VARIABLE_FUNCTIONS
249
250 /// @brief returns ValueType based on type in string
252 // Option for vec and mat
253 if (type.empty() || type[0] == 'f') { return ValueType::Float; }
254
255 if (type[0] == 'i') { return ValueType::Int; }
256
257 if (type[0] == 'u') { return ValueType::Uint; }
258
259 if (type[0] == 'd') { return ValueType::Double; }
260
261 if (type[0] == 'b') { return ValueType::Bool; }
262
263 [[unlikely]] return ValueType::Int;
264 }
265
266 /// @brief adds variable of type T to struct or layout (if count != 0 then it adds array of variables of type T)
267 template<class T, class S>
270 if (count != 0) { ref.template add<std::vector<T> >(name, count); }
271 else { ref.template add<T>(name); }
272 }
273 return ref;
274 }
275
276 #pragma endregion
277
278 #pragma region SCALAR_VARIABLE
279
280 /// @brief adds scalar with name and of type based on ValueType to struct or layout
281 template<class S>
283 const size_t count) {
284 switch (type) {
285 case ValueType::Bool: return _add_variable<bool>(ref, name, count);
286 default:
287 case ValueType::Int: return _add_variable<int>(ref, name, count);
288 case ValueType::Uint: return _add_variable<unsigned int>(ref, name, count);
289 case ValueType::Float: return _add_variable<float>(ref, name, count);
290 case ValueType::Double: return _add_variable<double>(ref, name, count);
291 }
292 }
293
294 #pragma endregion
295
296 #pragma region VEC_VARIABLE
297
298 /// @brief adds vec with name and with provided length to struct or layout
299 template<class T, class S>
301 const size_t count) {
302 switch (length) {
303 default:
304 case 2: return _add_variable<glm::vec<2, T> >(ref, name, count);
305 case 3: return _add_variable<glm::vec<3, T> >(ref, name, count);
306 case 4: return _add_variable<glm::vec<4, T> >(ref, name, count);
307 }
308 }
309
310 /// @brief adds vec with name and of type based on ValueType and with provided length to struct or layout
311 template<class S>
313 const std::string_view name, const size_t count) {
314 switch (type) {
315 case ValueType::Bool: return _add_vec_variable<bool>(ref, length, name, count);
316 default:
317 case ValueType::Int: return _add_vec_variable<int>(ref, length, name, count);
318 case ValueType::Uint: return _add_vec_variable<unsigned int>(ref, length, name, count);
319 case ValueType::Float: return _add_vec_variable<float>(ref, length, name, count);
320 case ValueType::Double: return _add_vec_variable<double>(ref, length, name, count);
321 }
322 }
323
324 #pragma endregion
325
326 #pragma region MAT_VARIABLE
327
328 /// @brief adds mat with name and with provided rows to struct or layout
329 template<class T, size_t Cols, class S>
331 const size_t count) {
332 switch (rows) {
333 default:
334 case 2: return _add_variable<glm::mat<Cols, 2, T> >(ref, name, count);
335 case 3: return _add_variable<glm::mat<Cols, 3, T> >(ref, name, count);
336 case 4: return _add_variable<glm::mat<Cols, 4, T> >(ref, name, count);
337 }
338 }
339
340 /// @brief adds mat with name and with provided columns and rows to struct or layout
341 template<class T, class S>
343 const std::string_view name, const size_t count) {
344 switch (cols) {
345 default:
346 case 2: return _add_mat_variable<T, 2>(ref, rows, name, count);
347 case 3: return _add_mat_variable<T, 3>(ref, rows, name, count);
348 case 4: return _add_mat_variable<T, 3>(ref, rows, name, count);
349 }
350 }
351
352 /// @brief adds mat with name and of type based on ValueType and with provided columns and rows to struct or layout
353 template<class S>
355 const std::string_view name, const size_t count) {
356 switch (type) {
357 case ValueType::Bool: return _add_mat_variable<bool>(ref, cols, rows, name, count);
358 default:
359 case ValueType::Int: return _add_mat_variable<int>(ref, cols, rows, name, count);
360 case ValueType::Uint: return _add_mat_variable<unsigned int>(ref, cols, rows, name, count);
361 case ValueType::Float: return _add_mat_variable<float>(ref, cols, rows, name, count);
362 case ValueType::Double: return _add_mat_variable<double>(ref, cols, rows, name, count);
363 }
364 }
365
366 #pragma endregion
367
368 #pragma region EXTRACT_STRUCTS
369
370 /// @brief extracts name and body of structure from string
392
393 /// @brief extracts struct strings from structs list
397 glsl_struct_assert(false, "Provided structs string '{}' didn't have any struct definition", structsStr);
398 return {};
399 }
400
403 for (const auto& result : results) { structs.push_back(result.get_sub_result_value("struct")); }
404 return structs;
405 }
406
407 #pragma endregion
408
409 #pragma region LAYOUT
410
411 /// @brief creates layout with variables in vars list
416
417 /// @brief loads layout from structsBodies to structsLayouts and returns if there is a layout with given name in structsLayouts
426
427 #pragma endregion
428
429 #pragma region CONTAINS
430
431 /// @brief returns true if struct with given name is in _structsBodies
439
440 /// @brief returns true if struct with given name is in _structsLayouts
448
449 #pragma endregion
450
451 #pragma region PARSE_AND_ADD_VARIABLES
452
453 /// @brief adds variable of type given in string and with name and count
454 template<class S>
456 const size_t count = 0) {
458
459 // Check if scalar type
462 count);
463 }
464
465 // Check if vec type
469
471 name, count);
472 }
473
474 // Check if mat type
477
478 size_t cols;
480
481 if (!result.has_sub_value("rows")) { return _add_mat_variable(ref, valueType, cols, cols, name, count); }
482
483 size_t rows;
485
487 }
488
489 // Check if struct type
490 if (_load_layout(type.data())) {
492 return ref;
493 }
494
495 glsl_struct_assert(false, "Provided type str '{}' was not a correct variable type", type);
496 return ref;
497 }
498
499 /// @brief adds variable given in string
500 template<class S>
504 glsl_struct_assert(false, "Provided var str '{}' was not a correct variable", varStr);
505 return ref;
506 }
507
508 size_t count = 0;
509 if (result.has_sub_value("count")) { mstd::strtounum(result.get_sub_result_value("count"), count); }
510 else if (result.has_sub_value("array")) { count = 1; }
511
513 }
514
515 /// @brief adds variables given in var list string
516 template<class S>
520 glsl_struct_assert(false, "Provided vars str '{}' was not a correct variables list", varsStr);
521 return ref;
522 }
523
524 for (const auto& result : results) { _add_variable(ref, result.get_sub_result_value("var")); }
525
526 return ref;
527 }
528
529 #pragma endregion
530
531 public:
532 /// @brief default constructor
534
535 #pragma region VARIABLE_PARSER
536
537 /// @brief adds variable array to layout
542
543 /// @brief adds variable array to struct
548
549 /// @brief adds variable to layout
554
555 /// @brief adds variable to struct
560
561 /// @brief adds variable to layout
565
566 /// @brief adds variable to struct
570
571 /// @brief adds variables to layout
575
576 /// @brief adds variables to struct
580
581 #pragma endregion
582
583 #pragma region STRUCTS_PARSER
584
585 /// @brief adds struct definition
589
590 /// @brief adds struct definition
595
596 /// @brief adds structs definitions
600
601 /// @brief creates layout with given variables
606
607 /// @brief creates struct with given variables
611
612 /// @brief get layout of struct earlier defined
614 if (!_load_layout(structName)) {
615 glsl_struct_assert(false, "Couldn't find definition for struct with name '{}'", structName);
616 return {};
617 }
618
620 }
621
622 /// @brief get struct earlier defined
626
627 /// @brief creates layouts from strings array
637
638 /// @brief creates layouts from string
642
643 /// @brief creates structs from strings array
653
654 /// @brief creates structs from string
658
659 /// @brief gets layouts with names in array
668
669 /// @brief gets structs with names in array
678
679 #pragma endregion
680 };
681
682 /**
683 * @ingroup glslstruct
684 * @brief parser for std140 layout
685 */
687 /**
688 * @ingroup glslstruct
689 * @brief parser for std430 layout
690 */
692 /**
693 * @ingroup glslstruct
694 * @brief parser for scalar layout
695 */
697
698} // namespace glslstruct
699
700 #endif
701#endif
#define _GLSL_STRUCT_HAS_PARSER
check if user want to include parser functionality
Definition config.hpp:186
#define _GLSL_STRUCT_CONSTEXPR20
constexpr keyword for c++20 and higher
Definition config.hpp:213
#define glsl_struct_assert(expression,...)
glslstruct assert
Definition assert.hpp:33
#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_CONSTEXPR17
constexpr for c++17 and higher
Definition config.hpp:196
Definition writer.hpp:25
Main namespace of glslstruct library.
Definition scalar_layout_traits.hpp:23
all parser patterns in one struct
Definition base_parser.hpp:31
static const auto structPattern
pattern to get struct data
Definition base_parser.hpp:54
static const auto vecPattern
pattern to get vec data
Definition base_parser.hpp:36
static const auto multiStructsPattern
pattern to get multiple structs
Definition base_parser.hpp:58
static const auto matPattern
pattern to get mat data
Definition base_parser.hpp:39
static const auto scalarsPattern
pattern to get scalar data
Definition base_parser.hpp:33
static const auto variablePattern
pattern to get variable data
Definition base_parser.hpp:43
static const auto multiVariablesPattern
pattern to get multiple variables
Definition base_parser.hpp:48
container for ssbo parser pattern
Definition base_parser.hpp:140
container for ubo parser pattern
Definition base_parser.hpp:76