deal.II version GIT relicensing-6960-g70e9c5b7be 2026-10-22 20:10:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
inplace_vector.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12#ifndef dealii_cxx26_inplace_vector_h
13#define dealii_cxx26_inplace_vector_h
14
15#include <deal.II/base/config.h>
16
17
18#ifdef DEAL_II_HAVE_CXX26
19# include <inplace_vector>
20#else
23
24// Header optimization: we can skip including utility and iterator and instead
25// rely on the implicit includes (which are smaller, e.g., <array> is less than
26// half the preprocessed size of <iterator>) from <array>
27# include <algorithm>
28# include <array>
29# include <cstdint>
30# include <initializer_list>
31# include <limits>
32# include <type_traits>
33#endif
34
35#include <boost/serialization/array_wrapper.hpp>
36#include <boost/serialization/collection_size_type.hpp>
37#include <boost/serialization/split_free.hpp>
38
40
41namespace std_cxx26
42{
43#ifndef DEAL_II_HAVE_CXX26
45 "The current operation requires more capacity than the "
46 "container can provide.");
47
76 template <typename T, std::size_t N>
78 {
79 public:
84 using value_type = T;
85 using size_type = std::size_t;
86 using difference_type = std::ptrdiff_t;
88 using const_reference = const value_type &;
90 using const_pointer = const value_type *;
93
94 using reverse_iterator = std::reverse_iterator<iterator>;
95 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
106 constexpr inplace_vector() noexcept
107 : n_elements(0)
108 {}
109
114 : n_elements(0)
115 {
116 internal_resize<true>(n);
117 }
118
122 inplace_vector(size_type n, const T &value)
123 : n_elements(0)
124 {
125 if (n > N)
126 throw std::bad_alloc();
127 internal_append(SingleInputIterator(std::addressof(value), 0),
128 SingleInputIterator(std::addressof(value), n));
129 }
130
134 template <class InputIterator>
135 inplace_vector(InputIterator first, InputIterator last)
136 : n_elements(0)
137 {
138 // If we have two integers (e.g., inplace_vector(42, 42)) then we should
139 // convert to the correct types and call the other constructor
140 if constexpr (std::is_integral_v<InputIterator>)
141 *this = inplace_vector(static_cast<size_type>(first),
142 static_cast<const T &>(last));
143 else
144 internal_append<InputIterator, true, false>(first, last);
145 }
146
147# ifdef DEAL_II_HAVE_CXX20
152 requires(std::is_trivially_copy_constructible_v<T>)
153 = default;
154# endif
155
159 inplace_vector(const inplace_vector &other) noexcept(
160 std::is_nothrow_copy_constructible_v<T>)
161 : n_elements(0)
162 {
163 internal_append(other.begin(), other.end());
164 }
165
166# ifdef DEAL_II_HAVE_CXX20
171 requires(std::is_trivially_move_constructible_v<T>)
172 = default;
173# endif
174
179 std::is_nothrow_move_constructible_v<T>)
180 : n_elements(0)
181 {
182 internal_append<iterator, false, true>(other.begin(), other.end());
183 }
184
188 constexpr inplace_vector(std::initializer_list<T> init)
189 : n_elements(0)
190 {
191 if (init.size() > N)
192 throw std::bad_alloc();
193 internal_append(init.begin(), init.end());
194 }
195
196# ifdef DEAL_II_HAVE_CXX20
201 requires(std::is_trivially_destructible_v<T>)
202 = default;
203# endif
204
205# ifdef DEAL_II_HAVE_CXX20
209 constexpr
210# endif
212 {
213 clear();
214 }
225# ifdef DEAL_II_HAVE_CXX20
228 requires((std::is_trivially_copy_assignable_v<T> &&
229 std::is_trivially_copy_constructible_v<T> &&
230 std::is_trivially_destructible_v<T>))
231 = default;
232# endif
233
239 {
240 if (std::addressof(other) != this)
241 internal_assign(other.begin(), other.end());
242
243 return *this;
244 }
245
246# ifdef DEAL_II_HAVE_CXX20
252 requires(std::is_trivially_move_assignable_v<T> &&
253 std::is_trivially_move_constructible_v<T> &&
254 std::is_trivially_destructible_v<T>)
255 = default;
256# endif
257
262 operator=(inplace_vector &&other) noexcept(
263 std::is_nothrow_move_assignable_v<T>
264 &&std::is_nothrow_move_constructible_v<T>)
265 {
266 if (std::addressof(other) != this)
267 internal_assign<iterator, false, true>(other.begin(), other.end());
268
269 return *this;
270 }
271
276 operator=(std::initializer_list<T> init)
277 {
278 if (init.size() > N)
279 throw std::bad_alloc();
280
281 internal_assign(init.begin(), init.end());
282
283 return *this;
284 }
295 template <class InputIterator>
296 void
297 assign(InputIterator first, InputIterator last)
298 {
299 if constexpr (std::is_integral_v<InputIterator>)
300 assign(static_cast<size_type>(first), static_cast<const T &>(last));
301 else
302 internal_assign(first, last);
303 }
304
308 void
309 assign(size_type n, const T &value)
310 {
311 if (n > N)
312 throw std::bad_alloc();
313
314 internal_assign(SingleInputIterator(std::addressof(value), 0),
315 SingleInputIterator(std::addressof(value), n));
316 }
317
321 void
322 assign(std::initializer_list<T> init)
323 {
324 if (init.size() > N)
325 throw std::bad_alloc();
326
327 internal_assign(init.begin(), init.end());
328 }
338 constexpr iterator
339 begin() noexcept
340 {
341 return std::addressof(elements[0]);
342 }
343
347 constexpr iterator
348 end() noexcept
349 {
350 return std::addressof(elements[0]) + size();
351 }
352
356 constexpr const_iterator
357 begin() const noexcept
358 {
359 return std::addressof(elements[0]);
360 }
361
365 constexpr const_iterator
366 end() const noexcept
367 {
368 return std::addressof(elements[0]) + size();
369 }
370
374 constexpr reverse_iterator
375 rbegin() noexcept
376 {
377 return reverse_iterator(end());
378 }
379
383 constexpr reverse_iterator
384 rend() noexcept
385 {
386 return reverse_iterator(begin());
387 }
388
392 constexpr const_reverse_iterator
393 rbegin() const noexcept
394 {
395 return const_reverse_iterator(end());
396 }
397
401 constexpr const_reverse_iterator
402 rend() const noexcept
403 {
405 }
406
410 constexpr const_iterator
411 cbegin() const noexcept
412 {
413 return std::addressof(elements[0]);
414 }
415
419 constexpr const_iterator
420 cend() const noexcept
421 {
422 return std::addressof(elements[0]) + size();
423 }
424
428 constexpr const_reverse_iterator
429 crbegin() const noexcept
430 {
432 }
433
437 constexpr const_reverse_iterator
438 crend() const noexcept
439 {
441 }
451 constexpr bool
452 empty() const noexcept
453 {
454 return size() == 0;
455 }
456
460 constexpr size_type
461 size() const noexcept
462 {
464 return n_elements;
465 }
466
470 static constexpr size_type
471 max_size() noexcept
472 {
473 return N;
474 }
475
479 static constexpr size_type
480 capacity() noexcept
481 {
482 return N;
483 }
484
488 void
490 {
491 internal_resize<true>(n);
492 }
493
498 void
499 resize(size_type n, const T &value)
500 {
501 internal_resize<true>(n, value);
502 }
503
510 static constexpr void
512 {
513 if (n > N)
514 throw std::bad_alloc();
515 }
516
521 static constexpr void
522 shrink_to_fit() noexcept
523 {}
536 {
538 return elements[n];
539 }
540
546 {
548 return elements[n];
549 }
550
557 {
558 if (!(n < size()))
559 throw std::out_of_range("inplace_vector::at(): index " +
560 std::to_string(n) + " out of range");
561 return elements[n];
562 }
563
569 at(size_type n) const
570 {
571 if (!(n < size()))
572 throw std::out_of_range("inplace_vector::at(): index " +
573 std::to_string(n) + " out of range");
574 return elements[n];
575 }
576
582 {
584 return elements[0];
585 }
586
591 front() const
592 {
594 return elements[0];
595 }
596
602 {
604 return elements[size() - 1];
605 }
606
611 back() const
612 {
614 return elements[size() - 1];
615 }
628 T *
629 data() noexcept
630 {
631 return begin();
632 }
633
639 const T *
640 data() const noexcept
641 {
642 return cbegin();
643 }
658 template <class... Args>
660 emplace_back(Args &&...args)
661 {
662 internal_resize<true>(size() + 1, std::forward<Args>(args)...);
663 return back();
664 }
665
673 push_back(const T &value)
674 {
675 internal_resize<true>(size() + 1, value);
676 return back();
677 }
678
686 push_back(T &&value)
687 {
688 internal_resize<true>(size() + 1, std::forward<T>(value));
689 return back();
690 }
691
696 void
698 {
700 internal_resize<true>(size() - 1);
701 }
702
710 template <class... Args>
713 {
715 internal_resize<false>(size() + 1, std::forward<Args>(args)...);
716 return back();
717 }
718
726 unchecked_push_back(const T &value)
727 {
729 internal_resize<false>(size() + 1, value);
730 return back();
731 }
732
741 {
743 internal_resize<false>(size() + 1, std::forward<T>(value));
744 return back();
745 }
746
751 template <class... Args>
753 emplace(const_iterator position, Args &&...args)
754 {
755 const auto index = position - cbegin();
756 AssertIndexRange(index, size());
757 // Since args may reference *this we have to construct the new object
758 // first: do that in the buffer and then rotate so it is in the correct
759 // place
760 internal_resize<true>(size() + 1, std::forward<Args>(args)...);
761
763 Assert(begin() + index <= end() - 1, ExcInternalError());
764 std::rotate(begin() + index, end() - 1, end());
765
766 return begin() + index;
767 }
768
773 insert(const_iterator position, const T &value)
774 {
775 return emplace(position, value);
776 }
777
782 insert(const_iterator position, T &&value)
783 {
784 return emplace(position, std::move(value));
785 }
786
791 insert(const_iterator position, size_type n, const T &value)
792 {
793 return insert(position,
794 SingleInputIterator(std::addressof(value), 0),
795 SingleInputIterator(std::addressof(value), n));
796 }
797
802 template <typename InputIterator>
804 insert(const_iterator position, InputIterator first, InputIterator last)
805 {
806 if constexpr (std::is_integral_v<InputIterator>)
807 {
808 return insert(position,
809 static_cast<size_type>(first),
810 static_cast<const T &>(last));
811 }
812 else
813 {
814 const auto original_size = size();
815 // TODO we need a nicer way to check for valid iterators
816 const auto index = position - cbegin();
817 Assert(position == cend() || index < size(),
818 ExcMessage("out of range"));
819 const auto n_new_elements =
820 internal_append<InputIterator>(first, last);
821 Assert(position + n_new_elements <= end(), ExcInternalError());
822 std::rotate(begin() + index, begin() + original_size, end());
823 return begin() + index;
824 }
825 }
826
831 insert(const_iterator position, std::initializer_list<T> init)
832 {
833 return insert(position, init.begin(), init.end());
834 }
835
841 {
842 const auto index = position - cbegin();
843 AssertIndexRange(index, size());
844 Assert(begin() + index + 1 <= end(), ExcInternalError());
845 std::move(begin() + index + 1, end(), begin() + index);
846 pop_back();
847
848 return begin() + index;
849 }
850
856 {
857 const auto original_size = size();
858 const auto distance = std::distance(first, last);
859 const auto first_index = first - begin();
860 const auto last_index = last - cbegin();
861 Assert(first_index <= last_index,
862 ExcMessage("The given range is not valid."));
863 std::rotate(begin() + first_index, begin() + last_index, end());
864 internal_resize<true>(size() - distance);
865 Assert(size() + distance == original_size, ExcInternalError());
866
867 return begin() + first_index;
868 }
869
873 void
874 swap(inplace_vector &other) noexcept(
875 std::is_nothrow_swappable_v<T> &&std::is_nothrow_move_constructible_v<T>)
876 {
877 if (std::addressof(other) == this)
878 return;
879
880 auto &smaller = size() < other.size() ? *this : other;
881 const auto smaller_size = smaller.size();
882 auto &larger = size() < other.size() ? other : *this;
883
884 // Do the same thing as GCC: copy or move elements from the larger to the
885 // smaller and then swap elements with the same indices.
886 for (std::size_t i = smaller.size(); i < larger.size(); ++i)
887 {
888 if constexpr (std::is_nothrow_move_constructible_v<T>)
889 smaller.push_back(std::move(larger[i]));
890 else
891 smaller.push_back(larger[i]);
892 }
893 larger.resize(smaller_size);
894 using std::swap;
895 for (std::size_t i = 0; i < smaller_size; ++i)
896 swap(smaller[i], larger[i]);
897 }
898
902 friend void
904 std::is_nothrow_swappable_v<T> &&std::is_nothrow_move_constructible_v<T>)
905 {
906 x.swap(y);
907 }
908
912 constexpr void
913 clear() noexcept
914 {
916 }
917
919 private:
932 {
933 public:
934 using value_type = const T;
935 using reference = const T &;
936 using iterator_category = std::input_iterator_tag;
937
939 : ptr(value)
940 , index(index)
941 {}
942
944 operator*() const
945 {
946 return *ptr;
947 }
948
949 bool
950 operator==(const SingleInputIterator &other) const
951 {
952 return ptr == other.ptr && index == other.index;
953 }
954
955 bool
956 operator!=(const SingleInputIterator &other) const
957 {
958 return !(*this == other);
959 }
960
963 {
964 ++index;
965 return *this;
966 }
967
968 private:
969 const T *ptr;
970
971 std::size_t index;
972 };
973
977 template <bool check = false, typename... Args>
978 constexpr void
979 internal_resize(const size_type n, Args &&...args) noexcept(!check)
980 {
982 static_assert(std::is_constructible_v<T, Args...>);
983 if constexpr (check)
984 if (n > N)
985 throw std::bad_alloc();
986
987 // Here and elsewhere we avoid std::uninitialized_copy() etc. so that we
988 // maintain the invariant that n_elements is always correct
989 if (n < size())
990 for (size_type i = size(); i > n; --i)
991 {
992 Assert(size() > 0, ExcInternalError());
993 back().~T();
994 --n_elements;
995 }
996 else
997 for (size_type i = size(); i < n; ++i)
998 {
1000 new (end()) T(std::forward<Args>(args)...);
1001 ++n_elements;
1002 }
1003 }
1004
1009 template <typename InputIterator, bool check = false, bool move = false>
1010 void
1011 internal_assign(InputIterator first, InputIterator last) noexcept(
1012 !check && (move ? std::is_nothrow_move_assignable_v<T> :
1013 std::is_nothrow_copy_assignable_v<T>))
1014 {
1015 static_assert(std::is_convertible_v<decltype(*first), T>);
1016 size_type i = 0;
1017 while (i < size() && first != last)
1018 {
1019 if constexpr (move)
1020 elements[i] = std::move(*first);
1021 else
1022 elements[i] = *first;
1023 ++i;
1024 ++first;
1025 }
1026 if (first == last)
1027 resize(i);
1028 else
1029 internal_append<InputIterator, check, move>(first, last);
1030 }
1031
1036 template <typename InputIterator, bool check = false, bool move = false>
1037 constexpr size_type
1038 internal_append(InputIterator first, InputIterator last) noexcept(
1039 !check && (move ? std::is_nothrow_move_constructible_v<T> :
1040 std::is_nothrow_copy_constructible_v<T>))
1041 {
1042 static_assert(std::is_convertible_v<decltype(*first), T>);
1043
1044 // TODO: for constexpr-ification with C++17 we need to find a way to copy
1045 // trivial values over without using new() (since that is not constexpr
1046 // until C++26)
1047
1048 size_type count = 0;
1049 while (first != last)
1050 {
1052 if constexpr (check)
1053 if (size() == N)
1054 throw std::bad_alloc();
1055 if constexpr (move)
1056 new (end()) T(std::move(*first));
1057 else
1058 new (end()) T(*first);
1059 ++n_elements;
1060 ++first;
1061 ++count;
1062 }
1063 return count;
1064 }
1065
1070 union
1071 {
1072 T elements[N > 0 ? N : 1];
1073 };
1074
1076 std::conditional_t<N <= std::numeric_limits<std::uint8_t>::max(),
1077 std::uint8_t,
1078 std::uint16_t>;
1079 static_assert(
1080 N <= std::numeric_limits<buffer_size_type>::max(),
1081 "This class only supports objects of size <= the maximum size of a "
1082 "std::uint16_t (65535).");
1083
1088 };
1089
1099 template <typename T, std::size_t N>
1100 bool
1102 {
1103 return (a.size() == b.size()) && std::equal(a.begin(), a.end(), b.begin());
1104 }
1105
1111 template <typename T, std::size_t N>
1112 bool
1114 {
1115 return !(a == b);
1116 }
1117
1123 template <typename T, std::size_t N>
1124 bool
1126 {
1127 return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
1128 }
1129
1135 template <typename T, std::size_t N>
1136 bool
1138 {
1139 return b < a;
1140 }
1141
1147 template <typename T, std::size_t N>
1148 bool
1149 operator<=(const inplace_vector<T, N> &a, const inplace_vector<T, N> &b)
1150 {
1151 return !(b < a);
1152 }
1153
1159 template <typename T, std::size_t N>
1160 bool
1162 {
1163 return !(a < b);
1164 }
1172 template <typename T, std::size_t N, typename U = T>
1173 std::size_t
1175 {
1176 auto it = std::remove(vec.begin(), vec.end(), value);
1177 const auto count = std::distance(it, vec.end());
1178 Assert(vec.size() >= count, ExcInternalError());
1179 vec.resize(vec.size() - count);
1180 return count;
1181 }
1182
1188 template <typename T, std::size_t N, typename Predicate>
1189 std::size_t
1191 {
1192 auto it = std::remove_if(vec.begin(), vec.end(), pred);
1193 const auto count = std::distance(it, vec.end());
1194 Assert(vec.size() >= count, ExcInternalError());
1195 vec.resize(vec.size() - count);
1196 return count;
1197 }
1198#else
1199 using std::erase;
1200 using std::erase_if;
1201 using std::inplace_vector;
1202#endif
1203} // namespace std_cxx26
1204
1206
1207namespace boost
1208{
1209 namespace serialization
1210 {
1216 template <class Archive, typename T, std::size_t N>
1217 inline void
1218 serialize(Archive &ar,
1220 const unsigned int file_version)
1221 {
1222 boost::serialization::split_free(ar, t, file_version);
1223 }
1224
1230 template <class Archive, typename T, std::size_t N>
1231 inline void
1232 save(Archive &ar,
1233 const ::std_cxx26::inplace_vector<T, N> &vec,
1234 const unsigned int /*version*/)
1235 {
1236 const boost::serialization::collection_size_type count(vec.size());
1237 ar << count;
1238 if (!vec.empty())
1239 ar << boost::serialization::make_array(vec.data(), count);
1240 }
1241
1242 template <class Archive, typename T, std::size_t N>
1243 inline void
1244 load(Archive &ar,
1246 const unsigned int /*version*/)
1247 {
1248 boost::serialization::collection_size_type count(vec.size());
1249 ar >> count;
1250 vec.resize(count);
1251 if (!vec.empty())
1252 ar >> boost::serialization::make_array(vec.data(), count);
1253 }
1254 } // namespace serialization
1255} // namespace boost
1256
1257#endif
bool operator==(const SingleInputIterator &other) const
bool operator!=(const SingleInputIterator &other) const
SingleInputIterator(const T *value, size_type index)
constexpr inplace_vector() noexcept
inplace_vector(InputIterator first, InputIterator last)
iterator insert(const_iterator position, const T &value)
inplace_vector & operator=(std::initializer_list< T > init)
const_reference back() const
bool operator>(const inplace_vector< T, N > &a, const inplace_vector< T, N > &b)
constexpr iterator end() noexcept
constexpr reverse_iterator rbegin() noexcept
constexpr const_reverse_iterator crbegin() const noexcept
constexpr void internal_resize(const size_type n, Args &&...args) noexcept(!check)
const_reference front() const
iterator erase(const_iterator position)
constexpr size_type size() const noexcept
reference push_back(const T &value)
reference at(size_type n)
void assign(InputIterator first, InputIterator last)
std::size_t erase_if(std_cxx26::inplace_vector< T, N > &vec, Predicate pred)
void assign(std::initializer_list< T > init)
constexpr const_reverse_iterator crend() const noexcept
constexpr iterator begin() noexcept
std::reverse_iterator< const_iterator > const_reverse_iterator
reference emplace_back(Args &&...args)
constexpr inplace_vector(std::initializer_list< T > init)
iterator emplace(const_iterator position, Args &&...args)
void resize(size_type n, const T &value)
void swap(inplace_vector &other) noexcept(std::is_nothrow_swappable_v< T > &&std::is_nothrow_move_constructible_v< T >)
const_reference at(size_type n) const
constexpr const_iterator begin() const noexcept
iterator erase(const_iterator first, const_iterator last)
bool operator>=(const inplace_vector< T, N > &a, const inplace_vector< T, N > &b)
constexpr reverse_iterator rend() noexcept
reference unchecked_push_back(const T &value)
constexpr bool empty() const noexcept
bool operator!=(const inplace_vector< T, N > &a, const inplace_vector< T, N > &b)
friend void swap(inplace_vector &x, inplace_vector &y) noexcept(std::is_nothrow_swappable_v< T > &&std::is_nothrow_move_constructible_v< T >)
iterator insert(const_iterator position, InputIterator first, InputIterator last)
inplace_vector(const inplace_vector &other) noexcept(std::is_nothrow_copy_constructible_v< T >)
static constexpr size_type max_size() noexcept
void internal_assign(InputIterator first, InputIterator last) noexcept(!check &&(move ? std::is_nothrow_move_assignable_v< T > :std::is_nothrow_copy_assignable_v< T >))
std::reverse_iterator< iterator > reverse_iterator
static constexpr void reserve(size_type n)
inplace_vector & operator=(const inplace_vector &other)
const value_type & const_reference
const value_type * const_pointer
constexpr const_iterator cend() const noexcept
reference push_back(T &&value)
std::size_t erase(std_cxx26::inplace_vector< T, N > &vec, const U &value)
reference operator[](size_type n)
static constexpr void shrink_to_fit() noexcept
const T * data() const noexcept
const_reference operator[](size_type n) const
bool operator==(const inplace_vector< T, N > &a, const inplace_vector< T, N > &b)
inplace_vector(size_type n, const T &value)
std::ptrdiff_t difference_type
constexpr const_iterator cbegin() const noexcept
iterator insert(const_iterator position, size_type n, const T &value)
iterator insert(const_iterator position, T &&value)
iterator insert(const_iterator position, std::initializer_list< T > init)
constexpr const_iterator end() const noexcept
reference unchecked_push_back(T &&value)
reference unchecked_emplace_back(Args &&...args)
std::conditional_t< N<=std::numeric_limits< std::uint8_t >::max(), std::uint8_t, std::uint16_t > buffer_size_type
constexpr size_type internal_append(InputIterator first, InputIterator last) noexcept(!check &&(move ? std::is_nothrow_move_constructible_v< T > :std::is_nothrow_copy_constructible_v< T >))
void assign(size_type n, const T &value)
constexpr const_reverse_iterator rend() const noexcept
constexpr const_reverse_iterator rbegin() const noexcept
inplace_vector(inplace_vector &&other) noexcept(std::is_nothrow_move_constructible_v< T >)
static constexpr size_type capacity() noexcept
constexpr void clear() noexcept
inplace_vector & operator=(inplace_vector &&other) noexcept(std::is_nothrow_move_assignable_v< T > &&std::is_nothrow_move_constructible_v< T >)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
Point< 2 > first
Definition grid_out.cc:4639
static ::ExceptionBase & ExcCapacityExceeded()
static ::ExceptionBase & ExcEmptyObject()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
void load(Archive &ar, ::std_cxx26::inplace_vector< T, N > &vec, const unsigned int)
void save(Archive &ar, const ::std_cxx26::inplace_vector< T, N > &vec, const unsigned int)
void serialize(Archive &ar, ::std_cxx26::inplace_vector< T, N > &t, const unsigned int file_version)
bool operator<(const SynchronousIterators< Iterators > &a, const SynchronousIterators< Iterators > &b)