GLSL Struct 1.4.0
glslstruct
Loading...
Searching...
No Matches
base_layout.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_BASE_LAYOUT_HPP_
12 #define _GLSL_STRUCT_BASE_LAYOUT_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/types.hpp>
21
22 #include <glslstruct/layout/traits/layout_traits_concept.hpp>
24 #include <glslstruct/type/containers/array_type.hpp>
25 #include <glslstruct/type/containers/mat_type.hpp>
26 #include <glslstruct/type/containers/scalar_type.hpp>
27 #include <glslstruct/type/containers/struct_type.hpp>
28 #include <glslstruct/type/containers/vec_type.hpp>
29 #include <glslstruct/type/visitors/is_of_type_visitor.hpp>
30 #endif
31 #include <glslstruct/utils/assert.hpp>
32 #include <glslstruct/utils/functions.hpp>
33 #include <glslstruct/utils/ValueType.hpp>
34 #include <glslstruct/var_data/var_data.hpp>
35 #include <glslstruct/variable/glsl_variable.hpp>
36
37namespace glslstruct {
38 namespace utils {
39 /**
40 * @brief Context container for layout
41 * @ingroup utils
42 * @tparam Traits layout traits type
43 */
44 template<class Traits>
46 /// @brief context type
48
49 protected:
50 /// @brief context value
52
53 public:
54 /// @brief default constructor
56 template<class C = context_type,
57 std::enable_if_t<std::is_default_constructible_v<context_type> && std::is_same_v<C, context_type>, bool> = true>
58 #endif
60 std::is_default_constructible_v<context_type>
61 )
62 : _context() {
63 }
64
65 /// @brief constructor with context value
67 };
68
69 /**
70 * @brief empty container for layout
71 * @ingroup utils
72 */
74 } // namespace utils
75
76 /**
77 * @brief base layout container
78 * @ingroup glslstruct
79 * @tparam Traits layout traits type
80 */
82 template<layout_traits Traits>
83 #else
84 template<class Traits, std::enable_if_t<is_layout_traits_v<Traits>, bool> >
85 #endif
88 public:
89 /// @brief traits type
90 using traits_type = Traits;
91
92 /// @brief value indicating if traits has context defined
93 static _GLSL_STRUCT_CONSTEXPR17 bool has_context = utils::has_layout_traits_context_v<traits_type>;
94
95 private:
96 friend struct std::hash<base_layout>;
97
98 /// @brief base layout struct
101
102 /// @brief variables data
104 /// @brief current offset
105 size_t _currentOffset = 0;
106
107 #pragma region VARIABLE_SET
108
109 /// @brief sets variable data
112 const base_type_handle& type,
113 #else
114 const size_t size,
115 #endif
116 const bool isTopLevel, const size_t padding = 0) {
119 type,
120 #else
121 size,
122 #endif
124 }
125
126 #pragma endregion
127
128 /// @brief calculates alignment offset
129 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t _calculate_alignment_offset(const size_t currentOffset,
130 const size_t baseAlignment) noexcept {
131 // CALCULATE ALIGNMENT
133
134 // CHECK IF NOT OVERFLOWED
136 glsl_struct_assert(false, "Data overflow would happen!");
137 return bad_offset();
138 }
139
140 return alignmentOffset;
141 }
142
143 /// @brief returns padding value
144 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t _calculate_padding(const size_t currentOffset,
145 const size_t baseAlignment) noexcept {
147 }
148
149 /// @brief moves current offset to end of variable
150 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 bool _move_current_offset(size_t& currentOffset,
151 const size_t distance) noexcept {
153 glsl_struct_assert(false, "Data overflow would happen!");
154 return false;
155 }
156 return true;
157 }
158
159 #pragma region COMMON_CHECKS
160
161 /// @brief checks if vec length is between 2 and 4
162 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 bool _is_vec_length_good(const size_t length) noexcept {
163 if (length < 2 || length > 4) {
164 glsl_struct_assert(false, "value should be in range <2, 4>!");
165 return false;
166 }
167 return true;
168 }
169
170 /// @brief checks if array count is not zero
171 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 bool _is_array_count_good(const size_t count) {
172 if (count == 0) {
173 glsl_struct_assert(false, "array count cannot be zero!!");
174 return false;
175 }
176 return true;
177 }
178
179 /// @brief checks if struct is not empty
181 const mstd::ordered_map<std::string, var_data>& values
182 ) noexcept {
183 if (values.empty()) {
184 glsl_struct_assert(false, "struct cannot be empty!!");
185 return false;
186 }
187 return true;
188 }
189
190 #pragma endregion
191
192 #pragma region STANDARD_ADD
193
194 /// @brief returns alignment offset of variable and moves current offset
195 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t _add(size_t& currentOffset, const size_t baseAlignment,
196 const size_t baseOffset) noexcept {
197 // GET ALIGNMENT OFFSET
199
200 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
201
202 // CHECK OFFSET BOUNDARIES
205
206 // MOVE CURRENT OFFSET
208 return alignmentOffset;
209 }
210
211 /// @brief returns alignment offsets of array variables and moves current offset
213 const size_t arrayBaseAlignment, const size_t elemBaseOffset, const size_t count) noexcept {
214 // CALCULATE ARRAY ELEMENTS OFFSETS
216
219 for (size_t i = 0, elemOffset; i < count; ++i) {
221
222 if (elemOffset == bad_offset()) { return std::vector<size_t>(); }
223
225 }
226
227 // MOVE CURRENT OFFSET
229 return arrayOffsets;
230 }
231
232 #pragma endregion
233
234 #pragma region VARIABLE_ADD
235
236 /// @brief sets variable data
238 const std::string_view name, const size_t alignmentOffset, const bool isTopLevel,
241 #else
242 const size_t typeSize
243 #endif
244 ) {
245 // CHECK VARIABLE NAME
246 glsl_struct_assert(!contains(name), "Layout already contains value with name {}", name);
247
248 // SET VARIABLE
249
252 type,
253 #else
254 typeSize,
255 #endif
256 isTopLevel);
257 }
258
259 /// @brief sets array variables data
261 const std::string_view name, const std::vector<size_t>& alignmentOffsets, const bool isTopLevel,
264 #else
266 #endif
267 ) {
270 #else
272 #endif
273
274 for (size_t i = 0; i < alignmentOffsets.size(); ++i) {
275 // SET ELEMENT VARIABLE
280 #else
282 #endif
283 );
284
285 if (i < alignmentOffsets.size() - 1) {
287 }
288 }
289
290 // ADD ARRAY VAR
291 return _add_variable(
295 #else
297 #endif
298 );
299 }
300
302 /// @brief sets standard array variable
309 #endif
310
311 /// @brief sets mat variable
328
329 /// @brief sets array of mats variable
331 const bool isTopLevel, const size_t count,
333 const ValueType valueType, const size_t columns, const size_t rows,
334 #endif
339 #endif
340
341 for (size_t i = 0; i < alignmentOffsets.size(); ++i) {
342 const auto& matOffsets = alignmentOffsets[i];
343
344 // ADD SINGLE MAT VARIABLE DATA
349 #else
351 #endif
352 );
353
354 if (i < count - 1) { varData.set_padding(matPadding); }
355 }
356
357 // ADD ARRAY TYPE POINTER TO FIRST MAT
362 #else
364 #endif
365 );
366
368
369 return arrayVarData;
370 }
371
372 #pragma endregion
373
374 #pragma region BEFORE_ADD_EVENTS
375
376 /// @brief calls before add event
385
386 /// @brief calls before add array event
396
397 /// @brief calls before add scalar event
407
408 /// @brief calls before add vec event
418
419 /// @brief calls before add mat event
429
430 /// @brief calls before add struct event
440
441 #pragma endregion
442
443 #pragma region AFTER_ADD_EVENTS
444
445 /// @brief calls after add event
454
455 /// @brief calls after add array event
465
466 /// @brief calls after add scalar event
476
477 /// @brief calls after add vec event
487
488 /// @brief calls after add mat event
500
501 /// @brief calls after add struct event
511
512 #pragma endregion
513
514 #pragma region GET_ALIGNMENT
515
516 /// @brief returns array of elements alignment
523
524 /// @brief returns scalar alignment
531
532 /// @brief returns array of scalars alignment
536
537 /// @brief returns vec alignment
538 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _get_vec_alignment(const ValueType valueType, const size_t length) {
541 }
543 }
544
545 /// @brief returns array of vecs alignment
546 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _get_vec_array_alignment(const ValueType valueType, const size_t length) {
548 }
549
550 /// @brief returns mat alignment
551 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _get_mat_alignment(const ValueType valueType, const size_t rows) {
553 }
554
555 #pragma endregion
556
557 #pragma region SPECIALIZED_ADD
558
559 /// @brief adds scalar
560 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _add_scalar(const std::string_view name, const ValueType valueType) {
561 // BEFORE ADD SCALAR
563
564 // GET BASE OFFSET
566
567 // GET BASE ALIGNMENT
569
570 // GET ALIGNMENT OFFSET
572
573 // CHECK ADD
574 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
575
576 // ADD VARIABLE DATA
578 name, alignmentOffset, true,
581 #else
583 #endif
584 );
585
586 // AFTER ADD SCALAR
588
589 return alignmentOffset;
590 }
591
592 /// @brief adds array of scalars
594 const ValueType valueType, const size_t count) {
595 // CHECK COUNT
596 if (!_is_array_count_good(count)) { return std::vector<size_t>(); }
597
598 // BEFORE ADD SCALAR ARRAY
600
601 // GET BASE OFFSET
603
604 // GET ARRAY ALIGNMENT
606
607 // GET ALIGNMENT OFFSETS
610
611 // CHECK ADD
612 if (alignmentOffsets.empty()) { return alignmentOffsets; }
613
614 // GET ARRAY SIZE
616
617 // GET ARRAY PADDING
619
620 // APPLY PADDING TO CURRENT OFFSET
623
624 // ADD VARIABLE DATA
628 #else
630 #endif
631 arraySize)
633
634 // AFTER ADD SCALAR ARRAY
636
637 return alignmentOffsets;
638 }
639
640 /// @brief adds vec
641 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _add_vec(const std::string_view name, const size_t length,
642 const ValueType valueType) {
643 // CHECK VEC LENGTH
644 if (!_is_vec_length_good(length)) { return bad_offset(); }
645
646 // BEFORE ADD VEC
648
649 // GET BASE OFFSET
651
652 // GET BASE ALIGNMENT
654
655 // GET ALIGNMENT OFFSET
657
658 // CHECK ADD
659 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
660
661 // ADD VARIABLE DATA
663 name, alignmentOffset, true,
666 #else
668 #endif
669 );
670
671 // AFTER ADD VEC
673
674 return alignmentOffset;
675 }
676
677 /// @brief adds array of vecs
679 const size_t length, const ValueType valueType, const size_t count) {
680 // CHECK COUNT
681 if (!_is_array_count_good(count)) { return std::vector<size_t>(); }
682
683 // CHECK VEC LENGTH
684 if (!_is_vec_length_good(length)) { return std::vector<size_t>(); }
685
686 // BEFORE ADD VEC ARRAY
688
689 // GET BASE OFFSET
691
692 // GET ARRAY ALIGNMENT
694
695 // GET ALIGNMENT OFFSETS
698
699 // CHECK ADD
700 if (alignmentOffsets.empty()) { return alignmentOffsets; }
701
702 // GET ARRAY SIZE
704
705 // GET ARRAY PADDING
707
708 // APPLY PADDING TO CURRENT OFFSET
711
712 // ADD VARIABLE DATA
716 #else
718 #endif
719 arraySize)
721
722 // AFTER ADD VEC ARRAY
724
725 return alignmentOffsets;
726 }
727
728 /// @brief adds mat
730 const size_t rows, const ValueType valueType) {
731 // CHECK MAT COLUMNS
732 if (!_is_vec_length_good(columns)) { return std::vector<size_t>(); }
733
734 // CHECK MAT ROWS
735 if (!_is_vec_length_good(rows)) { return std::vector<size_t>(); }
736
737 // BEFORE ADD MAT
739
740 // GET BASE OFFSET
742
743 // GET MAT ALIGNMENT
745
746 // GET ALIGNMENT OFFSETS
749
750 // CHECK ADD
751 if (alignmentOffsets.empty()) { return alignmentOffsets; }
752
753 // GET MAT SIZE
755
756 // GET ARRAY PADDING
758
759 // APPLY PADDING TO CURRENT OFFSET
762
763 // ADD VARIABLE DATA
767 #endif
770
771 // AFTER ADD MAT
773
774 return alignmentOffsets;
775 }
776
777 /// @brief adds array of mats
779 const size_t columns, const size_t rows, const ValueType valueType, const size_t count) {
780 // CHECK COUNT
781 if (!_is_array_count_good(count)) { return std::vector<std::vector<size_t> >(); }
782
783 // CHECK MAT COLUMNS
784 if (!_is_vec_length_good(columns)) { return std::vector<std::vector<size_t> >(); }
785
786 // CHECK MAT ROWS
787 if (!_is_vec_length_good(rows)) { return std::vector<std::vector<size_t> >(); }
788
789 // BEFORE ADD MAT ARRAY
791
792 // GET BASE OFFSET
794
795 // GET ARRAY ALIGNMENT
797
798 // GET MATS ALIGNMENT OFFSETS
800
801 size_t matSize = 0;
802 size_t matPadding = 0;
803
806 for (size_t i = 0; i < count; ++i) {
807 // GET VEC ALIGNMENT OFFSETS
809
810 // CHECK ADD
811 if (alignmentOffsets.empty()) { return std::vector<std::vector<size_t> >(); }
812
813 // CALCULATE SIZE AND PADDING ONCE
814 if (matSize == 0) {
815 // CALCULATE SIZE
817
818 // CALCULATE PADDING
820 }
821
822 // APPLY PADDING TO CURRENT OFFSET
823 if (i != count - 1) {
825 }
826
828 }
829
830 // GET ARRAY SIZE
832
833 // APPLY PADDING TO CURRENT OFFSET
836
837 // ADD VARIABLE DATA
841 #endif
843
844 // AFTER ADD SCALAR ARRAY
846
848 }
849
850 /// @brief adds struct
853 // CHECK VALUES
854 if (!_is_struct_not_empty(values)) { return bad_offset(); }
855
856 // BEFORE ADD STRUCT
858
859 // GET ALIGNMENT OFFSET
861
862 // CHECK ADD
863 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
864
865 // ADD VARIABLE DATA
867 name, alignmentOffset, true,
870 #else
872 #endif
873 );
874
875 // ADD STRUCTURE VARIABLES DATA
876 for (const auto& [value_name, data] : values) {
880 data.get_type()
881 #else
882 data.get_size()
883 #endif
884 )
886 }
887
888 // AFTER ADD STRUCT
890
891 return alignmentOffset;
892 }
893
894 /// @brief adds array of structs
897 const size_t count) {
898 // CHECK COUNT
899 if (!_is_array_count_good(count)) { return std::vector<size_t>(); }
900
901 // CHECK VALUES
902 if (!_is_struct_not_empty(values)) { return std::vector<size_t>(); }
903
904 // BEFORE ADD STRUCTS ARRAY
906
907 // GET ARRAY ALIGNMENT
909
910 // GET ALIGNMENT OFFSETS
913
914 // CHECK ADD
915 if (alignmentOffsets.empty()) { return alignmentOffsets; }
916
917 // GET ARRAY SIZE
919
920 // GET ARRAY PADDING
922
923 // APPLY PADDING TO CURRENT OFFSET
926
927 // Add variables
928 for (size_t i = 0; i < count; ++i) {
931
932 // ADD STRUCTURE VARIABLES DATA
933 for (const auto& [value_name, data] : values) {
937 data.get_type()
938 #else
939 data.get_size()
940 #endif
941 )
943 }
944 }
945
946 // ADD VARIABLE DATA
950 #else
952 #endif
953 arraySize)
955
956 // AFTER ADD SCALAR ARRAY
958
959 return alignmentOffsets;
960 }
961
962 /// @brief adds multiple variables
963 template<class T, class... Ts, size_t Num, size_t... Nums>
965 const glsl_variable<Ts, Nums>&... vars) noexcept {
966 using VarType = glsl_variable<T, Num>;
967
970 else { add(var.varName, var.layout); }
971 }
972 else {
974 else { add<T>(var.varName); }
975 }
976 if _GLSL_STRUCT_CONSTEXPR17 (sizeof...(Ts) > 0 && sizeof...(Nums) > 0) { _add_variables(vars...); }
977 }
978
979 #pragma endregion
980
981 public:
982 #pragma region CONSTRUCTORS_WITHOUT_CONTEXT
983 /// @brief default constructor without providing context
985 template<class T = traits_type,
988 bool> = true>
989 #endif
991 (has_context &&
992 std::is_default_constructible_v<base_struct>))
993 : base_struct() {
994 }
995
996 /// @brief constructor for multiple variables
998 template<class... Ts, size_t... Nums>
999 #else
1000 template<class... Ts, size_t... Nums,
1002 #endif
1004 const glsl_variable<Ts, Nums>&... vars
1005 ) noexcept _GLSL_STRUCT_REQUIRES(!has_context || (has_context && std::is_default_constructible_v<base_struct>))
1006 : base_struct() {
1007 _add_variables(vars...);
1008 }
1009
1010 #pragma endregion
1011
1012 #pragma region CONSTRUCTORS_WITH_CONTEXT
1013 /// @brief constructor with provided context
1015 template<class T = traits_type, std::enable_if_t<has_context && std::is_same_v<T, traits_type>, bool> = true>
1016 #endif
1022
1023 /// @brief constructor for multiple variables and with provided context
1025 template<class... Ts, size_t... Nums>
1026 #else
1027 template<class... Ts, size_t... Nums, std::enable_if_t<has_context, bool> = true>
1028 #endif
1034
1035 #pragma endregion
1036
1037 /// @brief default copy constructor
1039
1040 /// @brief default move constructor
1042
1043 /// @brief default destructor
1045
1046 /// @brief default copy assign operator
1047 _GLSL_STRUCT_CONSTEXPR17 base_layout& operator=(const base_layout& other) noexcept = default;
1048
1049 /// @brief default move assign operator
1051
1052 /// @brief value indicating error while returning offset
1053 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t bad_offset() noexcept { return std::numeric_limits<size_t>::max(); }
1054
1055 /// @brief returns true if layout contains variable with given name
1056 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 bool contains(const std::string_view name) const noexcept {
1057 return _variables.contains(name.data());
1058 }
1059
1060 /// @brief returns variable data
1062 glsl_struct_assert(contains(name), "The variable name doesn't exists!");
1063 return _variables.at(name.data());
1064 }
1065
1066 /// @brief returns array count (if single value then returns 1 else if value doesn't exist returns 0 else array count)
1067 [[nodiscard]]
1070 #endif
1071 size_t get_array_count(const std::string_view name) const noexcept {
1072 if (!contains(name)) { return 0; }
1073
1076
1079 #else
1080 size_t i = 0;
1081 while (true) {
1083
1084 if (!contains(valueName)) { break; }
1085 ++i;
1086 }
1087
1088 if (i != 0) { return i; }
1089 #endif
1090 return 1;
1091 }
1092
1093 /// @brief returns elem size of array
1094 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_array_elem_size(const std::string_view name) const noexcept {
1096
1097 if (arrayCount == 0) { return 0; }
1098
1099 if (arrayCount == 1) { return _variables.at(name.data()).get_size(); }
1100
1102 }
1103
1104 /// @brief returns offset of variable with given name
1105 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_offset(const std::string_view name) const noexcept {
1106 return get(name).get_offset();
1107 }
1108
1109 /// @brief returns offsets of array elements
1112
1113 if (arrayCount == 0) { return {}; }
1114
1115 if (arrayCount == 1) { return { _variables.at(name.data()).get_offset() }; }
1116
1119 for (size_t i = 0; i != arrayCount; ++i) {
1121 }
1122 return values;
1123 }
1124
1126 /// @brief returns type of variable
1128 return get(name).get_type();
1129 }
1130
1131 /// @brief returns type of variable with casting to given type (dynamic casting occurs)
1132 #if _GLSL_STRUCT_HAS_CXX20
1133 template<utils::glsl_type Type>
1134 #else
1135 template<class Type, std::enable_if_t<utils::is_glsl_type_v<Type>, bool> = true>
1136 #endif
1140 #endif
1141
1142 /// @brief returns total size of variable (size + padding)
1143 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_total_size(const std::string_view name) const noexcept {
1144 return get(name).get_total_size();
1145 }
1146
1147 /// @brief returns size of variable
1148 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_size(const std::string_view name) const noexcept {
1149 return get(name).get_size();
1150 }
1151
1152 /// @brief returns padding of variable
1153 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_padding(const std::string_view name) const noexcept {
1154 return get(name).get_padding();
1155 }
1156
1157 /// @brief returns all variables names
1161
1163 for (const auto& name : _variables | std::views::keys) { names.push_back(name); }
1164 #else
1165 for (const auto& [name, data] : _variables) { names.push_back(name); }
1166 #endif
1167
1168 return names;
1169 }
1170
1171 /// @brief returns all variables and their data
1173 return _variables;
1174 }
1175
1176 /// @brief returns all top level variables and their data
1179 for (const auto& [name, data] : _variables) {
1180 if (!data.is_top_level()) { continue; }
1182 }
1183 return variables;
1184 }
1185
1186 /// @brief returns base alignment of layout
1191
1192 /// @brief returns size of layout
1193 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t size() const noexcept { return _currentOffset; }
1194
1195 /// @brief clears layout and all variables
1197 _currentOffset = 0;
1198 _variables.clear();
1199 }
1200
1201 #pragma region ADD_SCALAR
1202 /// @brief adds scalar
1204 template<utils::glsl_scalar S>
1205 #else
1206 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S>, bool> = true>
1207 #endif
1211
1212 #pragma endregion
1213
1214 #pragma region ADD_SCALARS_ARRAY
1215
1216 /// @brief adds array of scalars
1218 template<utils::glsl_scalar S>
1219 #else
1220 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S>, bool> = true>
1221 #endif
1225
1226 /// @brief adds array of scalars
1228 template<utils::glsl_scalars_array SA>
1229 #else
1230 template<class SA, std::enable_if_t<utils::is_glsl_scalars_array_v<SA>, bool> = true>
1231 #endif
1233 using S = utils::array_value_type_t<SA>;
1234 return add<S>(name, count);
1235 }
1236
1237 /// @brief adds array of scalars
1240 #else
1241 template<class SA, std::enable_if_t<utils::is_glsl_scalars_static_size_array_v<SA>, bool> = true>
1242 #endif
1246
1247 #pragma endregion
1248
1249 #pragma region ADD_VEC
1250 /// @brief adds vec
1252 template<utils::glsl_vec V>
1253 #else
1254 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
1255 #endif
1259
1260 #pragma endregion
1261
1262 #pragma region ADD_VECS_ARRAY
1263
1264 /// @brief adds array of vecs
1266 template<utils::glsl_vec V>
1267 #else
1268 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
1269 #endif
1273
1274 /// @brief adds array of vecs
1276 template<utils::glsl_vecs_array VA>
1277 #else
1278 template<class VA, std::enable_if_t<utils::is_glsl_vecs_array_v<VA>, bool> = true>
1279 #endif
1281 using V = utils::array_value_type_t<VA>;
1282 return add<V>(name, count);
1283 }
1284
1285 /// @brief adds array of vecs
1288 #else
1289 template<class VA, std::enable_if_t<utils::is_glsl_vecs_static_size_array_v<VA>, bool> = true>
1290 #endif
1294
1295 #pragma endregion
1296
1297 #pragma region ADD_MAT
1298 /// @brief adds mat
1300 template<utils::glsl_mat M>
1301 #else
1302 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
1303 #endif
1307
1308 #pragma endregion
1309
1310 #pragma region ADD_MATS_ARRAY
1311
1312 /// @brief adds array of mats
1314 template<utils::glsl_mat M>
1315 #else
1316 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
1317 #endif
1321
1322 /// @brief adds array of mats
1324 template<utils::glsl_mats_array MA>
1325 #else
1326 template<class MA, std::enable_if_t<utils::is_glsl_mats_array_v<MA>, bool> = true>
1327 #endif
1332
1333 /// @brief adds array of mats
1336 #else
1337 template<class MA, std::enable_if_t<utils::is_glsl_mats_static_size_array_v<MA>, bool> = true>
1338 #endif
1342
1343 #pragma endregion
1344
1345 #pragma region ADD_STRUCT
1346
1347 /// @brief adds struct with given layout
1351
1352 #pragma endregion
1353
1354 #pragma region ADD_STRUCTS_ARRAY
1355
1356 /// @brief adds array of structs with given layout
1361
1362 #pragma endregion
1363
1364 /// @brief checks equality of layouts
1368
1369 /// @brief default not equal operator
1372 = default;
1373 #else
1374 {
1375 return !(*this == other);
1376 }
1377 #endif
1378 };
1379} // namespace glslstruct
1380
1381/**
1382 * @brief std::hash overload for base_layout
1383 * @ingroup glslstruct
1384 * @tparam Traits layout traits type
1385 */
1386template<class Traits>
1387struct std::hash<glslstruct::base_layout<Traits> > {
1388 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t operator()(const glslstruct::base_layout<Traits>& layout) const noexcept {
1389 size_t seed = mstd::hash_combine(layout._currentOffset, layout._maxAlignment);
1390 for (const auto& [name, data] : layout._variables) { mstd::hash_append(seed, name, data); }
1391 return seed;
1392 }
1393};
1394 #endif
1395#endif
base layout container
Definition base_layout.hpp:87
_GLSL_STRUCT_CONSTEXPR20 const mstd::ordered_map< std::string, var_data > & get_variables() const noexcept
returns all variables and their data
Definition base_layout.hpp:1172
_GLSL_STRUCT_CONSTEXPR20 std::vector< std::string > get_names() const noexcept
returns all variables names
Definition base_layout.hpp:1158
_GLSL_STRUCT_CONSTEXPR17 var_data & _add_variable(const std::string_view name, const size_t alignmentOffset, const bool isTopLevel, const base_type_handle &type)
sets variable data
Definition base_layout.hpp:237
_GLSL_STRUCT_CONSTEXPR17 size_t get_array_count(const std::string_view name) const noexcept
returns array count (if single value then returns 1 else if value doesn't exist returns 0 else array ...
Definition base_layout.hpp:1071
_GLSL_STRUCT_CONSTEXPR17 void _before_add_struct()
calls before add struct event
Definition base_layout.hpp:431
_GLSL_STRUCT_CONSTEXPR17 var_data & _add_mat_variable(const std::string_view name, const std::vector< size_t > &alignmentOffsets, const bool isTopLevel, const ValueType valueType, const size_t columns, const size_t rows, const size_t vecBaseOffset, const size_t matBaseOffset)
sets mat variable
Definition base_layout.hpp:312
_GLSL_STRUCT_CONSTEXPR17 size_t get_array_elem_size(const std::string_view name) const noexcept
returns elem size of array
Definition base_layout.hpp:1094
static _GLSL_STRUCT_CONSTEXPR17 size_t _calculate_padding(const size_t currentOffset, const size_t baseAlignment) noexcept
returns padding value
Definition base_layout.hpp:144
_GLSL_STRUCT_CONSTEXPR17 size_t _add_vec(const std::string_view name, const size_t length, const ValueType valueType)
adds vec
Definition base_layout.hpp:641
_GLSL_STRUCT_CONSTEXPR17 size_t get_offset(const std::string_view name) const noexcept
returns offset of variable with given name
Definition base_layout.hpp:1105
_GLSL_STRUCT_CONSTEXPR17 size_t get_total_size(const std::string_view name) const noexcept
returns total size of variable (size + padding)
Definition base_layout.hpp:1143
static _GLSL_STRUCT_CONSTEXPR20 std::vector< size_t > _add_array(size_t &currentOffset, const size_t arrayBaseAlignment, const size_t elemBaseOffset, const size_t count) noexcept
returns alignment offsets of array variables and moves current offset
Definition base_layout.hpp:212
static _GLSL_STRUCT_CONSTEXPR17 bool _is_struct_not_empty(const mstd::ordered_map< std::string, var_data > &values) noexcept
checks if struct is not empty
Definition base_layout.hpp:180
_GLSL_STRUCT_CONSTEXPR17 void _before_add_scalar()
calls before add scalar event
Definition base_layout.hpp:398
_GLSL_STRUCT_CONSTEXPR20 std::vector< size_t > _add_vec_array(const std::string_view name, const size_t length, const ValueType valueType, const size_t count)
adds array of vecs
Definition base_layout.hpp:678
_GLSL_STRUCT_CONSTEXPR17 base_layout & operator=(const base_layout &other) noexcept=default
default copy assign operator
Traits traits_type
traits type
Definition base_layout.hpp:90
_GLSL_STRUCT_CONSTEXPR17 void _after_add(const size_t baseOffset, const size_t baseAlignment)
calls after add event
Definition base_layout.hpp:446
_GLSL_STRUCT_CONSTEXPR17 size_t _get_scalar_alignment(const ValueType valueType)
returns scalar alignment
Definition base_layout.hpp:525
_GLSL_STRUCT_CONSTEXPR17 void clear() noexcept
clears layout and all variables
Definition base_layout.hpp:1196
_GLSL_STRUCT_CONSTEXPR17 void _after_add_mat(const size_t baseOffset, const size_t baseAlignment)
calls after add mat event
Definition base_layout.hpp:489
_GLSL_STRUCT_CONSTEXPR17 void _after_add_struct(const size_t baseOffset, const size_t baseAlignment)
calls after add struct event
Definition base_layout.hpp:502
static _GLSL_STRUCT_CONSTEXPR17 size_t _add(size_t &currentOffset, const size_t baseAlignment, const size_t baseOffset) noexcept
returns alignment offset of variable and moves current offset
Definition base_layout.hpp:195
_GLSL_STRUCT_CONSTEXPR17 void _after_add_array(const size_t baseOffset, const size_t baseAlignment)
calls after add array event
Definition base_layout.hpp:456
static _GLSL_STRUCT_CONSTEXPR17 bool has_context
value indicating if traits has context defined
Definition base_layout.hpp:93
_GLSL_STRUCT_CONSTEXPR17 size_t _add_scalar(const std::string_view name, const ValueType valueType)
adds scalar
Definition base_layout.hpp:560
static _GLSL_STRUCT_CONSTEXPR17 size_t _calculate_alignment_offset(const size_t currentOffset, const size_t baseAlignment) noexcept
calculates alignment offset
Definition base_layout.hpp:129
mstd::ordered_map< std::string, var_data > _variables
variables data
Definition base_layout.hpp:103
_GLSL_STRUCT_CONSTEXPR17 size_t _get_scalar_array_alignment(const ValueType valueType)
returns array of scalars alignment
Definition base_layout.hpp:533
_GLSL_STRUCT_CONSTEXPR17 void _after_add_vec(const size_t baseOffset, const size_t baseAlignment)
calls after add vec event
Definition base_layout.hpp:478
_GLSL_STRUCT_CONSTEXPR17 size_t get_size(const std::string_view name) const noexcept
returns size of variable
Definition base_layout.hpp:1148
_GLSL_STRUCT_CONSTEXPR20 std::vector< size_t > _add_mat(const std::string_view name, const size_t columns, const size_t rows, const ValueType valueType)
adds mat
Definition base_layout.hpp:729
_GLSL_STRUCT_CONSTEXPR17 size_t _get_array_alignment(const size_t elemBaseAlignment)
returns array of elements alignment
Definition base_layout.hpp:517
_GLSL_STRUCT_CONSTEXPR20 std::vector< size_t > get_array_offsets(const std::string_view name) const noexcept
returns offsets of array elements
Definition base_layout.hpp:1110
_GLSL_STRUCT_CONSTEXPR17 size_t _get_mat_alignment(const ValueType valueType, const size_t rows)
returns mat alignment
Definition base_layout.hpp:551
static _GLSL_STRUCT_CONSTEXPR17 bool _is_array_count_good(const size_t count)
checks if array count is not zero
Definition base_layout.hpp:171
_GLSL_STRUCT_CONSTEXPR17 size_t _get_vec_alignment(const ValueType valueType, const size_t length)
returns vec alignment
Definition base_layout.hpp:538
_GLSL_STRUCT_CONSTEXPR17 void _before_add_vec()
calls before add vec event
Definition base_layout.hpp:409
_GLSL_STRUCT_CONSTEXPR20 ~base_layout() noexcept=default
default destructor
static _GLSL_STRUCT_CONSTEXPR17 bool _move_current_offset(size_t &currentOffset, const size_t distance) noexcept
moves current offset to end of variable
Definition base_layout.hpp:150
_GLSL_STRUCT_CONSTEXPR17 var_data & _set_variable(const std::string_view name, const size_t offset, const base_type_handle &type, const bool isTopLevel, const size_t padding=0)
sets variable data
Definition base_layout.hpp:110
_GLSL_STRUCT_CONSTEXPR17 const var_data & get(const std::string_view name) const noexcept
returns variable data
Definition base_layout.hpp:1061
_GLSL_STRUCT_CONSTEXPR17 size_t size() const noexcept
returns size of layout
Definition base_layout.hpp:1193
size_t _currentOffset
current offset
Definition base_layout.hpp:105
_GLSL_STRUCT_CONSTEXPR17 base_layout(base_layout &&other) noexcept=default
default move constructor
_GLSL_STRUCT_CONSTEXPR20 std::vector< size_t > _add_scalar_array(const std::string_view name, const ValueType valueType, const size_t count)
adds array of scalars
Definition base_layout.hpp:593
static _GLSL_STRUCT_CONSTEXPR17 size_t bad_offset() noexcept
value indicating error while returning offset
Definition base_layout.hpp:1053
_GLSL_STRUCT_CONSTEXPR17 void _after_add_scalar(const size_t baseOffset, const size_t baseAlignment)
calls after add scalar event
Definition base_layout.hpp:467
var_data & _add_mat_array_variable(const std::string_view name, const std::vector< std::vector< size_t > > &alignmentOffsets, const bool isTopLevel, const size_t count, const ValueType valueType, const size_t columns, const size_t rows, const size_t vecBaseOffset, const size_t matBaseOffset, const size_t arrayBaseOffset, const size_t matPadding)
sets array of mats variable
Definition base_layout.hpp:330
_GLSL_STRUCT_CONSTEXPR17 size_t _get_vec_array_alignment(const ValueType valueType, const size_t length)
returns array of vecs alignment
Definition base_layout.hpp:546
mstd::ordered_map< std::string, var_data > get_top_level_variables() const noexcept
returns all top level variables and their data
Definition base_layout.hpp:1177
_GLSL_STRUCT_CONSTEXPR17 size_t base_alignment() const noexcept
returns base alignment of layout
Definition base_layout.hpp:1187
static _GLSL_STRUCT_CONSTEXPR17 bool _is_vec_length_good(const size_t length) noexcept
checks if vec length is between 2 and 4
Definition base_layout.hpp:162
_GLSL_STRUCT_CONSTEXPR17 void _before_add_mat()
calls before add mat event
Definition base_layout.hpp:420
_GLSL_STRUCT_CONSTEXPR17 base_layout & operator=(base_layout &&other) noexcept=default
default move assign operator
_GLSL_STRUCT_CONSTEXPR17 var_data & _add_array_variable(const std::string_view name, const std::vector< size_t > &alignmentOffsets, const bool isTopLevel, const base_type_handle &elemType, const base_type_handle &arrayType)
sets array variables data
Definition base_layout.hpp:260
_GLSL_STRUCT_CONSTEXPR17 size_t get_padding(const std::string_view name) const noexcept
returns padding of variable
Definition base_layout.hpp:1153
_GLSL_STRUCT_CONSTEXPR17 bool contains(const std::string_view name) const noexcept
returns true if layout contains variable with given name
Definition base_layout.hpp:1056
_GLSL_STRUCT_CONSTEXPR17 void _before_add_array()
calls before add array event
Definition base_layout.hpp:387
_GLSL_STRUCT_CONSTEXPR17 void _before_add()
calls before add event
Definition base_layout.hpp:377
#define _GLSL_STRUCT_TYPENAME17
Definition config.hpp:216
#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_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_HAS_TYPES
check if user not disabled type containers using GLSL_STRUCT_DISABLE_TYPES
Definition config.hpp:162
#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
Context container for layout.
Definition base_layout.hpp:45
_GLSL_STRUCT_CONSTEXPR17 layout_with_context(const context_type &ctx)
constructor with context value
Definition base_layout.hpp:66
context_type _context
context value
Definition base_layout.hpp:51
_GLSL_STRUCT_CONSTEXPR17 layout_with_context() noexcept _GLSL_STRUCT_REQUIRES(std
default constructor
Definition base_layout.hpp:59
_GLSL_STRUCT_TYPENAME17 Traits::context_type context_type
context type
Definition base_layout.hpp:47
empty container for layout
Definition base_layout.hpp:73