gstaichi 2.1.1rc3__cp312-cp312-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. gstaichi/CHANGELOG.md +4 -0
  2. gstaichi/__init__.py +40 -0
  3. gstaichi/_funcs.py +706 -0
  4. gstaichi/_kernels.py +420 -0
  5. gstaichi/_lib/__init__.py +3 -0
  6. gstaichi/_lib/core/__init__.py +0 -0
  7. gstaichi/_lib/core/gstaichi_python.cpython-312-darwin.so +0 -0
  8. gstaichi/_lib/core/gstaichi_python.pyi +2909 -0
  9. gstaichi/_lib/core/py.typed +0 -0
  10. gstaichi/_lib/runtime/libMoltenVK.dylib +0 -0
  11. gstaichi/_lib/runtime/runtime_arm64.bc +0 -0
  12. gstaichi/_lib/utils.py +243 -0
  13. gstaichi/_logging.py +131 -0
  14. gstaichi/_snode/__init__.py +5 -0
  15. gstaichi/_snode/fields_builder.py +187 -0
  16. gstaichi/_snode/snode_tree.py +34 -0
  17. gstaichi/_test_tools/__init__.py +18 -0
  18. gstaichi/_test_tools/dataclass_test_tools.py +36 -0
  19. gstaichi/_test_tools/load_kernel_string.py +30 -0
  20. gstaichi/_test_tools/textwrap2.py +6 -0
  21. gstaichi/_version.py +1 -0
  22. gstaichi/_version_check.py +100 -0
  23. gstaichi/ad/__init__.py +3 -0
  24. gstaichi/ad/_ad.py +530 -0
  25. gstaichi/algorithms/__init__.py +3 -0
  26. gstaichi/algorithms/_algorithms.py +117 -0
  27. gstaichi/assets/.git +1 -0
  28. gstaichi/assets/Go-Regular.ttf +0 -0
  29. gstaichi/assets/static/imgs/ti_gallery.png +0 -0
  30. gstaichi/examples/lcg_python.py +26 -0
  31. gstaichi/examples/lcg_taichi.py +34 -0
  32. gstaichi/examples/minimal.py +28 -0
  33. gstaichi/experimental.py +16 -0
  34. gstaichi/lang/__init__.py +50 -0
  35. gstaichi/lang/_dataclass_util.py +31 -0
  36. gstaichi/lang/_fast_caching/__init__.py +3 -0
  37. gstaichi/lang/_fast_caching/args_hasher.py +110 -0
  38. gstaichi/lang/_fast_caching/config_hasher.py +30 -0
  39. gstaichi/lang/_fast_caching/fast_caching_types.py +21 -0
  40. gstaichi/lang/_fast_caching/function_hasher.py +57 -0
  41. gstaichi/lang/_fast_caching/hash_utils.py +11 -0
  42. gstaichi/lang/_fast_caching/python_side_cache.py +52 -0
  43. gstaichi/lang/_fast_caching/src_hasher.py +75 -0
  44. gstaichi/lang/_kernel_impl_dataclass.py +212 -0
  45. gstaichi/lang/_ndarray.py +352 -0
  46. gstaichi/lang/_ndrange.py +152 -0
  47. gstaichi/lang/_template_mapper.py +195 -0
  48. gstaichi/lang/_texture.py +172 -0
  49. gstaichi/lang/_wrap_inspect.py +215 -0
  50. gstaichi/lang/any_array.py +99 -0
  51. gstaichi/lang/ast/__init__.py +5 -0
  52. gstaichi/lang/ast/ast_transformer.py +1323 -0
  53. gstaichi/lang/ast/ast_transformer_utils.py +346 -0
  54. gstaichi/lang/ast/ast_transformers/__init__.py +0 -0
  55. gstaichi/lang/ast/ast_transformers/call_transformer.py +324 -0
  56. gstaichi/lang/ast/ast_transformers/function_def_transformer.py +304 -0
  57. gstaichi/lang/ast/checkers.py +106 -0
  58. gstaichi/lang/ast/symbol_resolver.py +57 -0
  59. gstaichi/lang/ast/transform.py +9 -0
  60. gstaichi/lang/common_ops.py +310 -0
  61. gstaichi/lang/exception.py +80 -0
  62. gstaichi/lang/expr.py +180 -0
  63. gstaichi/lang/field.py +428 -0
  64. gstaichi/lang/impl.py +1243 -0
  65. gstaichi/lang/kernel_arguments.py +155 -0
  66. gstaichi/lang/kernel_impl.py +1341 -0
  67. gstaichi/lang/matrix.py +1835 -0
  68. gstaichi/lang/matrix_ops.py +341 -0
  69. gstaichi/lang/matrix_ops_utils.py +190 -0
  70. gstaichi/lang/mesh.py +687 -0
  71. gstaichi/lang/misc.py +782 -0
  72. gstaichi/lang/ops.py +1494 -0
  73. gstaichi/lang/runtime_ops.py +13 -0
  74. gstaichi/lang/shell.py +35 -0
  75. gstaichi/lang/simt/__init__.py +5 -0
  76. gstaichi/lang/simt/block.py +94 -0
  77. gstaichi/lang/simt/grid.py +7 -0
  78. gstaichi/lang/simt/subgroup.py +191 -0
  79. gstaichi/lang/simt/warp.py +96 -0
  80. gstaichi/lang/snode.py +489 -0
  81. gstaichi/lang/source_builder.py +150 -0
  82. gstaichi/lang/struct.py +810 -0
  83. gstaichi/lang/util.py +312 -0
  84. gstaichi/linalg/__init__.py +8 -0
  85. gstaichi/linalg/matrixfree_cg.py +310 -0
  86. gstaichi/linalg/sparse_cg.py +59 -0
  87. gstaichi/linalg/sparse_matrix.py +303 -0
  88. gstaichi/linalg/sparse_solver.py +123 -0
  89. gstaichi/math/__init__.py +11 -0
  90. gstaichi/math/_complex.py +205 -0
  91. gstaichi/math/mathimpl.py +886 -0
  92. gstaichi/profiler/__init__.py +6 -0
  93. gstaichi/profiler/kernel_metrics.py +260 -0
  94. gstaichi/profiler/kernel_profiler.py +586 -0
  95. gstaichi/profiler/memory_profiler.py +15 -0
  96. gstaichi/profiler/scoped_profiler.py +36 -0
  97. gstaichi/sparse/__init__.py +3 -0
  98. gstaichi/sparse/_sparse_grid.py +77 -0
  99. gstaichi/tools/__init__.py +12 -0
  100. gstaichi/tools/diagnose.py +117 -0
  101. gstaichi/tools/np2ply.py +364 -0
  102. gstaichi/tools/vtk.py +38 -0
  103. gstaichi/types/__init__.py +19 -0
  104. gstaichi/types/annotations.py +52 -0
  105. gstaichi/types/compound_types.py +71 -0
  106. gstaichi/types/enums.py +49 -0
  107. gstaichi/types/ndarray_type.py +169 -0
  108. gstaichi/types/primitive_types.py +206 -0
  109. gstaichi/types/quant.py +88 -0
  110. gstaichi/types/texture_type.py +85 -0
  111. gstaichi/types/utils.py +11 -0
  112. gstaichi-2.1.1rc3.data/data/include/GLFW/glfw3.h +6389 -0
  113. gstaichi-2.1.1rc3.data/data/include/GLFW/glfw3native.h +594 -0
  114. gstaichi-2.1.1rc3.data/data/include/spirv-tools/instrument.hpp +268 -0
  115. gstaichi-2.1.1rc3.data/data/include/spirv-tools/libspirv.h +907 -0
  116. gstaichi-2.1.1rc3.data/data/include/spirv-tools/libspirv.hpp +375 -0
  117. gstaichi-2.1.1rc3.data/data/include/spirv-tools/linker.hpp +97 -0
  118. gstaichi-2.1.1rc3.data/data/include/spirv-tools/optimizer.hpp +970 -0
  119. gstaichi-2.1.1rc3.data/data/include/spirv_cross/GLSL.std.450.h +114 -0
  120. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv.h +2568 -0
  121. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv.hpp +2579 -0
  122. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cfg.hpp +168 -0
  123. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_common.hpp +1920 -0
  124. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cpp.hpp +93 -0
  125. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cross.hpp +1171 -0
  126. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cross_c.h +1074 -0
  127. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cross_containers.hpp +754 -0
  128. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cross_error_handling.hpp +94 -0
  129. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cross_parsed_ir.hpp +256 -0
  130. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_cross_util.hpp +37 -0
  131. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_glsl.hpp +1001 -0
  132. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_hlsl.hpp +406 -0
  133. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_msl.hpp +1273 -0
  134. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_parser.hpp +103 -0
  135. gstaichi-2.1.1rc3.data/data/include/spirv_cross/spirv_reflect.hpp +91 -0
  136. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools/SPIRV-ToolsConfig.cmake +5 -0
  137. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools/SPIRV-ToolsTarget-release.cmake +29 -0
  138. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools/SPIRV-ToolsTarget.cmake +114 -0
  139. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-diff/SPIRV-Tools-diffConfig.cmake +5 -0
  140. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-diff/SPIRV-Tools-diffTargets-release.cmake +19 -0
  141. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-diff/SPIRV-Tools-diffTargets.cmake +123 -0
  142. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-link/SPIRV-Tools-linkConfig.cmake +5 -0
  143. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-link/SPIRV-Tools-linkTargets-release.cmake +19 -0
  144. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-link/SPIRV-Tools-linkTargets.cmake +123 -0
  145. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-lint/SPIRV-Tools-lintConfig.cmake +5 -0
  146. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-lint/SPIRV-Tools-lintTargets-release.cmake +19 -0
  147. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-lint/SPIRV-Tools-lintTargets.cmake +123 -0
  148. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-opt/SPIRV-Tools-optConfig.cmake +5 -0
  149. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-opt/SPIRV-Tools-optTargets-release.cmake +19 -0
  150. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-opt/SPIRV-Tools-optTargets.cmake +123 -0
  151. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-reduce/SPIRV-Tools-reduceConfig.cmake +5 -0
  152. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-reduce/SPIRV-Tools-reduceTarget-release.cmake +19 -0
  153. gstaichi-2.1.1rc3.data/data/lib/cmake/SPIRV-Tools-reduce/SPIRV-Tools-reduceTarget.cmake +123 -0
  154. gstaichi-2.1.1rc3.data/data/lib/cmake/glfw3/glfw3Config.cmake +3 -0
  155. gstaichi-2.1.1rc3.data/data/lib/cmake/glfw3/glfw3ConfigVersion.cmake +65 -0
  156. gstaichi-2.1.1rc3.data/data/lib/cmake/glfw3/glfw3Targets-release.cmake +19 -0
  157. gstaichi-2.1.1rc3.data/data/lib/cmake/glfw3/glfw3Targets.cmake +107 -0
  158. gstaichi-2.1.1rc3.data/data/lib/libSPIRV-Tools-shared.dylib +0 -0
  159. gstaichi-2.1.1rc3.data/data/share/spirv_cross_c/cmake/spirv_cross_cConfig-release.cmake +19 -0
  160. gstaichi-2.1.1rc3.data/data/share/spirv_cross_c/cmake/spirv_cross_cConfig.cmake +123 -0
  161. gstaichi-2.1.1rc3.data/data/share/spirv_cross_core/cmake/spirv_cross_coreConfig-release.cmake +19 -0
  162. gstaichi-2.1.1rc3.data/data/share/spirv_cross_core/cmake/spirv_cross_coreConfig.cmake +106 -0
  163. gstaichi-2.1.1rc3.data/data/share/spirv_cross_cpp/cmake/spirv_cross_cppConfig-release.cmake +19 -0
  164. gstaichi-2.1.1rc3.data/data/share/spirv_cross_cpp/cmake/spirv_cross_cppConfig.cmake +123 -0
  165. gstaichi-2.1.1rc3.data/data/share/spirv_cross_glsl/cmake/spirv_cross_glslConfig-release.cmake +19 -0
  166. gstaichi-2.1.1rc3.data/data/share/spirv_cross_glsl/cmake/spirv_cross_glslConfig.cmake +123 -0
  167. gstaichi-2.1.1rc3.data/data/share/spirv_cross_hlsl/cmake/spirv_cross_hlslConfig-release.cmake +19 -0
  168. gstaichi-2.1.1rc3.data/data/share/spirv_cross_hlsl/cmake/spirv_cross_hlslConfig.cmake +123 -0
  169. gstaichi-2.1.1rc3.data/data/share/spirv_cross_msl/cmake/spirv_cross_mslConfig-release.cmake +19 -0
  170. gstaichi-2.1.1rc3.data/data/share/spirv_cross_msl/cmake/spirv_cross_mslConfig.cmake +123 -0
  171. gstaichi-2.1.1rc3.data/data/share/spirv_cross_reflect/cmake/spirv_cross_reflectConfig-release.cmake +19 -0
  172. gstaichi-2.1.1rc3.data/data/share/spirv_cross_reflect/cmake/spirv_cross_reflectConfig.cmake +106 -0
  173. gstaichi-2.1.1rc3.data/data/share/spirv_cross_util/cmake/spirv_cross_utilConfig-release.cmake +19 -0
  174. gstaichi-2.1.1rc3.data/data/share/spirv_cross_util/cmake/spirv_cross_utilConfig.cmake +123 -0
  175. gstaichi-2.1.1rc3.dist-info/METADATA +106 -0
  176. gstaichi-2.1.1rc3.dist-info/RECORD +179 -0
  177. gstaichi-2.1.1rc3.dist-info/WHEEL +5 -0
  178. gstaichi-2.1.1rc3.dist-info/licenses/LICENSE +201 -0
  179. gstaichi-2.1.1rc3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,754 @@
