GLSL Struct 1.4.0
glslstruct
Loading...
Searching...
No Matches
base_struct.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_STRUCT_HPP_
12 #define _GLSL_STRUCT_BASE_STRUCT_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/layout/base_layout.hpp>
21 #include <glslstruct/value/glsl_value.hpp>
22
23namespace glslstruct {
24 /**
25 * @ingroup glslstruct
26 * @brief base class for glsl struct representation
27 * @tparam Layout struct layout
28 */
30 template<utils::glsl_layout Layout>
31 #else
32 template<class Layout, std::enable_if_t<utils::is_glsl_layout_v<Layout>, bool> >
33 #endif
35 public:
36 /// @brief struct layout type
38
39 private:
40 friend struct std::hash<base_struct>;
41
42 /// @brief check if type is simple glsl type or struct with given layout
43 template<class T>
45
46 /// @brief struct layout
48 /// @brief struct data
50
52 #pragma region TYPE_CHECKS
53
54 [[nodiscard]] static bool _is_scalar(const base_type_handle& varType, const ValueType type) {
55 if (!is_of_type<scalar_type>(varType)) { return false; }
57 }
58
59 [[nodiscard]] static bool _is_vec(const base_type_handle& varType, const ValueType type, const size_t length) {
60 if (!is_of_type<vec_type>(varType)) { return false; }
61
63 return type == vecVarType->get_type() && length == vecVarType->get_length();
64 }
65
66 [[nodiscard]] static bool _is_mat(const base_type_handle& varType, const ValueType type, const size_t columns,
67 const size_t rows) {
68 if (!is_of_type<mat_type>(varType)) { return false; }
69
72 }
73
79
81
82 [[nodiscard]] bool _scalar_check(const std::string_view name, const ValueType type) const {
84 return _is_scalar(varType, type);
85 }
86
89 if (!_is_array(varType)) { return false; }
91 }
92
93 [[nodiscard]] bool _vec_check(const std::string_view name, const ValueType type, const size_t length) const {
95 return _is_vec(varType, type, length);
96 }
97
98 [[nodiscard]] bool _vec_array_check(const std::string_view name, const ValueType type, const size_t length) const {
100 if (!_is_array(varType)) { return false; }
102 }
103
105 const size_t rows) const {
107 return _is_mat(varType, type, columns, rows);
108 }
109
111 const size_t rows) const {
113 if (!_is_array(varType)) { return false; }
115 }
116
122
129
130 #pragma endregion
131 #endif
132
133 #pragma region GET_VALUE_DATA
134
135 /// @brief returns scalar data bytes
136 template<class T>
140
141 /// @brief returns vec data bytes
142 template<class T>
146
147 /// @brief returns mat data bytes
148 template<class T>
151
154
155 for (size_t i = 0; i != vecsData.size(); ++i) { data.push_back(vecsData[i].data()); }
156
157 return data;
158 }
159
160 #pragma endregion
161
162 #pragma region GET_VALUE_FROM_DATA
163
164 /// @brief returns scalar value from data bytes
165 template<class T>
169
170 /// @brief returns vec value from data bytes
171 template<class T>
175
176 /// @brief returns mat value from data bytes
177 template<class T>
185
186 #pragma endregion
187
188 #pragma region ADD
189
190 /// @brief adds value data to given offset
192 const size_t dataSize) {
193 // CHECK ERROR
194 if (valueOffset == bad_offset()) { return valueOffset; }
195
196 // RESIZE DATA
197 if (_layout.size() > _data.size()) { _data.resize(_layout.size()); }
198
199 // SET VALUE DATA
201
202 return valueOffset;
203 }
204
205 /// @brief adds array values to given offsets
207 const std::vector<std::byte>* valuesData) {
208 // CHECK ERROR
209 if (valuesOffsets.empty()) { return valuesOffsets; }
210
211 // RESIZE DATA
213
214 // SET VALUES DATA
215 for (size_t i = 0; i < valuesOffsets.size(); ++i) {
216 // SET VALUE DATA
219 #else
221 #endif
222 }
223
224 return valuesOffsets;
225 }
226
227 /// @brief adds scalar
228 template<class T>
236
237 /// @brief adds scalars array
238 template<class T>
250
251 /// @brief adds vec
252 template<class V>
254 const size_t valueOffset = _layout.template add<V>(name);
255
257
258 return _add(valueOffset, data.data(), data.size());
259 }
260
261 /// @brief adds vecs array
262 template<class V>
274
275 /// @brief adds mat
276 template<class M>
284
285 /// @brief adds mats array
286 template<class M>
301
302 /// @brief adds struct
313
314 /// @brief adds structs array
319
320 /// @brief adds multiple values
321 template<class T, class... Ts, size_t Num, size_t... Nums>
323 using ValueType = glsl_value<T, Num>;
324
327 else { add(value.varName, value.value); }
328 }
329 else { add(value.varName, value.value); }
330
331
332 if _GLSL_STRUCT_CONSTEXPR17 (sizeof...(Ts) > 0 && sizeof...(Nums) > 0) { _add_values(values...); }
333 }
334
335 #pragma endregion
336
337 #pragma region SET
338
339 /// @brief sets value data at given offset
341 const size_t dataSize) {
342 if (valueOffset == bad_offset()) { return false; }
343
344 // SET VALUE DATA
346
347 return true;
348 }
349
350 /// @brief sets array values data at given offsets
352 const std::vector<std::byte>* valuesData, const size_t valuesCount) {
353 if (valuesOffsets.empty()) { return false; }
354
355 // SET VALUES DATA
356 for (size_t i = 0; i < std::min(valuesOffsets.size(), valuesCount); ++i) {
358
359 // SET VALUE DATA
361 }
362
363 return true;
364 }
365
366 /// @brief sets scalar
367 template<class T>
371 "Type mismatch! (If you don't want to see this error disable type checks)");
372 #endif
373
375
377
379 }
380
381 /// @brief sets scalar array
382 template<class T>
384 const size_t valuesCount) {
387 "Type mismatch! (If you don't want to see this error disable type checks)");
388 #endif
389
391
394
395 for (size_t i = 0; i < std::min(valuesCount, valuesOffsets.size()); ++i) {
397 }
398
400 }
401
402 /// @brief sets vec
403 template<class V>
407 "Type mismatch! (If you don't want to see this error disable type checks)");
408 #endif
409
411
413
414 return _set(valueOffset, data.data(), data.size());
415 }
416
417 /// @brief sets vec array
418 template<class V>
420 const size_t valuesCount) {
423 "Type mismatch! (If you don't want to see this error disable type checks)");
424 #endif
425
427
430
431 for (size_t i = 0; i < std::min(valuesCount, valuesOffsets.size()); ++i) {
433 }
434
436 }
437
438 /// @brief sets mat
439 template<class M>
443 "Type mismatch! (If you don't want to see this error disable type checks)");
444 #endif
445
447
449
451 }
452
453 /// @brief sets mat array
454 template<class M>
456 const size_t valuesCount) {
459 "Type mismatch! (If you don't want to see this error disable type checks)");
460 #endif
461
463
464 for (size_t m = 0; m < count; ++m) {
466
468
470
471 if (!_set_array(valuesOffsets, valuesData.data(), valuesData.size())) { return false; }
472 }
473
474 return true;
475 }
476
477 /// @brief sets struct
479 [[maybe_unused]] const layout_type& layout, const std::byte* data, const size_t bytesCount) {
482 "Type mismatch! (If you don't want to see this error disable type checks)");
483 #endif
485 }
486
487 /// @brief sets struct array
489 [[maybe_unused]] const layout_type& layout, const std::vector<std::byte>* values, const size_t valuesCount) {
492 "Type mismatch! (If you don't want to see this error disable type checks)");
493 #endif
495 }
496
497 #pragma endregion
498
499 #pragma region GET
500
501 /// @brief returns value data at given offset with given size
512
513 /// @brief returns array values data at given offsets with given value size
516 ) const {
517 // GET ARRAY ELEM DATA MAX SIZE
519
520 // GET VALUES DATA
523
526
527 size_t maxSize = 0;
528 for (size_t i = 0; i < valuesOffsets.size(); ++i) {
529 // GET MAX VALUE SIZE
531
532 // GET VALUE DATA
534
535 // CHECK VALUE DATA SIZE
536 if (maxSize < valueSize) {
537 std::fill_n(std::next(valueData.begin(), maxSize), valueSize - maxSize, static_cast<std::byte>(0));
538 }
539
540 // GET VALUE
542 }
543
544 // CLEAR TEMP VALUE DATA
546
547 // RETURN VALUES
548 return values;
549 }
550
551 /// @brief gets scalar value
552 template<class T>
556 "Type mismatch! (If you don't want to see this error disable type checks)");
557 #endif
559 }
560
561 /// @brief gets scalars array value
562 template<class T>
566 "Type mismatch! (If you don't want to see this error disable type checks)");
567 #endif
568
570
571 const std::vector<std::vector<std::byte> > valuesData =
573
574 std::vector<T> values;
576
578
579 return values;
580 }
581
582 /// @brief gets vec value
583 template<class V>
587 "Type mismatch! (If you don't want to see this error disable type checks)");
588 #endif
590 }
591
592 /// @brief gets vec array value
593 template<class V>
597 "Type mismatch! (If you don't want to see this error disable type checks)");
598 #endif
599
601
602 const std::vector<std::vector<std::byte> > valuesData =
604
605 std::vector<V> values;
608
609 return values;
610 }
611
612 /// @brief gets mat value
613 template<class M>
617 "Type mismatch! (If you don't want to see this error disable type checks)");
618 #endif
621 }
622
623 /// @brief gets mat array value
624 template<class M>
628 "Type mismatch! (If you don't want to see this error disable type checks)");
629 #endif
630
632
633 std::vector<M> values;
635
636 for (size_t m = 0; m < matsCount; ++m) {
638
640
641 const std::vector<std::vector<std::byte> > valuesData =
643
645 }
646
647 return values;
648 }
649
650 /// @brief gets struct value
652 const layout_type& layout) const {
655 "Type mismatch! (If you don't want to see this error disable type checks)");
656 #endif
658 }
659
660 /// @brief gets struct array value
662 const layout_type& layout) const {
665 "Type mismatch! (If you don't want to see this error disable type checks)");
666 #endif
667
669
670 const std::vector<std::vector<std::byte> > valuesData =
672
675
676 for (size_t i = 0; i < valuesOffsets.size(); ++i) { values.emplace_back(layout, valuesData[i]); }
677
678 return values;
679 }
680
681 #pragma endregion
682
683 public:
684 #pragma region CONSTRUCTORS
685 /// @brief default constructor
687 template<class T = layout_type,
689 #endif
690 _GLSL_STRUCT_CONSTEXPR20 base_struct() noexcept _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<layout_type>)
691 : _layout() {
692 }
693
694 /// @brief constructor with context
696 template<class T = layout_type, std::enable_if_t<std::is_same_v<T, layout_type> && layout_type::has_context, bool> = true>
697 #endif
700 ) noexcept _GLSL_STRUCT_REQUIRES(layout_type::has_context)
701 : _layout(ctx) {
702 }
703
704 /// @brief constructor with layout
706 : _layout(layout), _data(_layout.size(), static_cast<std::byte>(0)) {}
707
708 /// @brief constructor with layout and data
710 : _layout(layout), _data(data) {
711 _data.resize(_layout.size(), static_cast<std::byte>(0));
712 }
713
714 /// @brief constructor with multiple values
718 #else
719 template<class... Args, size_t... Nums,
721 #endif
723 const glsl_value<Args, Nums>&... values
724 ) noexcept _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<layout_type>) {
726 }
727
728 /// @brief constructor with multiple values and context
731 std::enable_if_t<layout_type::has_context, bool> = true>
732 #else
733 template<class... Args, size_t... Nums,
735 #endif
737 const _GLSL_STRUCT_TYPENAME17 layout_type::context_type& ctx) noexcept _GLSL_STRUCT_REQUIRES(layout_type::has_context)
738 : _layout(ctx) {
740 }
741
742 /// @brief default copy constructor
744
745 /// @brief move constructor
748
749 #pragma endregion
750
751 /// @brief default destructor
753
754 /// @brief default copy assign operator
756
757 /// @brief move assign operator
760 _data = std::exchange(other._data, {});
761 return *this;
762 }
763
764 /// @brief invalid offset value returned when there is error
766
767 #pragma region ADD
768 #pragma region ADD_SCALAR
769 /// @brief adds scalar with default value and returns offset
771 template<utils::glsl_scalar S>
772 #else
773 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S> && std::is_default_constructible_v<S>, bool> = true>
774 #endif
776 const std::string_view name
777 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<S>) {
778 return _add_scalar(name, S());
779 }
780
781 /// @brief adds scalar and returns offset
783 template<utils::glsl_scalar S>
784 #else
785 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S>, bool> = true>
786 #endif
790
791 #pragma endregion
792
793 #pragma region ADD_SCALARS_ARRAYS
794 /// @brief adds array of scalars with pointer to values and size
796 template<utils::glsl_scalar S>
797 #else
798 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S>, bool> = true>
799 #endif
803
804 /// @brief adds array of scalars
806 template<utils::glsl_scalars_array SA>
807 #else
808 template<class SA,
810 bool> = true>
811 #endif
813 const size_t count) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<SA> >) {
814 using S = utils::array_value_type_t<SA>;
816 const std::vector<uint8_t> values(count, S());
817 return _add_scalar_array<bool>(name, reinterpret_cast<const bool*>(values.data()), values.size());
818 }
819 else {
820 const std::vector<S> values(count, S());
822 }
823 }
824
825 /// @brief adds array of scalars
828 #else
831 bool> = true>
832 #endif
834 const std::string_view name
835 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<SA> >) {
837 }
838
839 /// @brief adds array of scalars
841 template<utils::glsl_scalars_array SA>
842 #else
843 template<class SA, std::enable_if_t<utils::is_glsl_scalars_array_v<SA>, bool> = true>
844 #endif
848
849 #pragma endregion
850
851 #pragma region ADD_VEC
852 /// @brief adds default vec and returns offset
854 template<utils::glsl_vec V>
855 #else
856 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V> && std::is_default_constructible_v<V>, bool> = true>
857 #endif
859 const std::string_view name
860 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<V>) {
861 return _add_vec(name, V());
862 }
863
864 /// @brief adds vec and returns offset
866 template<utils::glsl_vec V>
867 #else
868 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
869 #endif
873
874 #pragma endregion
875
876 #pragma region ADD_VEC_ARRAYS
877 /// @brief adds array of vecs using pointer to values and size
879 template<utils::glsl_vec V>
880 #else
881 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
882 #endif
886
887 /// @brief adds array of default vecs
889 template<utils::glsl_vecs_array VA>
890 #else
891 template<class VA,
893 bool> = true>
894 #endif
896 const size_t count) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<VA> >) {
897 using V = utils::array_value_type_t<VA>;
898 const std::vector<V> values(count, V());
900 }
901
902 /// @brief adds array of default vecs
905 #else
908 bool> = true>
909 #endif
911 const std::string_view name
912 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<VA> >) {
914 }
915
916 /// @brief adds array of vecs
918 template<utils::glsl_vecs_array VA>
919 #else
920 template<class VA, std::enable_if_t<utils::is_glsl_vecs_array_v<VA>, bool> = true>
921 #endif
925
926 #pragma endregion
927
928 #pragma region ADD_MAT
929 /// @brief adds default mat and returns offset
931 template<utils::glsl_mat M>
932 #else
933 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M> && std::is_default_constructible_v<M>, bool> = true>
934 #endif
936 const std::string_view name
937 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<M>) {
938 return _add_mat(name, M());
939 }
940
941 /// @brief adds mat and returns offset
943 template<utils::glsl_mat M>
944 #else
945 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
946 #endif
950
951 #pragma endregion
952
953 #pragma region ADD_MAT_ARRAYS
954 /// @brief adds array of mats with pointer to values and size
956 template<utils::glsl_mat M>
957 #else
958 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
959 #endif
963
964 /// @brief adds array of default mats
966 template<utils::glsl_mats_array MA>
967 #else
968 template<class MA,
970 bool> = true>
971 #endif
973 const size_t count) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<MA> >) {
974 using M = utils::array_value_type_t<MA>;
975 const std::vector<M> values(count, M());
977 }
978
979 /// @brief adds array of default mats
982 #else
985 bool> = true>
986 #endif
988 const std::string_view name
989 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<MA> >) {
991 }
992
993 /// @brief adds array of mats
995 template<utils::glsl_mats_array MA>
996 #else
997 template<class MA, std::enable_if_t<utils::is_glsl_mats_array_v<MA>, bool> = true>
998 #endif
1002
1003 #pragma endregion
1004
1005 #pragma region ADD_STRUCT
1006
1007 /// @brief adds struct
1011
1012 /// @brief adds struct based on layout
1017
1018 /// @brief adds struct based on layout and pointer to data in bytes
1023
1024 /// @brief adds struct based on layout and array of data in bytes
1025 template<class BA, std::enable_if_t<utils::is_array_of_v<std::is_same, BA, std::byte>, bool> = true>
1029
1030 #pragma endregion
1031
1032 #pragma region ADD_STRUCT_ARRAYS
1033
1034 /// @brief adds array of structs based on layout and pointer to data in bytes
1039
1040 /// @brief adds array of structs based on layout and array of data in bytes
1046
1047 /// @brief adds array of structs based on layout and array of data in bytes
1048 template<class SBA, std::enable_if_t<utils::is_array_of_v<std::is_same, SBA, std::vector<std::byte> >, bool> = true>
1053
1054 #pragma endregion
1055 #pragma endregion
1056
1057 #pragma region SET
1058 #pragma region SET_SCALAR
1059 /// @brief sets default scalar value
1061 template<utils::glsl_scalar S>
1062 #else
1063 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S> && std::is_default_constructible_v<S>, bool> = true>
1064 #endif
1065 _GLSL_STRUCT_CONSTEXPR20 bool set(const std::string_view name) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<S>) {
1066 return _set_scalar(name, S());
1067 }
1068
1069 /// @brief sets scalar value
1071 template<utils::glsl_scalar S>
1072 #else
1073 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S>, bool> = true>
1074 #endif
1076 return _set_scalar(name, value);
1077 }
1078
1079 #pragma endregion
1080
1081 #pragma region SET_SCALARS_ARRAYS
1082 /// @brief sets scalar array value using pointer to values
1084 template<utils::glsl_scalar S>
1085 #else
1086 template<class S, std::enable_if_t<utils::is_glsl_scalar_v<S>, bool> = true>
1087 #endif
1091
1092 /// @brief sets scalar array value with array of default values
1094 template<utils::glsl_scalars_array SA>
1095 #else
1096 template<class SA,
1098 bool> = true>
1099 #endif
1101 const size_t count) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<SA> >) {
1102 using S = utils::array_value_type_t<SA>;
1103 const std::vector<S> values(count, S());
1105 }
1106
1107 /// @brief sets scalar array value with array of default values
1110 #else
1113 bool> = true>
1114 #endif
1116 const std::string_view name
1117 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<SA> >) {
1118 return set<SA>(name, utils::array_static_size_v<SA>);
1119 }
1120
1121 /// @brief sets scalar array value with array of values
1123 template<utils::glsl_scalars_array SA>
1124 #else
1125 template<class SA, std::enable_if_t<utils::is_glsl_scalars_array_v<SA>, bool> = true>
1126 #endif
1130
1131 #pragma endregion
1132
1133 #pragma region SET_VEC
1134 /// @brief sets vec default value
1136 template<utils::glsl_vec V>
1137 #else
1138 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V> && std::is_default_constructible_v<V>, bool> = true>
1139 #endif
1140 _GLSL_STRUCT_CONSTEXPR17 bool set(const std::string_view name) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<V>) {
1141 return _set_vec(name, V());
1142 }
1143
1144 /// @brief sets vec value
1146 template<utils::glsl_vec V>
1147 #else
1148 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
1149 #endif
1151 return _set_vec(name, value);
1152 }
1153
1154 #pragma endregion
1155
1156 #pragma region SET_VEC_ARRAYS
1157 /// @brief sets vec array value using pointer to values
1159 template<utils::glsl_vec V>
1160 #else
1161 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
1162 #endif
1164 return _set_vec_array(name, values, size);
1165 }
1166
1167 /// @brief sets vec array value with array of default values
1169 template<utils::glsl_vecs_array VA>
1170 #else
1171 template<class VA,
1173 bool> = true>
1174 #endif
1176 const size_t count) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<VA> >) {
1177 using V = utils::array_value_type_t<VA>;
1178 const std::vector<V> values(count, V());
1179 return _set_vec_array(name, values.data(), values.size());
1180 }
1181
1182 /// @brief sets vec array value with array of default values
1185 #else
1188 bool> = true>
1189 #endif
1191 const std::string_view name
1192 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<VA> >) {
1193 return set<VA>(name, utils::array_static_size_v<VA>);
1194 }
1195
1196 /// @brief sets vec array value with array of values
1198 template<utils::glsl_vecs_array VA>
1199 #else
1200 template<class VA, std::enable_if_t<utils::is_glsl_vecs_array_v<VA>, bool> = true>
1201 #endif
1205
1206 #pragma endregion
1207
1208 #pragma region SET_MAT
1209 /// @brief sets default mat value
1211 template<utils::glsl_mat M>
1212 #else
1213 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M> && std::is_default_constructible_v<M>, bool> = true>
1214 #endif
1215 _GLSL_STRUCT_CONSTEXPR20 bool set(const std::string_view name) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<M>) {
1216 return _set_mat(name, M());
1217 }
1218
1219 /// @brief sets mat value
1221 template<utils::glsl_mat M>
1222 #else
1223 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
1224 #endif
1226 return _set_mat(name, value);
1227 }
1228
1229 #pragma endregion
1230
1231 #pragma region SET_MAT_ARRAYS
1232 /// @brief sets mat array value using pointer to values
1234 template<utils::glsl_mat M>
1235 #else
1236 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
1237 #endif
1241
1242 /// @brief sets mat array value with array of default values
1244 template<utils::glsl_mats_array MA>
1245 #else
1246 template<class MA,
1248 bool> = true>
1249 #endif
1251 const size_t count) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<MA> >) {
1252 using M = utils::array_value_type_t<MA>;
1253 const std::vector<M> values(count, M());
1254 return _set_mat_array(name, values.data(), values.size());
1255 }
1256
1257 /// @brief sets mat array value with array of default values
1260 #else
1263 bool> = true>
1264 #endif
1266 const std::string_view name
1267 ) _GLSL_STRUCT_REQUIRES(std::is_default_constructible_v<utils::array_value_type_t<MA> >) {
1268 return set<MA>(name, utils::array_static_size_v<MA>);
1269 }
1270
1271 /// @brief sets mat array value with array of values
1273 template<utils::glsl_mats_array MA>
1274 #else
1275 template<class MA, std::enable_if_t<utils::is_glsl_mats_array_v<MA>, bool> = true>
1276 #endif
1280
1281 #pragma endregion
1282
1283 #pragma region SET_STRUCT
1284
1285 /// @brief sets struct value
1289
1290 /// @brief sets empty struct
1292 const std::vector<std::byte> data(layout.size(), std::byte {});
1293 return _set_struct(name, layout, data.data(), data.size());
1294 }
1295
1296 /// @brief sets struct value using pointer to data
1298 const size_t bytesCount) {
1300 }
1301
1302 /// @brief sets struct value using array of data bytes
1303 template<class BA, std::enable_if_t<utils::is_array_of_v<std::is_same, BA, std::byte>, bool> = true>
1307
1308 #pragma endregion
1309
1310 #pragma region SET_STRUCT_ARRAYS
1311
1312 /// @brief sets mat array value with pointer to values
1317
1318 /// @brief sets mat array value using array of datas
1319 template<class SBA, std::enable_if_t<utils::is_array_of_v<std::is_same, SBA, std::vector<std::byte> >, bool> = true>
1324
1325 /// @brief sets mat array value using array of datas
1326 template<class SBA, std::enable_if_t<utils::is_array_of_v<std::is_same, SBA, std::vector<std::byte> >, bool> = true>
1330
1331 #pragma endregion
1332 #pragma endregion
1333
1334 #pragma region GET
1335 #pragma region GET_SCALARS
1336 /// @brief gets scalar value
1338 template<utils::glsl_scalar T>
1339 #else
1340 template<class T, std::enable_if_t<utils::is_glsl_scalar_v<T>, bool> = true>
1341 #endif
1343 return _get_scalar<T>(name);
1344 }
1345
1346 #pragma endregion
1347
1348 #pragma region GET_SCALARS_ARRAYS
1349 /// @brief copies scalars array value to provided pointer
1351 template<utils::glsl_scalar T>
1352 #else
1353 template<class T, std::enable_if_t<utils::is_glsl_scalar_v<T>, bool> = true>
1354 #endif
1359
1360 /// @brief gets scalars array value as std::vector
1362 template<utils::glsl_scalars_array SA>
1363 #else
1364 template<class SA, std::enable_if_t<utils::is_glsl_scalars_array_v<SA>, bool> = true>
1365 #endif
1371
1372 #pragma endregion
1373
1374 #pragma region GET_VEC
1375 /// @brief gets vec value
1377 template<utils::glsl_vec V>
1378 #else
1379 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
1380 #endif
1382 return _get_vec<V>(name);
1383 }
1384
1385 #pragma endregion
1386
1387 #pragma region GET_VEC_ARRAYS
1388 /// @brief copies vecs array value to provided pointer
1390 template<utils::glsl_vec V>
1391 #else
1392 template<class V, std::enable_if_t<utils::is_glsl_vec_v<V>, bool> = true>
1393 #endif
1398
1399 /// @brief gets vecs array value as std::vector
1401 template<utils::glsl_vecs_array VA>
1402 #else
1403 template<class VA, std::enable_if_t<utils::is_glsl_vecs_array_v<VA>, bool> = true>
1404 #endif
1410
1411 #pragma endregion
1412
1413 #pragma region GET_MAT
1414 /// @brief gets mat value
1416 template<utils::glsl_mat M>
1417 #else
1418 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
1419 #endif
1421 return _get_mat<M>(name);
1422 }
1423
1424 #pragma endregion
1425
1426 #pragma region GET_MAT_ARRAYS
1427 /// @brief copies mats array value to provided pointer
1429 template<utils::glsl_mat M>
1430 #else
1431 template<class M, std::enable_if_t<utils::is_glsl_mat_v<M>, bool> = true>
1432 #endif
1437
1438 /// @brief gets mats array value as std::vector
1440 template<utils::glsl_mats_array MA>
1441 #else
1442 template<class MA, std::enable_if_t<utils::is_glsl_mats_array_v<MA>, bool> = true>
1443 #endif
1449
1450 #pragma endregion
1451
1452 #pragma region GET_STRUCT
1453 /// @brief gets struct value
1456 #else
1457 template<class S, std::enable_if_t<utils::is_glsl_layout_struct_v<S, layout_type>, bool> = true>
1458 #endif
1462
1463 #pragma endregion
1464
1465 #pragma region GET_STRUCT_ARRAYS
1466
1467 /// @brief copies struct array value to provided pointer
1473
1474 /// @brief gets struct array value as std::vector
1477 #else
1478 template<class LSA, std::enable_if_t<utils::is_glsl_layout_structs_array_v<LSA, layout_type>, bool> = true>
1479 #endif
1484
1485 #pragma endregion
1486 #pragma endregion
1487
1488 /// @brief returns struct layout
1489 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 const layout_type& get_layout() const noexcept { return _layout; }
1490
1491 /// @brief returns true if struct contains variable with given name
1493
1494 /// @brief returns offset of variable
1498
1499 /// @brief returns offsets of elements of array
1503
1505 /// @brief returns type of variable
1509
1510 /// @brief returns type of variable casted to desired type (using dynamic_type_cast)
1511 #if _GLSL_STRUCT_HAS_CXX20
1512 template<utils::glsl_type T>
1513 #else
1514 template<class T, std::enable_if_t<utils::is_glsl_type_v<T>, bool> = true>
1515 #endif
1517 return _layout.template get_type<T>(name);
1518 }
1519 #endif
1520
1521 /// @brief returns total size of variable (size + padding)
1525
1526 /// @brief returns size of variable
1528 return _layout.get_size(name);
1529 }
1530
1531 /// @brief returns variable padding
1535
1536 /// @brief returns names of all variables
1538
1539 /// @brief returns all variables and their data
1543
1544 /// @brief returns all top level variables and their data
1548
1549 /// @brief returns struct data in bytes
1550 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 const std::vector<std::byte>& data() const noexcept { return _data; }
1551
1552 /// @brief returns base alignment of struct
1554
1555 /// @brief returns size of struct data
1556 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 size_t size() const noexcept { return _data.size(); }
1557
1558 /// @brief returns struct padding
1560
1561 /// @brief resets data to all zeros
1564 std::ranges::fill(_data, static_cast<std::byte>(0));
1565 #else
1566 std::fill(_data.begin(), _data.end(), static_cast<std::byte>(0));
1567 #endif
1568 }
1569
1570 /// @brief clears layout and data
1572 _layout.clear();
1573 _data.clear();
1574 }
1575
1576 /// @brief checks if two structs are equal
1578 return _layout == other._layout && _data == other._data;
1579 }
1580
1581 /// @brief default not equal operator
1584 #else
1585 [[nodiscard]] _GLSL_STRUCT_CONSTEXPR17 bool operator!=(const base_struct& other) const { return !(*this == other); }
1586 #endif
1587 };
1588} // namespace glslstruct
1589
1590/**
1591 * @brief std::hash overload for base_struct
1592 * @tparam Layout layout of struct
1593 * @ingroup glslstruct
1594 */
1595template<class Layout>
1596struct std::hash<glslstruct::base_struct<Layout> > {
1597 size_t operator()(const glslstruct::base_struct<Layout>& glslStruct) {
1598 size_t seed = 0;
1599 mstd::hash_append(seed, glslStruct._layout);
1600 mstd::hash_range(seed, glslStruct._data.begin(), glslStruct._data.end());
1601 return seed;
1602 }
1603};
1604
1605 #endif
1606#endif
#define _GLSL_STRUCT_TYPENAME17
Definition config.hpp:216
#define _GLSL_STRUCT_HAS_TYPE_CHECKS
check if user enabled type checks for struct getters using GLSL_STRUCT_ENABLE_TYPE_CHECKS (remember i...
Definition config.hpp:173
#define _GLSL_STRUCT_CONSTEXPR20
constexpr keyword for c++20 and higher
Definition config.hpp:213
#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
Main namespace of glslstruct library.
Definition scalar_layout_traits.hpp:23