GLSL Struct 1.4.8
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/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/hash.hpp>
34 #include <glslstruct/utils/ValueType.hpp>
35 #include <glslstruct/var_data/var_data.hpp>
36 #include <glslstruct/variable/glsl_variable.hpp>
37
38namespace glslstruct {
39 namespace utils {
40 /**
41 * @brief Context container for layout
42 * @ingroup utils
43 * @tparam Traits layout traits type
44 */
45 template<class Traits>
47 /// @brief context type
49
50 protected:
51 /// @brief context value
53
54 public:
55 /// @brief default constructor
57 template<class C = context_type,
58 std::enable_if_t<std::is_default_constructible_v<context_type> && std::is_same_v<C, context_type>, bool> = true>
59 #endif
61 std::is_default_constructible_v<context_type>
62 )
63 : _context() {
64 }
65
66 /// @brief constructor with context value
68 };
69
70 /**
71 * @brief empty container for layout
72 * @ingroup utils
73 */
75 } // namespace utils
76
77 /**
78 * @brief base layout container
79 * @ingroup glslstruct
80 * @tparam Traits layout traits type
81 */
83 template<layout_traits Traits>
84 #else
85 template<class Traits, std::enable_if_t<is_layout_traits_v<Traits>, bool> >
86 #endif
89 public:
90 /// @brief traits type
91 using traits_type = Traits;
92
93 /// @brief value indicating if traits has context defined
94 static _GLSL_STRUCT_CONSTEXPR17 bool has_context = utils::has_layout_traits_context_v<traits_type>;
95
96 private:
97 friend struct std::hash<base_layout>;
98
99 /// @brief base layout struct
102
103 /// @brief variables data
105 /// @brief current offset
106 size_t _currentOffset = 0;
107
108 #pragma region VARIABLE_SET
109
110 /// @brief sets variable data
113 const base_type_handle& type,
114 #else
115 const size_t size,
116 #endif
117 const bool isTopLevel, const size_t padding = 0) {
120 type,
121 #else
122 size,
123 #endif
125 }
126
127 #pragma endregion
128
129 /// @brief calculates alignment offset
130 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t _calculate_alignment_offset(const size_t currentOffset,
131 const size_t baseAlignment) noexcept {
132 // CALCULATE ALIGNMENT
134
135 // CHECK IF NOT OVERFLOWED
137 glsl_struct_assert(false, "Data overflow would happen!");
138 return bad_offset();
139 }
140
141 return alignmentOffset;
142 }
143
144 /// @brief returns padding value
145 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t _calculate_padding(const size_t currentOffset,
146 const size_t baseAlignment) noexcept {
148 }
149
150 /// @brief moves current offset to end of variable
151 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 bool _move_current_offset(size_t& currentOffset,
152 const size_t distance) noexcept {
154 glsl_struct_assert(false, "Data overflow would happen!");
155 return false;
156 }
157 return true;
158 }
159
160 #pragma region COMMON_CHECKS
161
162 /// @brief checks if vec length is between 2 and 4
163 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 bool _is_vec_length_good(const size_t length) noexcept {
164 if (length < 2 || length > 4) {
165 glsl_struct_assert(false, "value should be in range <2, 4>!");
166 return false;
167 }
168 return true;
169 }
170
171 /// @brief checks if array count is not zero
172 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 bool _is_array_count_good(const size_t count) {
173 if (count == 0) {
174 glsl_struct_assert(false, "array count cannot be zero!!");
175 return false;
176 }
177 return true;
178 }
179
180 /// @brief checks if struct is not empty
182 const mstd::ordered_map<std::string, var_data>& values
183 ) noexcept {
184 if (values.empty()) {
185 glsl_struct_assert(false, "struct cannot be empty!!");
186 return false;
187 }
188 return true;
189 }
190
191 #pragma endregion
192
193 #pragma region STANDARD_ADD
194
195 /// @brief returns alignment offset of variable and moves current offset
196 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t _add(size_t& currentOffset, const size_t baseAlignment,
197 const size_t baseOffset) noexcept {
198 // GET ALIGNMENT OFFSET
200
201 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
202
203 // CHECK OFFSET BOUNDARIES
206
207 // MOVE CURRENT OFFSET
209 return alignmentOffset;
210 }
211
212 /// @brief returns alignment offsets of array variables and moves current offset
214 const size_t arrayBaseAlignment, const size_t elemBaseOffset, const size_t count) noexcept {
215 // CALCULATE ARRAY ELEMENTS OFFSETS
217
220 for (size_t i = 0, elemOffset; i < count; ++i) {
222
223 if (elemOffset == bad_offset()) { return std::vector<size_t>(); }
224
226 }
227
228 // MOVE CURRENT OFFSET
230 return arrayOffsets;
231 }
232
233 #pragma endregion
234
235 #pragma region VARIABLE_ADD
236
237 /// @brief sets variable data
239 const std::string_view name, const size_t alignmentOffset, const bool isTopLevel,
242 #else
243 const size_t typeSize
244 #endif
245 ) {
246 // CHECK VARIABLE NAME
247 glsl_struct_assert(!contains(name), "Layout already contains value with name {}", name);
248
249 // SET VARIABLE
250
253 type,
254 #else
255 typeSize,
256 #endif
257 isTopLevel);
258 }
259
260 /// @brief sets array variables data
262 const std::string_view name, const std::vector<size_t>& alignmentOffsets, const bool isTopLevel,
265 #else
267 #endif
268 ) {
271 #else
273 #endif
274
275 for (size_t i = 0; i < alignmentOffsets.size(); ++i) {
276 // SET ELEMENT VARIABLE
281 #else
283 #endif
284 );
285
286 if (i < alignmentOffsets.size() - 1) {
288 }
289 }
290
291 // ADD ARRAY VAR
292 return _add_variable(
296 #else
298 #endif
299 );
300 }
301
303 /// @brief sets standard array variable
310 #endif
311
312 /// @brief sets mat variable
329
330 /// @brief sets array of mats variable
332 const bool isTopLevel, const size_t count,
334 const ValueType valueType, const size_t columns, const size_t rows,
335 #endif
340 #endif
341
342 for (size_t i = 0; i < alignmentOffsets.size(); ++i) {
343 const auto& matOffsets = alignmentOffsets[i];
344
345 // ADD SINGLE MAT VARIABLE DATA
350 #else
352 #endif
353 );
354
355 if (i < count - 1) { varData.set_padding(matPadding); }
356 }
357
358 // ADD ARRAY TYPE POINTER TO FIRST MAT
363 #else
365 #endif
366 );
367
369
370 return arrayVarData;
371 }
372
373 #pragma endregion
374
375 #pragma region BEFORE_ADD_EVENTS
376
377 /// @brief calls before add event
386
387 /// @brief calls before add array event
397
398 /// @brief calls before add scalar event
408
409 /// @brief calls before add vec event
419
420 /// @brief calls before add mat event
430
431 /// @brief calls before add struct event
441
442 #pragma endregion
443
444 #pragma region AFTER_ADD_EVENTS
445
446 /// @brief calls after add event
455
456 /// @brief calls after add array event
466
467 /// @brief calls after add scalar event
477
478 /// @brief calls after add vec event
488
489 /// @brief calls after add mat event
501
502 /// @brief calls after add struct event
512
513 #pragma endregion
514
515 #pragma region GET_ALIGNMENT
516
517 /// @brief returns array of elements alignment
524
525 /// @brief returns scalar alignment
532
533 /// @brief returns array of scalars alignment
537
538 /// @brief returns vec alignment
539 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _get_vec_alignment(const ValueType valueType, const size_t length) {
542 }
544 }
545
546 /// @brief returns array of vecs alignment
547 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _get_vec_array_alignment(const ValueType valueType, const size_t length) {
549 }
550
551 /// @brief returns mat alignment
552 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _get_mat_alignment(const ValueType valueType, const size_t rows) {
554 }
555
556 #pragma endregion
557
558 #pragma region SPECIALIZED_ADD
559
560 /// @brief adds scalar
561 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _add_scalar(const std::string_view name, const ValueType valueType) {
562 // BEFORE ADD SCALAR
564
565 // GET BASE OFFSET
567
568 // GET BASE ALIGNMENT
570
571 // GET ALIGNMENT OFFSET
573
574 // CHECK ADD
575 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
576
577 // ADD VARIABLE DATA
579 name, alignmentOffset, true,
582 #else
584 #endif
585 );
586
587 // AFTER ADD SCALAR
589
590 return alignmentOffset;
591 }
592
593 /// @brief adds array of scalars
595 const ValueType valueType, const size_t count) {
596 // CHECK COUNT
597 if (!_is_array_count_good(count)) { return std::vector<size_t>(); }
598
599 // BEFORE ADD SCALAR ARRAY
601
602 // GET BASE OFFSET
604
605 // GET ARRAY ALIGNMENT
607
608 // GET ALIGNMENT OFFSETS
611
612 // CHECK ADD
613 if (alignmentOffsets.empty()) { return alignmentOffsets; }
614
615 // GET ARRAY SIZE
617
618 // GET ARRAY PADDING
620
621 // APPLY PADDING TO CURRENT OFFSET
624
625 // ADD VARIABLE DATA
629 #else
631 #endif
632 arraySize)
634
635 // AFTER ADD SCALAR ARRAY
637
638 return alignmentOffsets;
639 }
640
641 /// @brief adds vec
642 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t _add_vec(const std::string_view name, const size_t length,
643 const ValueType valueType) {
644 // CHECK VEC LENGTH
645 if (!_is_vec_length_good(length)) { return bad_offset(); }
646
647 // BEFORE ADD VEC
649
650 // GET BASE OFFSET
652
653 // GET BASE ALIGNMENT
655
656 // GET ALIGNMENT OFFSET
658
659 // CHECK ADD
660 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
661
662 // ADD VARIABLE DATA
664 name, alignmentOffset, true,
667 #else
669 #endif
670 );
671
672 // AFTER ADD VEC
674
675 return alignmentOffset;
676 }
677
678 /// @brief adds array of vecs
680 const size_t length, const ValueType valueType, const size_t count) {
681 // CHECK COUNT
682 if (!_is_array_count_good(count)) { return std::vector<size_t>(); }
683
684 // CHECK VEC LENGTH
685 if (!_is_vec_length_good(length)) { return std::vector<size_t>(); }
686
687 // BEFORE ADD VEC ARRAY
689
690 // GET BASE OFFSET
692
693 // GET ARRAY ALIGNMENT
695
696 // GET ALIGNMENT OFFSETS
699
700 // CHECK ADD
701 if (alignmentOffsets.empty()) { return alignmentOffsets; }
702
703 // GET ARRAY SIZE
705
706 // GET ARRAY PADDING
708
709 // APPLY PADDING TO CURRENT OFFSET
712
713 // ADD VARIABLE DATA
717 #else
719 #endif
720 arraySize)
722
723 // AFTER ADD VEC ARRAY
725
726 return alignmentOffsets;
727 }
728
729 /// @brief adds mat
731 const size_t rows, const ValueType valueType) {
732 // CHECK MAT COLUMNS
733 if (!_is_vec_length_good(columns)) { return std::vector<size_t>(); }
734
735 // CHECK MAT ROWS
736 if (!_is_vec_length_good(rows)) { return std::vector<size_t>(); }
737
738 // BEFORE ADD MAT
740
741 // GET BASE OFFSET
743
744 // GET MAT ALIGNMENT
746
747 // GET ALIGNMENT OFFSETS
750
751 // CHECK ADD
752 if (alignmentOffsets.empty()) { return alignmentOffsets; }
753
754 // GET MAT SIZE
756
757 // GET ARRAY PADDING
759
760 // APPLY PADDING TO CURRENT OFFSET
763
764 // ADD VARIABLE DATA
768 #endif
771
772 // AFTER ADD MAT
774
775 return alignmentOffsets;
776 }
777
778 /// @brief adds array of mats
780 const size_t columns, const size_t rows, const ValueType valueType, const size_t count) {
781 // CHECK COUNT
782 if (!_is_array_count_good(count)) { return std::vector<std::vector<size_t> >(); }
783
784 // CHECK MAT COLUMNS
785 if (!_is_vec_length_good(columns)) { return std::vector<std::vector<size_t> >(); }
786
787 // CHECK MAT ROWS
788 if (!_is_vec_length_good(rows)) { return std::vector<std::vector<size_t> >(); }
789
790 // BEFORE ADD MAT ARRAY
792
793 // GET BASE OFFSET
795
796 // GET ARRAY ALIGNMENT
798
799 // GET MATS ALIGNMENT OFFSETS
801
802 size_t matSize = 0;
803 size_t matPadding = 0;
804
807 for (size_t i = 0; i < count; ++i) {
808 // GET VEC ALIGNMENT OFFSETS
810
811 // CHECK ADD
812 if (alignmentOffsets.empty()) { return std::vector<std::vector<size_t> >(); }
813
814 // CALCULATE SIZE AND PADDING ONCE
815 if (matSize == 0) {
816 // CALCULATE SIZE
818
819 // CALCULATE PADDING
821 }
822
823 // APPLY PADDING TO CURRENT OFFSET
824 if (i != count - 1) {
826 }
827
829 }
830
831 // GET ARRAY SIZE
833
834 // APPLY PADDING TO CURRENT OFFSET
837
838 // ADD VARIABLE DATA
842 #endif
844
845 // AFTER ADD SCALAR ARRAY
847
849 }
850
851 /// @brief adds struct
854 // CHECK VALUES
855 if (!_is_struct_not_empty(values)) { return bad_offset(); }
856
857 // BEFORE ADD STRUCT
859
860 // GET ALIGNMENT OFFSET
862
863 // CHECK ADD
864 if (alignmentOffset == bad_offset()) { return alignmentOffset; }
865
866 // ADD VARIABLE DATA
868 name, alignmentOffset, true,
871 #else
873 #endif
874 );
875
876 // ADD STRUCTURE VARIABLES DATA
877 for (const auto& [value_name, data] : values) {
881 data.get_type()
882 #else
883 data.get_size()
884 #endif
885 )
887 }
888
889 // AFTER ADD STRUCT
891
892 return alignmentOffset;
893 }
894
895 /// @brief adds array of structs
898 const size_t count) {
899 // CHECK COUNT
900 if (!_is_array_count_good(count)) { return std::vector<size_t>(); }
901
902 // CHECK VALUES
903 if (!_is_struct_not_empty(values)) { return std::vector<size_t>(); }
904
905 // BEFORE ADD STRUCTS ARRAY
907
908 // GET ARRAY ALIGNMENT
910
911 // GET ALIGNMENT OFFSETS
914
915 // CHECK ADD
916 if (alignmentOffsets.empty()) { return alignmentOffsets; }
917
918 // GET ARRAY SIZE
920
921 // GET ARRAY PADDING
923
924 // APPLY PADDING TO CURRENT OFFSET
927
928 // Add variables
929 for (size_t i = 0; i < count; ++i) {
932
933 // ADD STRUCTURE VARIABLES DATA
934 for (const auto& [value_name, data] : values) {
938 data.get_type()
939 #else
940 data.get_size()
941 #endif
942 )
944 }
945 }
946
947 // ADD VARIABLE DATA
951 #else
953 #endif
954 arraySize)
956
957 // AFTER ADD SCALAR ARRAY
959
960 return alignmentOffsets;
961 }
962
963 /// @brief adds multiple variables
964 template<class T, class... Ts, size_t Num, size_t... Nums>
966 const glsl_variable<Ts, Nums>&... vars) noexcept {
967 using VarType = glsl_variable<T, Num>;
968
971 else { add(var.varName, var.layout); }
972 }
973 else {
975 else { add<T>(var.varName); }
976 }
977 if _GLSL_STRUCT_CONSTEXPR17 (sizeof...(Ts) > 0 && sizeof...(Nums) > 0) { _add_variables(vars...); }
978 }
979
980 #pragma endregion
981
982 public:
983 #pragma region CONSTRUCTORS_WITHOUT_CONTEXT
984 /// @brief default constructor without providing context
986 template<class T = traits_type,
989 bool> = true>
990 #endif
992 (has_context &&
993 std::is_default_constructible_v<base_struct>))
994 : base_struct() {
995 }
996
997 /// @brief constructor for multiple variables
999 template<class... Ts, size_t... Nums>
1000 #else
1001 template<class... Ts, size_t... Nums,
1003 #endif
1005 const glsl_variable<Ts, Nums>&... vars
1006 ) noexcept _GLSL_STRUCT_REQUIRES(!has_context || (has_context && std::is_default_constructible_v<base_struct>))
1007 : base_struct() {
1008 _add_variables(vars...);
1009 }
1010
1011 #pragma endregion
1012
1013 #pragma region CONSTRUCTORS_WITH_CONTEXT
1014 /// @brief constructor with provided context
1016 template<class T = traits_type, std::enable_if_t<has_context && std::is_same_v<T, traits_type>, bool> = true>
1017 #endif
1023
1024 /// @brief constructor for multiple variables and with provided context
1026 template<class... Ts, size_t... Nums>
1027 #else
1028 template<class... Ts, size_t... Nums, std::enable_if_t<has_context, bool> = true>
1029 #endif
1035
1036 #pragma endregion
1037
1038 /// @brief default copy constructor
1040
1041 /// @brief default move constructor
1043
1044 /// @brief default destructor
1046
1047 /// @brief default copy assign operator
1048 _GLSL_STRUCT_CONSTEXPR17 base_layout& operator=(const base_layout& other) noexcept = default;
1049
1050 /// @brief default move assign operator
1052
1053 /// @brief value indicating error while returning offset
1054 [[nodiscard]] static _GLSL_STRUCT_CONSTEXPR17 size_t bad_offset() noexcept { return std::numeric_limits<size_t>::max(); }
1055
1056 /// @brief returns true if layout contains variable with given name
1057 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 bool contains(const std::string_view name) const noexcept {
1058 return _variables.contains(name.data());
1059 }
1060
1061 /// @brief returns variable data
1063 glsl_struct_assert(contains(name), "The variable name doesn't exists!");
1064 return _variables.at(name.data());
1065 }
1066
1067 /// @brief returns array count (if single value then returns 1 else if value doesn't exist returns 0 else array count)
1068 [[nodiscard]]
1071 #endif
1072 size_t get_array_count(const std::string_view name) const noexcept {
1073 if (!contains(name)) { return 0; }
1074
1077
1080 #else
1081 size_t i = 0;
1082 while (true) {
1084
1085 if (!contains(valueName)) { break; }
1086 ++i;
1087 }
1088
1089 if (i != 0) { return i; }
1090 #endif
1091 return 1;
1092 }
1093
1094 /// @brief returns elem size of array
1095 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_array_elem_size(const std::string_view name) const noexcept {
1097
1098 if (arrayCount == 0) { return 0; }
1099
1100 if (arrayCount == 1) { return _variables.at(name.data()).get_size(); }
1101
1103 }
1104
1105 /// @brief returns offset of variable with given name
1106 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_offset(const std::string_view name) const noexcept {
1107 return get(name).get_offset();
1108 }
1109
1110 /// @brief returns offsets of array elements
1113
1114 if (arrayCount == 0) { return {}; }
1115
1116 if (arrayCount == 1) { return { _variables.at(name.data()).get_offset() }; }
1117
1120 for (size_t i = 0; i != arrayCount; ++i) {
1122 }
1123 return values;
1124 }
1125
1127 /// @brief returns type of variable
1129 return get(name).get_type();
1130 }
1131
1132 /// @brief returns type of variable with casting to given type (dynamic casting occurs)
1133 #if _GLSL_STRUCT_HAS_CXX20
1134 template<glsl_type Type>
1135 #else
1136 template<class Type, std::enable_if_t<is_glsl_type_v<Type>, bool> = true>
1137 #endif
1141 #endif
1142
1143 /// @brief returns total size of variable (size + padding)
1144 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_total_size(const std::string_view name) const noexcept {
1145 return get(name).get_total_size();
1146 }
1147
1148 /// @brief returns size of variable
1149 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_size(const std::string_view name) const noexcept {
1150 return get(name).get_size();
1151 }
1152
1153 /// @brief returns padding of variable
1154 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t get_padding(const std::string_view name) const noexcept {
1155 return get(name).get_padding();
1156 }
1157
1158 /// @brief returns all variables names
1162
1164 for (const auto& name : _variables | std::views::keys) { names.push_back(name); }
1165 #else
1166 for (const auto& [name, data] : _variables) { names.push_back(name); }
1167 #endif
1168
1169 return names;
1170 }
1171
1172 /// @brief returns all variables and their data
1174 return _variables;
1175 }
1176
1177 /// @brief returns all top level variables and their data
1180 for (const auto& [name, data] : _variables) {
1181 if (!data.is_top_level()) { continue; }
1183 }
1184 return variables;
1185 }
1186
1187 /// @brief returns base alignment of layout
1192
1193 /// @brief returns size of layout
1194 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t size() const noexcept { return _currentOffset; }
1195
1196 /// @brief clears layout and all variables
1198 _currentOffset = 0;
1199 _variables.clear();
1200 }
1201
1202 #pragma region ADD_SCALAR
1203 /// @brief adds scalar
1205 template<glsl_scalar S>
1206 #else
1207 template<class S, std::enable_if_t<is_glsl_scalar_v<S>, bool> = true>
1208 #endif
1209 _GLSL_STRUCT_CONSTEXPR17 size_t add(const std::string_view name) {
1211 }
1212
1213 #pragma endregion
1214
1215 #pragma region ADD_SCALARS_ARRAY
1216
1217 /// @brief adds array of scalars
1219 template<glsl_scalar S>
1220 #else
1221 template<class S, std::enable_if_t<is_glsl_scalar_v<S>, bool> = true>
1222 #endif
1226
1227 /// @brief adds array of scalars
1229 template<utils::glsl_scalars_array SA>
1230 #else
1231 template<class SA, std::enable_if_t<utils::is_glsl_scalars_array_v<SA>, bool> = true>
1232 #endif
1234 using S = utils::array_value_type_t<SA>;
1235 return add<S>(name, count);
1236 }
1237
1238 /// @brief adds array of scalars
1241 #else
1242 template<class SA, std::enable_if_t<utils::is_glsl_scalars_static_size_array_v<SA>, bool> = true>
1243 #endif
1247
1248 #pragma endregion
1249
1250 #pragma region ADD_VEC
1251 /// @brief adds vec
1253 template<glsl_vec V>
1254 #else
1255 template<class V, std::enable_if_t<is_glsl_vec_v<V>, bool> = true>
1256 #endif
1260
1261 #pragma endregion
1262
1263 #pragma region ADD_VECS_ARRAY
1264
1265 /// @brief adds array of vecs
1267 template<glsl_vec V>
1268 #else
1269 template<class V, std::enable_if_t<is_glsl_vec_v<V>, bool> = true>
1270 #endif
1274
1275 /// @brief adds array of vecs
1277 template<utils::glsl_vecs_array VA>
1278 #else
1279 template<class VA, std::enable_if_t<utils::is_glsl_vecs_array_v<VA>, bool> = true>
1280 #endif
1282 using V = utils::array_value_type_t<VA>;
1283 return add<V>(name, count);
1284 }
1285
1286 /// @brief adds array of vecs
1289 #else
1290 template<class VA, std::enable_if_t<utils::is_glsl_vecs_static_size_array_v<VA>, bool> = true>
1291 #endif
1295
1296 #pragma endregion
1297
1298 #pragma region ADD_MAT
1299 /// @brief adds mat
1301 template<glsl_mat M>
1302 #else
1303 template<class M, std::enable_if_t<is_glsl_mat_v<M>, bool> = true>
1304 #endif
1308
1309 #pragma endregion
1310
1311 #pragma region ADD_MATS_ARRAY
1312
1313 /// @brief adds array of mats
1315 template<glsl_mat M>
1316 #else
1317 template<class M, std::enable_if_t<is_glsl_mat_v<M>, bool> = true>
1318 #endif
1322
1323 /// @brief adds array of mats
1325 template<utils::glsl_mats_array MA>
1326 #else
1327 template<class MA, std::enable_if_t<utils::is_glsl_mats_array_v<MA>, bool> = true>
1328 #endif
1333
1334 /// @brief adds array of mats
1337 #else
1338 template<class MA, std::enable_if_t<utils::is_glsl_mats_static_size_array_v<MA>, bool> = true>
1339 #endif
1343
1344 #pragma endregion
1345
1346 #pragma region ADD_STRUCT
1347
1348 /// @brief adds struct with given layout
1352
1353 #pragma endregion
1354
1355 #pragma region ADD_STRUCTS_ARRAY
1356
1357 /// @brief adds array of structs with given layout
1362
1363 #pragma endregion
1364
1365 /// @brief checks equality of layouts
1369
1370 /// @brief default not equal operator
1373 = default;
1374 #else
1375 {
1376 return !(*this == other);
1377 }
1378 #endif
1379 };
1380} // namespace glslstruct
1381
1382/**
1383 * @brief std::hash overload for base_layout
1384 * @ingroup glslstruct
1385 * @tparam Traits layout traits type
1386 */
1387template<class Traits>
1388struct std::hash<glslstruct::base_layout<Traits> > {
1389 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t operator()(const glslstruct::base_layout<Traits>& layout) const noexcept {
1390 size_t seed = std::hash<size_t> {}(layout._currentOffset);
1391 if _GLSL_STRUCT_CONSTEXPR17 (layout.has_context &&
1392 glslstruct::utils::is_hashable_v<typename glslstruct::base_layout<Traits>::context_type>) {
1393 mstd::hash_append(seed, layout._context);
1394 }
1395 for (const auto& [name, data] : layout._variables) { mstd::hash_append(seed, name, data); }
1396 return seed;
1397 }
1398};
1399 #endif
1400#endif
base layout container
Definition base_layout.hpp:88
_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:1173
_GLSL_STRUCT_CONSTEXPR20 std::vector< std::string > get_names() const noexcept
returns all variables names
Definition base_layout.hpp:1159
_GLSL_STRUCT_CONSTEXPR17 size_t add(const std::string_view name)
adds scalar
Definition base_layout.hpp:1209
_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:238
_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:1072
_GLSL_STRUCT_CONSTEXPR17 void _before_add_struct()
calls before add struct event
Definition base_layout.hpp:432
_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:313
_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:1095
static _GLSL_STRUCT_CONSTEXPR17 size_t _calculate_padding(const size_t currentOffset, const size_t baseAlignment) noexcept
returns padding value
Definition base_layout.hpp:145
_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:642
_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:1106
_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:1144
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:213
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:181
_GLSL_STRUCT_CONSTEXPR17 void _before_add_scalar()
calls before add scalar event
Definition base_layout.hpp:399
_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:679
_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:91
_GLSL_STRUCT_CONSTEXPR17 void _after_add(const size_t baseOffset, const size_t baseAlignment)
calls after add event
Definition base_layout.hpp:447
_GLSL_STRUCT_CONSTEXPR20 std::vector< size_t > add(const std::string_view name, const size_t count)
adds array of scalars
Definition base_layout.hpp:1223
_GLSL_STRUCT_CONSTEXPR17 size_t _get_scalar_alignment(const ValueType valueType)
returns scalar alignment
Definition base_layout.hpp:526
_GLSL_STRUCT_CONSTEXPR17 void clear() noexcept
clears layout and all variables
Definition base_layout.hpp:1197
_GLSL_STRUCT_CONSTEXPR17 void _after_add_mat(const size_t baseOffset, const size_t baseAlignment)
calls after add mat event
Definition base_layout.hpp:490
_GLSL_STRUCT_CONSTEXPR17 void _after_add_struct(const size_t baseOffset, const size_t baseAlignment)
calls after add struct event
Definition base_layout.hpp:503
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:196
_GLSL_STRUCT_CONSTEXPR17 void _after_add_array(const size_t baseOffset, const size_t baseAlignment)
calls after add array event
Definition base_layout.hpp:457
static _GLSL_STRUCT_CONSTEXPR17 bool has_context
value indicating if traits has context defined
Definition base_layout.hpp:94
_GLSL_STRUCT_CONSTEXPR17 size_t _add_scalar(const std::string_view name, const ValueType valueType)
adds scalar
Definition base_layout.hpp:561
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:130
mstd::ordered_map< std::string, var_data > _variables
variables data
Definition base_layout.hpp:104
_GLSL_STRUCT_CONSTEXPR17 size_t _get_scalar_array_alignment(const ValueType valueType)
returns array of scalars alignment
Definition base_layout.hpp:534
_GLSL_STRUCT_CONSTEXPR17 void _after_add_vec(const size_t baseOffset, const size_t baseAlignment)
calls after add vec event
Definition base_layout.hpp:479
_GLSL_STRUCT_CONSTEXPR17 size_t get_size(const std::string_view name) const noexcept
returns size of variable
Definition base_layout.hpp:1149
_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:730
_GLSL_STRUCT_CONSTEXPR17 size_t _get_array_alignment(const size_t elemBaseAlignment)
returns array of elements alignment
Definition base_layout.hpp:518
_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:1111
_GLSL_STRUCT_CONSTEXPR17 size_t _get_mat_alignment(const ValueType valueType, const size_t rows)
returns mat alignment
Definition base_layout.hpp:552
static _GLSL_STRUCT_CONSTEXPR17 bool _is_array_count_good(const size_t count)
checks if array count is not zero
Definition base_layout.hpp:172
_GLSL_STRUCT_CONSTEXPR17 size_t _get_vec_alignment(const ValueType valueType, const size_t length)
returns vec alignment
Definition base_layout.hpp:539
_GLSL_STRUCT_CONSTEXPR17 void _before_add_vec()
calls before add vec event
Definition base_layout.hpp:410
_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:151
_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:111
_GLSL_STRUCT_CONSTEXPR17 const var_data & get(const std::string_view name) const noexcept
returns variable data
Definition base_layout.hpp:1062
_GLSL_STRUCT_CONSTEXPR17 size_t size() const noexcept
returns size of layout
Definition base_layout.hpp:1194
size_t _currentOffset
current offset
Definition base_layout.hpp:106
_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:594
static _GLSL_STRUCT_CONSTEXPR17 size_t bad_offset() noexcept
value indicating error while returning offset
Definition base_layout.hpp:1054
_GLSL_STRUCT_CONSTEXPR17 void _after_add_scalar(const size_t baseOffset, const size_t baseAlignment)
calls after add scalar event
Definition base_layout.hpp:468
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:331
_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:547
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:1178
_GLSL_STRUCT_CONSTEXPR17 size_t base_alignment() const noexcept
returns base alignment of layout
Definition base_layout.hpp:1188
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:163
_GLSL_STRUCT_CONSTEXPR17 void _before_add_mat()
calls before add mat event
Definition base_layout.hpp:421
_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:261
_GLSL_STRUCT_CONSTEXPR17 size_t get_padding(const std::string_view name) const noexcept
returns padding of variable
Definition base_layout.hpp:1154
_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:1057
_GLSL_STRUCT_CONSTEXPR17 void _before_add_array()
calls before add array event
Definition base_layout.hpp:388
_GLSL_STRUCT_CONSTEXPR17 void _before_add()
calls before add event
Definition base_layout.hpp:378
#define _GLSL_STRUCT_TYPENAME17
Definition config.hpp:216
#define _GLSL_STRUCT_EXPORT
This is for exporting symbols in shared library setup.
Definition config.hpp:251
#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 contexts.hpp:20
Context container for layout.
Definition base_layout.hpp:46
_GLSL_STRUCT_CONSTEXPR17 layout_with_context(const context_type &ctx)
constructor with context value
Definition base_layout.hpp:67
context_type _context
context value
Definition base_layout.hpp:52
_GLSL_STRUCT_CONSTEXPR17 layout_with_context() noexcept _GLSL_STRUCT_REQUIRES(std
default constructor
Definition base_layout.hpp:60
_GLSL_STRUCT_TYPENAME17 Traits::context_type context_type
context type
Definition base_layout.hpp:48
empty container for layout
Definition base_layout.hpp:74