1
+ /*
2
+ * Copyright 2019-2021 Hans-Kristian Arntzen
3
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /*
19
+ * At your option, you may choose to accept this material under either:
20
+ * 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or
21
+ * 2. The MIT License, found at <http://opensource.org/licenses/MIT>.
22
+ */
23
+
24
+ #ifndef SPIRV_CROSS_CONTAINERS_HPP
25
+ #define SPIRV_CROSS_CONTAINERS_HPP
26
+
27
+ #include "spirv_cross_error_handling.hpp"
28
+ #include <algorithm>
29
+ #include <functional>
30
+ #include <iterator>
31
+ #include <limits>
32
+ #include <memory>
33
+ #include <stack>
34
+ #include <stddef.h>
35
+ #include <stdint.h>
36
+ #include <stdlib.h>
37
+ #include <string.h>
38
+ #include <type_traits>
39
+ #include <unordered_map>
40
+ #include <unordered_set>
41
+ #include <utility>
42
+ #include <vector>
43
+
44
+ #ifdef SPIRV_CROSS_NAMESPACE_OVERRIDE
45
+ #define SPIRV_CROSS_NAMESPACE SPIRV_CROSS_NAMESPACE_OVERRIDE
46
+ #else
47
+ #define SPIRV_CROSS_NAMESPACE spirv_cross
48
+ #endif
49
+
50
+ namespace SPIRV_CROSS_NAMESPACE
51
+ {
52
+ #ifndef SPIRV_CROSS_FORCE_STL_TYPES
53
+ // std::aligned_storage does not support size == 0, so roll our own.
54
+ template <typename T, size_t N>
55
+ class AlignedBuffer
56
+ {
57
+ public:
58
+ T *data()
59
+ {
60
+ #if defined(_MSC_VER) && _MSC_VER < 1900
61
+ // MSVC 2013 workarounds, sigh ...
62
+ // Only use this workaround on MSVC 2013 due to some confusion around default initialized unions.
63
+ // Spec seems to suggest the memory will be zero-initialized, which is *not* what we want.
64
+ return reinterpret_cast<T *>(u.aligned_char);
65
+ #else
66
+ return reinterpret_cast<T *>(aligned_char);
67
+ #endif
68
+ }
69
+
70
+ private:
71
+ #if defined(_MSC_VER) && _MSC_VER < 1900
72
+ // MSVC 2013 workarounds, sigh ...
73
+ union
74
+ {
75
+ char aligned_char[sizeof(T) * N];
76
+ double dummy_aligner;
77
+ } u;
78
+ #else
79
+ alignas(T) char aligned_char[sizeof(T) * N];
80
+ #endif
81
+ };
82
+
83
+ template <typename T>
84
+ class AlignedBuffer<T, 0>
85
+ {
86
+ public:
87
+ T *data()
88
+ {
89
+ return nullptr;
90
+ }
91
+ };
92
+
93
+ // An immutable version of SmallVector which erases type information about storage.
94
+ template <typename T>
95
+ class VectorView
96
+ {
97
+ public:
98
+ T &operator[](size_t i) SPIRV_CROSS_NOEXCEPT
99
+ {
100
+ return ptr[i];
101
+ }
102
+
103
+ const T &operator[](size_t i) const SPIRV_CROSS_NOEXCEPT
104
+ {
105
+ return ptr[i];
106
+ }
107
+
108
+ bool empty() const SPIRV_CROSS_NOEXCEPT
109
+ {
110
+ return buffer_size == 0;
111
+ }
112
+
113
+ size_t size() const SPIRV_CROSS_NOEXCEPT
114
+ {
115
+ return buffer_size;
116
+ }
117
+
118
+ T *data() SPIRV_CROSS_NOEXCEPT
119
+ {
120
+ return ptr;
121
+ }
122
+
123
+ const T *data() const SPIRV_CROSS_NOEXCEPT
124
+ {
125
+ return ptr;
126
+ }
127
+
128
+ T *begin() SPIRV_CROSS_NOEXCEPT
129
+ {
130
+ return ptr;
131
+ }
132
+
133
+ T *end() SPIRV_CROSS_NOEXCEPT
134
+ {
135
+ return ptr + buffer_size;
136
+ }
137
+
138
+ const T *begin() const SPIRV_CROSS_NOEXCEPT
139
+ {
140
+ return ptr;
141
+ }
142
+
143
+ const T *end() const SPIRV_CROSS_NOEXCEPT
144
+ {
145
+ return ptr + buffer_size;
146
+ }
147
+
148
+ T &front() SPIRV_CROSS_NOEXCEPT
149
+ {
150
+ return ptr[0];
151
+ }
152
+
153
+ const T &front() const SPIRV_CROSS_NOEXCEPT
154
+ {
155
+ return ptr[0];
156
+ }
157
+
158
+ T &back() SPIRV_CROSS_NOEXCEPT
159
+ {
160
+ return ptr[buffer_size - 1];
161
+ }
162
+
163
+ const T &back() const SPIRV_CROSS_NOEXCEPT
164
+ {
165
+ return ptr[buffer_size - 1];
166
+ }
167
+
168
+ // Makes it easier to consume SmallVector.
169
+ #if defined(_MSC_VER) && _MSC_VER < 1900
170
+ explicit operator std::vector<T>() const
171
+ {
172
+ // Another MSVC 2013 workaround. It does not understand lvalue/rvalue qualified operations.
173
+ return std::vector<T>(ptr, ptr + buffer_size);
174
+ }
175
+ #else
176
+ // Makes it easier to consume SmallVector.
177
+ explicit operator std::vector<T>() const &
178
+ {
179
+ return std::vector<T>(ptr, ptr + buffer_size);
180
+ }
181
+
182
+ // If we are converting as an r-value, we can pilfer our elements.
183
+ explicit operator std::vector<T>() &&
184
+ {
185
+ return std::vector<T>(std::make_move_iterator(ptr), std::make_move_iterator(ptr + buffer_size));
186
+ }
187
+ #endif
188
+
189
+ // Avoid sliced copies. Base class should only be read as a reference.
190
+ VectorView(const VectorView &) = delete;
191
+ void operator=(const VectorView &) = delete;
192
+
193
+ protected:
194
+ VectorView() = default;
195
+ T *ptr = nullptr;
196
+ size_t buffer_size = 0;
197
+ };
198
+
199
+ // Simple vector which supports up to N elements inline, without malloc/free.
200
+ // We use a lot of throwaway vectors all over the place which triggers allocations.
201
+ // This class only implements the subset of std::vector we need in SPIRV-Cross.
202
+ // It is *NOT* a drop-in replacement in general projects.
203
+ template <typename T, size_t N = 8>
204
+ class SmallVector : public VectorView<T>
205
+ {
206
+ public:
207
+ SmallVector() SPIRV_CROSS_NOEXCEPT
208
+ {
209
+ this->ptr = stack_storage.data();
210
+ buffer_capacity = N;
211
+ }
212
+
213
+ template <typename U>
214
+ SmallVector(const U *arg_list_begin, const U *arg_list_end) SPIRV_CROSS_NOEXCEPT : SmallVector()
215
+ {
216
+ auto count = size_t(arg_list_end - arg_list_begin);
217
+ reserve(count);
218
+ for (size_t i = 0; i < count; i++, arg_list_begin++)
219
+ new (&this->ptr[i]) T(*arg_list_begin);
220
+ this->buffer_size = count;
221
+ }
222
+
223
+ template <typename U>
224
+ SmallVector(std::initializer_list<U> init) SPIRV_CROSS_NOEXCEPT : SmallVector(init.begin(), init.end())
225
+ {
226
+ }
227
+
228
+ template <typename U, size_t M>
229
+ SmallVector(const U (&init)[M]) SPIRV_CROSS_NOEXCEPT : SmallVector(init, init + M)
230
+ {
231
+ }
232
+
233
+ SmallVector(SmallVector &&other) SPIRV_CROSS_NOEXCEPT : SmallVector()
234
+ {
235
+ *this = std::move(other);
236
+ }
237
+
238
+ SmallVector &operator=(SmallVector &&other) SPIRV_CROSS_NOEXCEPT
239
+ {
240
+ clear();
241
+ if (other.ptr != other.stack_storage.data())
242
+ {
243
+ // Pilfer allocated pointer.
244
+ if (this->ptr != stack_storage.data())
245
+ free(this->ptr);
246
+ this->ptr = other.ptr;
247
+ this->buffer_size = other.buffer_size;
248
+ buffer_capacity = other.buffer_capacity;
249
+ other.ptr = nullptr;
250
+ other.buffer_size = 0;
251
+ other.buffer_capacity = 0;
252
+ }
253
+ else
254
+ {
255
+ // Need to move the stack contents individually.
256
+ reserve(other.buffer_size);
257
+ for (size_t i = 0; i < other.buffer_size; i++)
258
+ {
259
+ new (&this->ptr[i]) T(std::move(other.ptr[i]));
260
+ other.ptr[i].~T();
261
+ }
262
+ this->buffer_size = other.buffer_size;
263
+ other.buffer_size = 0;
264
+ }
265
+ return *this;
266
+ }
267
+
268
+ SmallVector(const SmallVector &other) SPIRV_CROSS_NOEXCEPT : SmallVector()
269
+ {
270
+ *this = other;
271
+ }
272
+
273
+ SmallVector &operator=(const SmallVector &other) SPIRV_CROSS_NOEXCEPT
274
+ {
275
+ if (this == &other)
276
+ return *this;
277
+
278
+ clear();
279
+ reserve(other.buffer_size);
280
+ for (size_t i = 0; i < other.buffer_size; i++)
281
+ new (&this->ptr[i]) T(other.ptr[i]);
282
+ this->buffer_size = other.buffer_size;
283
+ return *this;
284
+ }
285
+
286
+ explicit SmallVector(size_t count) SPIRV_CROSS_NOEXCEPT : SmallVector()
287
+ {
288
+ resize(count);
289
+ }
290
+
291
+ ~SmallVector()
292
+ {
293
+ clear();
294
+ if (this->ptr != stack_storage.data())
295
+ free(this->ptr);
296
+ }
297
+
298
+ void clear() SPIRV_CROSS_NOEXCEPT
299
+ {
300
+ for (size_t i = 0; i < this->buffer_size; i++)
301
+ this->ptr[i].~T();
302
+ this->buffer_size = 0;
303
+ }
304
+
305
+ void push_back(const T &t) SPIRV_CROSS_NOEXCEPT
306
+ {
307
+ reserve(this->buffer_size + 1);
308
+ new (&this->ptr[this->buffer_size]) T(t);
309
+ this->buffer_size++;
310
+ }
311
+
312
+ void push_back(T &&t) SPIRV_CROSS_NOEXCEPT
313
+ {
314
+ reserve(this->buffer_size + 1);
315
+ new (&this->ptr[this->buffer_size]) T(std::move(t));
316
+ this->buffer_size++;
317
+ }
318
+
319
+ void pop_back() SPIRV_CROSS_NOEXCEPT
320
+ {
321
+ // Work around false positive warning on GCC 8.3.
322
+ // Calling pop_back on empty vector is undefined.
323
+ if (!this->empty())
324
+ resize(this->buffer_size - 1);
325
+ }
326
+
327
+ template <typename... Ts>
328
+ void emplace_back(Ts &&... ts) SPIRV_CROSS_NOEXCEPT
329
+ {
330
+ reserve(this->buffer_size + 1);
331
+ new (&this->ptr[this->buffer_size]) T(std::forward<Ts>(ts)...);
332
+ this->buffer_size++;
333
+ }
334
+
335
+ void reserve(size_t count) SPIRV_CROSS_NOEXCEPT
336
+ {
337
+ if ((count > (std::numeric_limits<size_t>::max)() / sizeof(T)) ||
338
+ (count > (std::numeric_limits<size_t>::max)() / 2))
339
+ {
340
+ // Only way this should ever happen is with garbage input, terminate.
341
+ std::terminate();
342
+ }
343
+
344
+ if (count > buffer_capacity)
345
+ {
346
+ size_t target_capacity = buffer_capacity;
347
+ if (target_capacity == 0)
348
+ target_capacity = 1;
349
+
350
+ // Weird parens works around macro issues on Windows if NOMINMAX is not used.
351
+ target_capacity = (std::max)(target_capacity, N);
352
+
353
+ // Need to ensure there is a POT value of target capacity which is larger than count,
354
+ // otherwise this will overflow.
355
+ while (target_capacity < count)
356
+ target_capacity <<= 1u;
357
+
358
+ T *new_buffer =
359
+ target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();
360
+
361
+ // If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
362
+ if (!new_buffer)
363
+ std::terminate();
364
+
365
+ // In case for some reason two allocations both come from same stack.
366
+ if (new_buffer != this->ptr)
367
+ {
368
+ // We don't deal with types which can throw in move constructor.
369
+ for (size_t i = 0; i < this->buffer_size; i++)
370
+ {
371
+ new (&new_buffer[i]) T(std::move(this->ptr[i]));
372
+ this->ptr[i].~T();
373
+ }
374
+ }
375
+
376
+ if (this->ptr != stack_storage.data())
377
+ free(this->ptr);
378
+ this->ptr = new_buffer;
379
+ buffer_capacity = target_capacity;
380
+ }
381
+ }
382
+
383
+ void insert(T *itr, const T *insert_begin, const T *insert_end) SPIRV_CROSS_NOEXCEPT
384
+ {
385
+ auto count = size_t(insert_end - insert_begin);
386
+ if (itr == this->end())
387
+ {
388
+ reserve(this->buffer_size + count);
389
+ for (size_t i = 0; i < count; i++, insert_begin++)
390
+ new (&this->ptr[this->buffer_size + i]) T(*insert_begin);
391
+ this->buffer_size += count;
392
+ }
393
+ else
394
+ {
395
+ if (this->buffer_size + count > buffer_capacity)
396
+ {
397
+ auto target_capacity = this->buffer_size + count;
398
+ if (target_capacity == 0)
399
+ target_capacity = 1;
400
+ if (target_capacity < N)
401
+ target_capacity = N;
402
+
403
+ while (target_capacity < count)
404
+ target_capacity <<= 1u;
405
+
406
+ // Need to allocate new buffer. Move everything to a new buffer.
407
+ T *new_buffer =
408
+ target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();
409
+
410
+ // If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
411
+ if (!new_buffer)
412
+ std::terminate();
413
+
414
+ // First, move elements from source buffer to new buffer.
415
+ // We don't deal with types which can throw in move constructor.
416
+ auto *target_itr = new_buffer;
417
+ auto *original_source_itr = this->begin();
418
+
419
+ if (new_buffer != this->ptr)
420
+ {
421
+ while (original_source_itr != itr)
422
+ {
423
+ new (target_itr) T(std::move(*original_source_itr));
424
+ original_source_itr->~T();
425
+ ++original_source_itr;
426
+ ++target_itr;
427
+ }
428
+ }
429
+
430
+ // Copy-construct new elements.
431
+ for (auto *source_itr = insert_begin; source_itr != insert_end; ++source_itr, ++target_itr)
432
+ new (target_itr) T(*source_itr);
433
+
434
+ // Move over the other half.
435
+ if (new_buffer != this->ptr || insert_begin != insert_end)
436
+ {
437
+ while (original_source_itr != this->end())
438
+ {
439
+ new (target_itr) T(std::move(*original_source_itr));
440
+ original_source_itr->~T();
441
+ ++original_source_itr;
442
+ ++target_itr;
443
+ }
444
+ }
445
+
446
+ if (this->ptr != stack_storage.data())
447
+ free(this->ptr);
448
+ this->ptr = new_buffer;
449
+ buffer_capacity = target_capacity;
450
+ }
451
+ else
452
+ {
453
+ // Move in place, need to be a bit careful about which elements are constructed and which are not.
454
+ // Move the end and construct the new elements.
455
+ auto *target_itr = this->end() + count;
456
+ auto *source_itr = this->end();
457
+ while (target_itr != this->end() && source_itr != itr)
458
+ {
459
+ --target_itr;
460
+ --source_itr;
461
+ new (target_itr) T(std::move(*source_itr));
462
+ }
463
+
464
+ // For already constructed elements we can move-assign.
465
+ std::move_backward(itr, source_itr, target_itr);
466
+
467
+ // For the inserts which go to already constructed elements, we can do a plain copy.
468
+ while (itr != this->end() && insert_begin != insert_end)
469
+ *itr++ = *insert_begin++;
470
+
471
+ // For inserts into newly allocated memory, we must copy-construct instead.
472
+ while (insert_begin != insert_end)
473
+ {
474
+ new (itr) T(*insert_begin);
475
+ ++itr;
476
+ ++insert_begin;
477
+ }
478
+ }
479
+
480
+ this->buffer_size += count;
481
+ }
482
+ }
483
+
484
+ void insert(T *itr, const T &value) SPIRV_CROSS_NOEXCEPT
485
+ {
486
+ insert(itr, &value, &value + 1);
487
+ }
488
+
489
+ T *erase(T *itr) SPIRV_CROSS_NOEXCEPT
490
+ {
491
+ std::move(itr + 1, this->end(), itr);
492
+ this->ptr[--this->buffer_size].~T();
493
+ return itr;
494
+ }
495
+
496
+ void erase(T *start_erase, T *end_erase) SPIRV_CROSS_NOEXCEPT
497
+ {
498
+ if (end_erase == this->end())
499
+ {
500
+ resize(size_t(start_erase - this->begin()));
501
+ }
502
+ else
503
+ {
504
+ auto new_size = this->buffer_size - (end_erase - start_erase);
505
+ std::move(end_erase, this->end(), start_erase);
506
+ resize(new_size);
507
+ }
508
+ }
509
+
510
+ void resize(size_t new_size) SPIRV_CROSS_NOEXCEPT
511
+ {
512
+ if (new_size < this->buffer_size)
513
+ {
514
+ for (size_t i = new_size; i < this->buffer_size; i++)
515
+ this->ptr[i].~T();
516
+ }
517
+ else if (new_size > this->buffer_size)
518
+ {
519
+ reserve(new_size);
520
+ for (size_t i = this->buffer_size; i < new_size; i++)
521
+ new (&this->ptr[i]) T();
522
+ }
523
+
524
+ this->buffer_size = new_size;
525
+ }
526
+
527
+ private:
528
+ size_t buffer_capacity = 0;
529
+ AlignedBuffer<T, N> stack_storage;
530
+ };
531
+
532
+ // A vector without stack storage.
533
+ // Could also be a typedef-ed to std::vector,
534
+ // but might as well use the one we have.
535
+ template <typename T>
536
+ using Vector = SmallVector<T, 0>;
537
+
538
+ #else // SPIRV_CROSS_FORCE_STL_TYPES
539
+
540
+ template <typename T, size_t N = 8>
541
+ using SmallVector = std::vector<T>;
542
+ template <typename T>
543
+ using Vector = std::vector<T>;
544
+ template <typename T>
545
+ using VectorView = std::vector<T>;
546
+
547
+ #endif // SPIRV_CROSS_FORCE_STL_TYPES
548
+
549
+ // An object pool which we use for allocating IVariant-derived objects.
550
+ // We know we are going to allocate a bunch of objects of each type,
551
+ // so amortize the mallocs.
552
+ class ObjectPoolBase
553
+ {
554
+ public:
555
+ virtual ~ObjectPoolBase() = default;
556
+ virtual void deallocate_opaque(void *ptr) = 0;
557
+ };
558
+
559
+ template <typename T>
560
+ class ObjectPool : public ObjectPoolBase
561
+ {
562
+ public:
563
+ explicit ObjectPool(unsigned start_object_count_ = 16)
564
+ : start_object_count(start_object_count_)
565
+ {
566
+ }
567
+
568
+ template <typename... P>
569
+ T *allocate(P &&... p)
570
+ {
571
+ if (vacants.empty())
572
+ {
573
+ unsigned num_objects = start_object_count << memory.size();
574
+ T *ptr = static_cast<T *>(malloc(num_objects * sizeof(T)));
575
+ if (!ptr)
576
+ return nullptr;
577
+
578
+ for (unsigned i = 0; i < num_objects; i++)
579
+ vacants.push_back(&ptr[i]);
580
+
581
+ memory.emplace_back(ptr);
582
+ }
583
+
584
+ T *ptr = vacants.back();
585
+ vacants.pop_back();
586
+ new (ptr) T(std::forward<P>(p)...);
587
+ return ptr;
588
+ }
589
+
590
+ void deallocate(T *ptr)
591
+ {
592
+ ptr->~T();
593
+ vacants.push_back(ptr);
594
+ }
595
+
596
+ void deallocate_opaque(void *ptr) override
597
+ {
598
+ deallocate(static_cast<T *>(ptr));
599
+ }
600
+
601
+ void clear()
602
+ {
603
+ vacants.clear();
604
+ memory.clear();
605
+ }
606
+
607
+ protected:
608
+ Vector<T *> vacants;
609
+
610
+ struct MallocDeleter
611
+ {
612
+ void operator()(T *ptr)
613
+ {
614
+ ::free(ptr);
615
+ }
616
+ };
617
+
618
+ SmallVector<std::unique_ptr<T, MallocDeleter>> memory;
619
+ unsigned start_object_count;
620
+ };
621
+
622
+ template <size_t StackSize = 4096, size_t BlockSize = 4096>
623
+ class StringStream
624
+ {
625
+ public:
626
+ StringStream()
627
+ {
628
+ reset();
629
+ }
630
+
631
+ ~StringStream()
632
+ {
633
+ reset();
634
+ }
635
+
636
+ // Disable copies and moves. Makes it easier to implement, and we don't need it.
637
+ StringStream(const StringStream &) = delete;
638
+ void operator=(const StringStream &) = delete;
639
+
640
+ template <typename T, typename std::enable_if<!std::is_floating_point<T>::value, int>::type = 0>
641
+ StringStream &operator<<(const T &t)
642
+ {
643
+ auto s = std::to_string(t);
644
+ append(s.data(), s.size());
645
+ return *this;
646
+ }
647
+
648
+ // Only overload this to make float/double conversions ambiguous.
649
+ StringStream &operator<<(uint32_t v)
650
+ {
651
+ auto s = std::to_string(v);
652
+ append(s.data(), s.size());
653
+ return *this;
654
+ }
655
+
656
+ StringStream &operator<<(char c)
657
+ {
658
+ append(&c, 1);
659
+ return *this;
660
+ }
661
+
662
+ StringStream &operator<<(const std::string &s)
663
+ {
664
+ append(s.data(), s.size());
665
+ return *this;
666
+ }
667
+
668
+ StringStream &operator<<(const char *s)
669
+ {
670
+ append(s, strlen(s));
671
+ return *this;
672
+ }
673
+
674
+ template <size_t N>
675
+ StringStream &operator<<(const char (&s)[N])
676
+ {
677
+ append(s, strlen(s));
678
+ return *this;
679
+ }
680
+
681
+ std::string str() const
682
+ {
683
+ std::string ret;
684
+ size_t target_size = 0;
685
+ for (auto &saved : saved_buffers)
686
+ target_size += saved.offset;
687
+ target_size += current_buffer.offset;
688
+ ret.reserve(target_size);
689
+
690
+ for (auto &saved : saved_buffers)
691
+ ret.insert(ret.end(), saved.buffer, saved.buffer + saved.offset);
692
+ ret.insert(ret.end(), current_buffer.buffer, current_buffer.buffer + current_buffer.offset);
693
+ return ret;
694
+ }
695
+
696
+ void reset()
697
+ {
698
+ for (auto &saved : saved_buffers)
699
+ if (saved.buffer != stack_buffer)
700
+ free(saved.buffer);
701
+ if (current_buffer.buffer != stack_buffer)
702
+ free(current_buffer.buffer);
703
+
704
+ saved_buffers.clear();
705
+ current_buffer.buffer = stack_buffer;
706
+ current_buffer.offset = 0;
707
+ current_buffer.size = sizeof(stack_buffer);
708
+ }
709
+
710
+ private:
711
+ struct Buffer
712
+ {
713
+ char *buffer = nullptr;
714
+ size_t offset = 0;
715
+ size_t size = 0;
716
+ };
717
+ Buffer current_buffer;
718
+ char stack_buffer[StackSize];
719
+ SmallVector<Buffer> saved_buffers;
720
+
721
+ void append(const char *s, size_t len)
722
+ {
723
+ size_t avail = current_buffer.size - current_buffer.offset;
724
+ if (avail < len)
725
+ {
726
+ if (avail > 0)
727
+ {
728
+ memcpy(current_buffer.buffer + current_buffer.offset, s, avail);
729
+ s += avail;
730
+ len -= avail;
731
+ current_buffer.offset += avail;
732
+ }
733
+
734
+ saved_buffers.push_back(current_buffer);
735
+ size_t target_size = len > BlockSize ? len : BlockSize;
736
+ current_buffer.buffer = static_cast<char *>(malloc(target_size));
737
+ if (!current_buffer.buffer)
738
+ SPIRV_CROSS_THROW("Out of memory.");
739
+
740
+ memcpy(current_buffer.buffer, s, len);
741
+ current_buffer.offset = len;
742
+ current_buffer.size = target_size;
743
+ }
744
+ else
745
+ {
746
+ memcpy(current_buffer.buffer + current_buffer.offset, s, len);
747
+ current_buffer.offset += len;
748
+ }
749
+ }
750
+ };
751
+
752
+ } // namespace SPIRV_CROSS_NAMESPACE
753
+
754
+ #endif