Ginkgo Generated from branch based on master. Ginkgo version 1.7.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
exception_helpers.hpp
1/*******************************<GINKGO LICENSE>******************************
2Copyright (c) 2017-2023, the Ginkgo authors
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions
7are met:
8
91. Redistributions of source code must retain the above copyright
10notice, this list of conditions and the following disclaimer.
11
122. Redistributions in binary form must reproduce the above copyright
13notice, this list of conditions and the following disclaimer in the
14documentation and/or other materials provided with the distribution.
15
163. Neither the name of the copyright holder nor the names of its
17contributors may be used to endorse or promote products derived from
18this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31******************************<GINKGO LICENSE>*******************************/
32
33#ifndef GKO_PUBLIC_CORE_BASE_EXCEPTION_HELPERS_HPP_
34#define GKO_PUBLIC_CORE_BASE_EXCEPTION_HELPERS_HPP_
35
36
37#include <typeinfo>
38
39
40#include <ginkgo/core/base/batch_dim.hpp>
41#include <ginkgo/core/base/dim.hpp>
42#include <ginkgo/core/base/exception.hpp>
43#include <ginkgo/core/base/name_demangling.hpp>
44#include <ginkgo/core/base/utils_helper.hpp>
45
46
47namespace gko {
48
49
57#define GKO_QUOTE(...) #__VA_ARGS__
58
59
66#define GKO_NOT_IMPLEMENTED \
67 { \
68 throw ::gko::NotImplemented(__FILE__, __LINE__, __func__); \
69 } \
70 static_assert(true, \
71 "This assert is used to counter the false positive extra " \
72 "semi-colon warnings")
73
74
83#define GKO_NOT_COMPILED(_module) \
84 { \
85 throw ::gko::NotCompiled(__FILE__, __LINE__, __func__, \
86 GKO_QUOTE(_module)); \
87 } \
88 static_assert(true, \
89 "This assert is used to counter the false positive extra " \
90 "semi-colon warnings")
91
92
93namespace detail {
94
95
96template <typename T, typename T2 = void>
97struct dynamic_type_helper {
98 static const std::type_info& get(const T& obj) { return typeid(obj); }
99};
100
101template <typename T>
102struct dynamic_type_helper<T,
103 typename std::enable_if<std::is_pointer<T>::value ||
104 have_ownership<T>()>::type> {
105 static const std::type_info& get(const T& obj)
106 {
107 return obj ? typeid(*obj) : typeid(nullptr);
108 }
109};
110
111template <typename T>
112const std::type_info& get_dynamic_type(const T& obj)
113{
114 return dynamic_type_helper<T>::get(obj);
115}
116
117
118} // namespace detail
119
120
128#define GKO_NOT_SUPPORTED(_obj) \
129 { \
130 throw ::gko::NotSupported(__FILE__, __LINE__, __func__, \
131 ::gko::name_demangling::get_type_name( \
132 ::gko::detail::get_dynamic_type(_obj))); \
133 } \
134 static_assert(true, \
135 "This assert is used to counter the false positive extra " \
136 "semi-colon warnings")
137
138
139namespace detail {
140
141
142template <typename T>
143inline dim<2> get_size(const T& op)
144{
145 return op->get_size();
146}
147
148inline dim<2> get_size(const dim<2>& size) { return size; }
149
150
151template <typename T>
152inline batch_dim<2> get_batch_size(const T& op)
153{
154 return op->get_size();
155}
156
157inline batch_dim<2> get_batch_size(const batch_dim<2>& size) { return size; }
158
159
160template <typename T>
161inline size_type get_num_batch_items(const T& obj)
162{
163 return obj.get_num_batch_items();
164}
165
166
167} // namespace detail
168
169
175#define GKO_ASSERT_EQ(_val1, _val2) \
176 if (_val1 != _val2) { \
177 throw ::gko::ValueMismatch(__FILE__, __LINE__, __func__, _val1, _val2, \
178 "expected equal values"); \
179 }
180
181
188#define GKO_ASSERT_IS_SQUARE_MATRIX(_op1) \
189 if (::gko::detail::get_size(_op1)[0] != \
190 ::gko::detail::get_size(_op1)[1]) { \
191 throw ::gko::DimensionMismatch( \
192 __FILE__, __LINE__, __func__, #_op1, \
193 ::gko::detail::get_size(_op1)[0], \
194 ::gko::detail::get_size(_op1)[1], #_op1, \
195 ::gko::detail::get_size(_op1)[0], \
196 ::gko::detail::get_size(_op1)[1], "expected square matrix"); \
197 }
198
199
205#define GKO_ASSERT_IS_NON_EMPTY_MATRIX(_op1) \
206 if (!(::gko::detail::get_size(_op1))) { \
207 throw ::gko::BadDimension(__FILE__, __LINE__, __func__, #_op1, \
208 ::gko::detail::get_size(_op1)[0], \
209 ::gko::detail::get_size(_op1)[1], \
210 "expected non-empty matrix"); \
211 }
212
213
219#define GKO_ASSERT_IS_POWER_OF_TWO(_val) \
220 do { \
221 if (_val == 0 || (_val & (_val - 1)) != 0) { \
222 throw ::gko::BadDimension(__FILE__, __LINE__, __func__, #_val, \
223 _val, _val, \
224 "expected power-of-two dimension"); \
225 } \
226 } while (false)
227
228
234#define GKO_ASSERT_CONFORMANT(_op1, _op2) \
235 if (::gko::detail::get_size(_op1)[1] != \
236 ::gko::detail::get_size(_op2)[0]) { \
237 throw ::gko::DimensionMismatch(__FILE__, __LINE__, __func__, #_op1, \
238 ::gko::detail::get_size(_op1)[0], \
239 ::gko::detail::get_size(_op1)[1], \
240 #_op2, \
241 ::gko::detail::get_size(_op2)[0], \
242 ::gko::detail::get_size(_op2)[1], \
243 "expected matching inner dimensions"); \
244 }
245
246
252#define GKO_ASSERT_REVERSE_CONFORMANT(_op1, _op2) \
253 if (::gko::detail::get_size(_op1)[0] != \
254 ::gko::detail::get_size(_op2)[1]) { \
255 throw ::gko::DimensionMismatch(__FILE__, __LINE__, __func__, #_op1, \
256 ::gko::detail::get_size(_op1)[0], \
257 ::gko::detail::get_size(_op1)[1], \
258 #_op2, \
259 ::gko::detail::get_size(_op2)[0], \
260 ::gko::detail::get_size(_op2)[1], \
261 "expected matching inner dimensions"); \
262 }
263
264
270#define GKO_ASSERT_EQUAL_ROWS(_op1, _op2) \
271 if (::gko::detail::get_size(_op1)[0] != \
272 ::gko::detail::get_size(_op2)[0]) { \
273 throw ::gko::DimensionMismatch( \
274 __FILE__, __LINE__, __func__, #_op1, \
275 ::gko::detail::get_size(_op1)[0], \
276 ::gko::detail::get_size(_op1)[1], #_op2, \
277 ::gko::detail::get_size(_op2)[0], \
278 ::gko::detail::get_size(_op2)[1], "expected matching row length"); \
279 }
280
281
288#define GKO_ASSERT_EQUAL_COLS(_op1, _op2) \
289 if (::gko::detail::get_size(_op1)[1] != \
290 ::gko::detail::get_size(_op2)[1]) { \
291 throw ::gko::DimensionMismatch(__FILE__, __LINE__, __func__, #_op1, \
292 ::gko::detail::get_size(_op1)[0], \
293 ::gko::detail::get_size(_op1)[1], \
294 #_op2, \
295 ::gko::detail::get_size(_op2)[0], \
296 ::gko::detail::get_size(_op2)[1], \
297 "expected matching column length"); \
298 }
299
300
307#define GKO_ASSERT_EQUAL_DIMENSIONS(_op1, _op2) \
308 if (::gko::detail::get_size(_op1) != ::gko::detail::get_size(_op2)) { \
309 throw ::gko::DimensionMismatch( \
310 __FILE__, __LINE__, __func__, #_op1, \
311 ::gko::detail::get_size(_op1)[0], \
312 ::gko::detail::get_size(_op1)[1], #_op2, \
313 ::gko::detail::get_size(_op2)[0], \
314 ::gko::detail::get_size(_op2)[1], "expected equal dimensions"); \
315 }
316
317
323#define GKO_ASSERT_BATCH_EQUAL_NUM_ITEMS(_op1, _op2) \
324 { \
325 auto equal_num_items = \
326 ::gko::detail::get_batch_size(_op1).get_num_batch_items() == \
327 ::gko::detail::get_batch_size(_op2).get_num_batch_items(); \
328 if (!equal_num_items) { \
329 throw ::gko::ValueMismatch( \
330 __FILE__, __LINE__, __func__, \
331 ::gko::detail::get_batch_size(_op1).get_num_batch_items(), \
332 ::gko::detail::get_batch_size(_op2).get_num_batch_items(), \
333 "expected equal number of batch items"); \
334 } \
335 }
336
337
343#define GKO_ASSERT_BATCH_CONFORMANT(_op1, _op2) \
344 { \
345 GKO_ASSERT_BATCH_EQUAL_NUM_ITEMS(_op1, _op2); \
346 auto equal_inner_size = \
347 ::gko::detail::get_batch_size(_op1).get_common_size()[1] == \
348 ::gko::detail::get_batch_size(_op2).get_common_size()[0]; \
349 if (!equal_inner_size) { \
350 throw ::gko::DimensionMismatch( \
351 __FILE__, __LINE__, __func__, #_op1, \
352 ::gko::detail::get_batch_size(_op1).get_common_size()[0], \
353 ::gko::detail::get_batch_size(_op1).get_common_size()[1], \
354 #_op2, \
355 ::gko::detail::get_batch_size(_op2).get_common_size()[0], \
356 ::gko::detail::get_batch_size(_op2).get_common_size()[1], \
357 "expected matching inner dimensions among all batch items"); \
358 } \
359 }
360
361
367#define GKO_ASSERT_BATCH_REVERSE_CONFORMANT(_op1, _op2) \
368 { \
369 GKO_ASSERT_BATCH_EQUAL_NUM_ITEMS(_op1, _op2); \
370 auto equal_outer_size = \
371 ::gko::detail::get_batch_size(_op1).get_common_size()[0] == \
372 ::gko::detail::get_batch_size(_op2).get_common_size()[1]; \
373 if (!equal_outer_size) { \
374 throw ::gko::DimensionMismatch( \
375 __FILE__, __LINE__, __func__, #_op1, \
376 ::gko::detail::get_batch_size(_op1).get_common_size()[0], \
377 ::gko::detail::get_batch_size(_op1).get_common_size()[1], \
378 #_op2, \
379 ::gko::detail::get_batch_size(_op2).get_common_size()[0], \
380 ::gko::detail::get_batch_size(_op2).get_common_size()[1], \
381 "expected matching outer dimensions among all batch items"); \
382 } \
383 }
384
385
391#define GKO_ASSERT_BATCH_EQUAL_ROWS(_op1, _op2) \
392 { \
393 GKO_ASSERT_BATCH_EQUAL_NUM_ITEMS(_op1, _op2); \
394 auto equal_rows = \
395 ::gko::detail::get_batch_size(_op1).get_common_size()[0] == \
396 ::gko::detail::get_batch_size(_op2).get_common_size()[0]; \
397 if (!equal_rows) { \
398 throw ::gko::DimensionMismatch( \
399 __FILE__, __LINE__, __func__, #_op1, \
400 ::gko::detail::get_batch_size(_op1).get_common_size()[0], \
401 ::gko::detail::get_batch_size(_op1).get_common_size()[1], \
402 #_op2, \
403 ::gko::detail::get_batch_size(_op2).get_common_size()[0], \
404 ::gko::detail::get_batch_size(_op2).get_common_size()[1], \
405 "expected matching number of rows among all batch items"); \
406 } \
407 }
408
409
416#define GKO_ASSERT_BATCH_EQUAL_COLS(_op1, _op2) \
417 { \
418 GKO_ASSERT_BATCH_EQUAL_NUM_ITEMS(_op1, _op2); \
419 auto equal_cols = \
420 ::gko::detail::get_batch_size(_op1).get_common_size()[1] == \
421 ::gko::detail::get_batch_size(_op2).get_common_size()[1]; \
422 if (!equal_cols) { \
423 throw ::gko::DimensionMismatch( \
424 __FILE__, __LINE__, __func__, #_op1, \
425 ::gko::detail::get_batch_size(_op1).get_common_size()[0], \
426 ::gko::detail::get_batch_size(_op1).get_common_size()[1], \
427 #_op2, \
428 ::gko::detail::get_batch_size(_op2).get_common_size()[0], \
429 ::gko::detail::get_batch_size(_op2).get_common_size()[1], \
430 "expected matching number of cols among all batch items"); \
431 } \
432 }
433
434
441#define GKO_ASSERT_BATCH_EQUAL_DIMENSIONS(_op1, _op2) \
442 { \
443 GKO_ASSERT_BATCH_EQUAL_NUM_ITEMS(_op1, _op2); \
444 auto equal_size = \
445 ::gko::detail::get_batch_size(_op1).get_common_size() == \
446 ::gko::detail::get_batch_size(_op2).get_common_size(); \
447 if (!equal_size) { \
448 throw ::gko::DimensionMismatch( \
449 __FILE__, __LINE__, __func__, #_op1, \
450 ::gko::detail::get_batch_size(_op1).get_common_size()[0], \
451 ::gko::detail::get_batch_size(_op1).get_common_size()[1], \
452 #_op2, \
453 ::gko::detail::get_batch_size(_op2).get_common_size()[0], \
454 ::gko::detail::get_batch_size(_op2).get_common_size()[1], \
455 "expected matching size among all batch items"); \
456 } \
457 }
458
459
466#define GKO_ASSERT_BATCH_HAS_SQUARE_DIMENSIONS(_op1) \
467 { \
468 auto is_square = \
469 ::gko::detail::get_batch_size(_op1).get_common_size()[0] == \
470 ::gko::detail::get_batch_size(_op1).get_common_size()[1]; \
471 if (!is_square) { \
472 throw ::gko::BadDimension( \
473 __FILE__, __LINE__, __func__, #_op1, \
474 ::gko::detail::get_batch_size(_op1).get_common_size()[0], \
475 ::gko::detail::get_batch_size(_op1).get_common_size()[1], \
476 "expected common size of matrices to be square"); \
477 } \
478 }
479
480
486#define GKO_MPI_ERROR(_errcode) \
487 ::gko::MpiError(__FILE__, __LINE__, __func__, _errcode)
488
489
495#define GKO_CUDA_ERROR(_errcode) \
496 ::gko::CudaError(__FILE__, __LINE__, __func__, _errcode)
497
498
504#define GKO_CUBLAS_ERROR(_errcode) \
505 ::gko::CublasError(__FILE__, __LINE__, __func__, _errcode)
506
507
513#define GKO_CURAND_ERROR(_errcode) \
514 ::gko::CurandError(__FILE__, __LINE__, __func__, _errcode)
515
516
522#define GKO_CUSPARSE_ERROR(_errcode) \
523 ::gko::CusparseError(__FILE__, __LINE__, __func__, _errcode)
524
525
531#define GKO_CUFFT_ERROR(_errcode) \
532 ::gko::CufftError(__FILE__, __LINE__, __func__, _errcode)
533
534
540#define GKO_ASSERT_NO_CUDA_ERRORS(_cuda_call) \
541 do { \
542 auto _errcode = _cuda_call; \
543 if (_errcode != cudaSuccess) { \
544 throw GKO_CUDA_ERROR(_errcode); \
545 } \
546 } while (false)
547
548
554#define GKO_ASSERT_NO_CUBLAS_ERRORS(_cublas_call) \
555 do { \
556 auto _errcode = _cublas_call; \
557 if (_errcode != CUBLAS_STATUS_SUCCESS) { \
558 throw GKO_CUBLAS_ERROR(_errcode); \
559 } \
560 } while (false)
561
562
568#define GKO_ASSERT_NO_CURAND_ERRORS(_curand_call) \
569 do { \
570 auto _errcode = _curand_call; \
571 if (_errcode != CURAND_STATUS_SUCCESS) { \
572 throw GKO_CURAND_ERROR(_errcode); \
573 } \
574 } while (false)
575
576
582#define GKO_ASSERT_NO_CUSPARSE_ERRORS(_cusparse_call) \
583 do { \
584 auto _errcode = _cusparse_call; \
585 if (_errcode != CUSPARSE_STATUS_SUCCESS) { \
586 throw GKO_CUSPARSE_ERROR(_errcode); \
587 } \
588 } while (false)
589
590
596#define GKO_ASSERT_NO_CUFFT_ERRORS(_cufft_call) \
597 do { \
598 auto _errcode = _cufft_call; \
599 if (_errcode != CUFFT_SUCCESS) { \
600 throw GKO_CUFFT_ERROR(_errcode); \
601 } \
602 } while (false)
603
604
610#define GKO_HIP_ERROR(_errcode) \
611 ::gko::HipError(__FILE__, __LINE__, __func__, _errcode)
612
613
619#define GKO_HIPBLAS_ERROR(_errcode) \
620 ::gko::HipblasError(__FILE__, __LINE__, __func__, _errcode)
621
622
628#define GKO_HIPRAND_ERROR(_errcode) \
629 ::gko::HiprandError(__FILE__, __LINE__, __func__, _errcode)
630
631
637#define GKO_HIPSPARSE_ERROR(_errcode) \
638 ::gko::HipsparseError(__FILE__, __LINE__, __func__, _errcode)
639
640
646#define GKO_HIPFFT_ERROR(_errcode) \
647 ::gko::HipfftError(__FILE__, __LINE__, __func__, _errcode)
648
649
655#define GKO_ASSERT_NO_HIP_ERRORS(_hip_call) \
656 do { \
657 auto _errcode = _hip_call; \
658 if (_errcode != hipSuccess) { \
659 throw GKO_HIP_ERROR(_errcode); \
660 } \
661 } while (false)
662
663
669#define GKO_ASSERT_NO_HIPBLAS_ERRORS(_hipblas_call) \
670 do { \
671 auto _errcode = _hipblas_call; \
672 if (_errcode != HIPBLAS_STATUS_SUCCESS) { \
673 throw GKO_HIPBLAS_ERROR(_errcode); \
674 } \
675 } while (false)
676
677
683#define GKO_ASSERT_NO_HIPRAND_ERRORS(_hiprand_call) \
684 do { \
685 auto _errcode = _hiprand_call; \
686 if (_errcode != HIPRAND_STATUS_SUCCESS) { \
687 throw GKO_HIPRAND_ERROR(_errcode); \
688 } \
689 } while (false)
690
691
697#define GKO_ASSERT_NO_HIPSPARSE_ERRORS(_hipsparse_call) \
698 do { \
699 auto _errcode = _hipsparse_call; \
700 if (_errcode != HIPSPARSE_STATUS_SUCCESS) { \
701 throw GKO_HIPSPARSE_ERROR(_errcode); \
702 } \
703 } while (false)
704
705
711#define GKO_ASSERT_NO_HIPFFT_ERRORS(_hipfft_call) \
712 do { \
713 auto _errcode = _hipfft_call; \
714 if (_errcode != HIPFFT_SUCCESS) { \
715 throw GKO_HIPFFT_ERROR(_errcode); \
716 } \
717 } while (false)
718
719
725#define GKO_ASSERT_NO_MPI_ERRORS(_mpi_call) \
726 do { \
727 auto _errcode = _mpi_call; \
728 if (_errcode != MPI_SUCCESS) { \
729 throw GKO_MPI_ERROR(_errcode); \
730 } \
731 } while (false)
732
733
734namespace detail {
735
736
737template <typename T>
738inline T ensure_allocated_impl(T ptr, const std::string& file, int line,
739 const std::string& dev, size_type size)
740{
741 if (ptr == nullptr) {
742 throw AllocationError(file, line, dev, size);
743 }
744 return ptr;
745}
746
747
748} // namespace detail
749
750
765#define GKO_ENSURE_ALLOCATED(_ptr, _dev, _size) \
766 ::gko::detail::ensure_allocated_impl(_ptr, __FILE__, __LINE__, _dev, _size)
767
768
777#define GKO_ENSURE_IN_BOUNDS(_index, _bound) \
778 if (_index >= _bound) { \
779 throw ::gko::OutOfBoundsError(__FILE__, __LINE__, _index, _bound); \
780 } \
781 static_assert(true, \
782 "This assert is used to counter the false positive extra " \
783 "semi-colon warnings")
784
785
796#define GKO_ENSURE_COMPATIBLE_BOUNDS(_source, _target) \
797 if (_source > _target) { \
798 throw ::gko::OutOfBoundsError(__FILE__, __LINE__, _source, _target); \
799 } \
800 static_assert(true, \
801 "This assert is used to counter the false positive extra " \
802 "semi-colon warnings")
803
804
815#define GKO_STREAM_ERROR(_message) \
816 ::gko::StreamError(__FILE__, __LINE__, __func__, _message)
817
818
825#define GKO_KERNEL_NOT_FOUND \
826 { \
827 throw ::gko::KernelNotFound(__FILE__, __LINE__, __func__); \
828 } \
829 static_assert(true, \
830 "This assert is used to counter the false positive extra " \
831 "semi-colon warnings")
832
833
840#define GKO_UNSUPPORTED_MATRIX_PROPERTY(_message) \
841 { \
842 throw ::gko::UnsupportedMatrixProperty(__FILE__, __LINE__, _message); \
843 } \
844 static_assert(true, \
845 "This assert is used to counter the false positive extra " \
846 "semi-colon warnings")
847
848
859#define GKO_ASSERT_BLOCK_SIZE_CONFORMANT(_size, _block_size) \
860 if (_size % _block_size != 0) { \
861 throw BlockSizeError<decltype(_size)>(__FILE__, __LINE__, _block_size, \
862 _size); \
863 } \
864 static_assert(true, \
865 "This assert is used to counter the false positive extra " \
866 "semi-colon warnings")
867
868
876#define GKO_ASSERT_IS_SCALAR(_op) \
877 { \
878 auto sz = gko::detail::get_size(_op); \
879 if (sz[0] != 1 || sz[1] != 1) { \
880 throw ::gko::BadDimension(__FILE__, __LINE__, __func__, #_op, \
881 sz[0], sz[1], "expected scalar"); \
882 } \
883 } \
884 static_assert(true, \
885 "This assert is used to counter the false positive extra " \
886 "semi-colon warnings")
887
888
896#define GKO_INVALID_STATE(_message) \
897 { \
898 throw ::gko::InvalidStateError(__FILE__, __LINE__, __func__, \
899 _message); \
900 } \
901 static_assert(true, \
902 "This assert is used to counter the false positive extra " \
903 "semi-colon warnings")
904
905
914#define GKO_THROW_IF_INVALID(_condition, _message) \
915 { \
916 if (!(_condition)) { \
917 throw ::gko::InvalidStateError(__FILE__, __LINE__, __func__, \
918 _message); \
919 } \
920 } \
921 static_assert(true, \
922 "This assert is used to counter the false positive extra " \
923 "semi-colon warnings")
924
925
926} // namespace gko
927
928
929#endif // GKO_PUBLIC_CORE_BASE_EXCEPTION_HELPERS_HPP_
The Ginkgo namespace.
Definition abstract_factory.hpp:48
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:803
std::size_t size_type
Integral type used for allocation quantities.
Definition types.hpp:120