deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20: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: 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// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14#ifndef dealii_cxx26_inplace_vector_h
15#define dealii_cxx26_inplace_vector_h
16
17#include <deal.II/base/config.h>
18
19
20#ifdef DEAL_II_HAVE_CXX26
21# include <inplace_vector>
22#else
25
26// Header optimization: we can skip including utility and iterator and instead
27// rely on the implicit includes (which are smaller, e.g., <array> is less than
28// half the preprocessed size of <iterator>) from <array>
29# include <algorithm>
30# include <array>
31# include <cstdint>
32# include <initializer_list>
33# include <limits>
34# include <type_traits>
35#endif
36
37#include <boost/serialization/array_wrapper.hpp>
38#include <boost/serialization/collection_size_type.hpp>
39#include <boost/serialization/split_free.hpp>
40
42
43namespace std_cxx26
44{
45#ifndef DEAL_II_HAVE_CXX26
47 "The current operation requires more capacity than the "
48 "container can provide.");
49
78 template <typename T, std::size_t N>
80 {
81 public:
86 using value_type = T;
87 using size_type = std::size_t;
88 using difference_type = std::ptrdiff_t;
90 using const_reference = const value_type &;
92 using const_pointer = const value_type *;
95
96 using reverse_iterator = std::reverse_iterator<iterator>;
97 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
108 constexpr inplace_vector() noexcept
109 : n_elements(0)
110 {}
111
116 : n_elements(0)
117 {
118 internal_resize<true>(n);
119 }
120
124 inplace_vector(size_type n, const T &value)
125 : n_elements(0)
126 {
127 if (n > N)
128 throw std::bad_alloc();
129 internal_append(SingleInputIterator(std::addressof(value), 0),
130 SingleInputIterator(std::addressof(value), n));
131 }
132
136 template <class InputIterator>
137 inplace_vector(InputIterator first, InputIterator last)
138 : n_elements(0)
139 {
140 // If we have two integers (e.g., inplace_vector(42, 42)) then we should
141 // convert to the correct types and call the other constructor
142 if constexpr (std::is_integral_v<InputIterator>)
143 *this = inplace_vector(static_cast<size_type>(first),
144 static_cast<const T &>(last));
145 else
146 internal_append<InputIterator, true, false>(first, last);
147 }
148
149# ifdef DEAL_II_HAVE_CXX20
154 requires(std::is_trivially_copy_constructible_v<T>)
155 = default;
156# endif
157
161 inplace_vector(const inplace_vector &other) noexcept(
162 std::is_nothrow_copy_constructible_v<T>)
163 : n_elements(0)
164 {
165 internal_append(other.begin(), other.end());
166 }
167
168# ifdef DEAL_II_HAVE_CXX20
173 requires(std::is_trivially_move_constructible_v<T>)
174 = default;
175# endif
176
181 std::is_nothrow_move_constructible_v<T>)
182 : n_elements(0)
183 {
184 internal_append<iterator, false, true>(other.begin(), other.end());
185 }
186
190 constexpr inplace_vector(std::initializer_list<T> init)
191 : n_elements(0)
192 {
193 if (init.size() > N)
194 throw std::bad_alloc();
195 internal_append(init.begin(), init.end());
196 }
197
198# ifdef DEAL_II_HAVE_CXX20
203 requires(std::is_trivially_destructible_v<T>)
204 = default;
205# endif
206
207# ifdef DEAL_II_HAVE_CXX20
211 constexpr
212# endif
214 {
215 clear();
216 }
227# ifdef DEAL_II_HAVE_CXX20
230 requires((std::is_trivially_copy_assignable_v<T> &&
231 std::is_trivially_copy_constructible_v<T> &&
232 std::is_trivially_destructible_v<T>))
233 = default;
234# endif
235
241 {
242 if (std::addressof(other) != this)
243 internal_assign(other.begin(), other.end());
244
245 return *this;
246 }
247
248# ifdef DEAL_II_HAVE_CXX20
254 requires(std::is_trivially_move_assignable_v<T> &&
255 std::is_trivially_move_constructible_v<T> &&
256 std::is_trivially_destructible_v<T>)
257 = default;
258# endif
259
264 operator=(inplace_vector &&other) noexcept(
265 std::is_nothrow_move_assignable_v<T>
266 &&std::is_nothrow_move_constructible_v<T>)
267 {
268 if (std::addressof(other) != this)
269 internal_assign<iterator, false, true>(other.begin(), other.end());
270
271 return *this;
272 }
273
278 operator=(std::initializer_list<T> init)
279 {
280 if (init.size() > N)
281 throw std::bad_alloc();
282
283 internal_assign(init.begin(), init.end());
284
285 return *this;
286 }
297 template <class InputIterator>
298 void
299 assign(InputIterator first, InputIterator last)
300 {
301 if constexpr (std::is_integral_v<InputIterator>)
302 assign(static_cast<size_type>(first), static_cast<const T &>(last));
303 else
304 internal_assign(first, last);
305 }
306
310 void
311 assign(size_type n, const T &value)
312 {
313 if (n > N)
314 throw std::bad_alloc();
315
316 internal_assign(SingleInputIterator(std::addressof(value), 0),
317 SingleInputIterator(std::addressof(value), n));
318 }
319
323 void
324 assign(std::initializer_list<T> init)
325 {
326 if (init.size() > N)
327 throw std::bad_alloc();
328
329 internal_assign(init.begin(), init.end());
330 }
340 constexpr iterator
341 begin() noexcept
342 {
343 return std::addressof(elements[0]);
344 }
345
349 constexpr iterator
350 end() noexcept
351 {
352 return std::addressof(elements[0]) + size();
353 }
354
358 constexpr const_iterator
359 begin() const noexcept
360 {
361 return std::addressof(elements[0]);
362 }
363
367 constexpr const_iterator
368 end() const noexcept
369 {
370 return std::addressof(elements[0]) + size();
371 }
372
376 constexpr reverse_iterator
377 rbegin() noexcept
378 {
379 return reverse_iterator(end());
380 }
381
385 constexpr reverse_iterator
386 rend() noexcept
387 {
388 return reverse_iterator(begin());
389 }
390
394 constexpr const_reverse_iterator
395 rbegin() const noexcept
396 {
397 return const_reverse_iterator(end());
398 }
399
403 constexpr const_reverse_iterator
404 rend() const noexcept
405 {
407 }
408
412 constexpr const_iterator
413 cbegin() const noexcept
414 {
415 return std::addressof(elements[0]);
416 }
417
421 constexpr const_iterator
422 cend() const noexcept
423 {
424 return std::addressof(elements[0]) + size();
425 }
426
430 constexpr const_reverse_iterator
431 crbegin() const noexcept
432 {
434 }
435
439 constexpr const_reverse_iterator
440 crend() const noexcept
441 {
443 }
453 constexpr bool
454 empty() const noexcept
455 {
456 return size() == 0;
457 }
458
462 constexpr size_type
463 size() const noexcept
464 {
466 return n_elements;
467 }
468
472 static constexpr size_type
473 max_size() noexcept
474 {
475 return N;
476 }
477
481 static constexpr size_type
482 capacity() noexcept
483 {
484 return N;
485 }
486
490 void
492 {
493 internal_resize<true>(n);
494 }
495
500 void
501 resize(size_type n, const T &value)
502 {
503 internal_resize<true>(n, value);
504 }
505
512 static constexpr void
514 {
515 if (n > N)
516 throw std::bad_alloc();
517 }
518
523 static constexpr void
524 shrink_to_fit() noexcept
525 {}
538 {
540 return elements[n];
541 }
542
548 {
550 return elements[n];
551 }
552
559 {
560 if (!(n < size()))
561 throw std::out_of_range("inplace_vector::at(): index " +
562 std::to_string(n) + " out of range");
563 return elements[n];
564 }
565
571 at(size_type n) const
572 {
573 if (!(n < size()))
574 throw std::out_of_range("inplace_vector::at(): index " +
575 std::to_string(n) + " out of range");
576 return elements[n];
577 }
578
584 {
586 return elements[0];
587 }
588
593 front() const
594 {
596 return elements[0];
597 }
598
604 {
606 return elements[size() - 1];
607 }
608
613 back() const
614 {
616 return elements[size() - 1];
617 }
630 T *
631 data() noexcept
632 {
633 return begin();
634 }
635
641 const T *
642 data() const noexcept
643 {
644 return cbegin();
645 }
660 template <class... Args>
662 emplace_back(Args &&...args)
663 {
664 internal_resize<true>(size() + 1, std::forward<Args>(args)...);
665 return back();
666 }
667
675 push_back(const T &value)
676 {
677 internal_resize<true>(size() + 1, value);
678 return back();
679 }
680
688 push_back(T &&value)
689 {
690 internal_resize<true>(size() + 1, std::forward<T>(value));
691 return back();
692 }
693
698 void
700 {
702 internal_resize<true>(size() - 1);
703 }
704
712 template <class... Args>
715 {
717 internal_resize<false>(size() + 1, std::forward<Args>(args)...);
718 return back();
719 }
720
728 unchecked_push_back(const T &value)
729 {
731 internal_resize<false>(size() + 1, value);
732 return back();
733 }
734
743 {
745 internal_resize<false>(size() + 1, std::forward<T>(value));
746 return back();
747 }
748
753 template <class... Args>
755 emplace(const_iterator position, Args &&...args)
756 {
757 const auto index = position - cbegin();
758 AssertIndexRange(index, size());
759 // Since args may reference *this we have to construct the new object
760 // first: do that in the buffer and then rotate so it is in the correct
761 // place
762 internal_resize<true>(size() + 1, std::forward<Args>(args)...);
763
765 Assert(begin() + index <= end() - 1, ExcInternalError());
766 std::rotate(begin() + index, end() - 1, end());
767
768 return begin() + index;
769 }
770
775 insert(const_iterator position, const T &value)
776 {
777 return emplace(position, value);
778 }
779
784 insert(const_iterator position, T &&value)
785 {
786 return emplace(position, std::move(value));
787 }
788
793 insert(const_iterator position, size_type n, const T &value)
794 {
795 return insert(position,
796 SingleInputIterator(std::addressof(value), 0),
797 SingleInputIterator(std::addressof(value), n));
798 }
799
804 template <typename InputIterator>
806 insert(const_iterator position, InputIterator first, InputIterator last)
807 {
808 if constexpr (std::is_integral_v<InputIterator>)
809 {
810 return insert(position,
811 static_cast<size_type>(first),
812 static_cast<const T &>(last));
813 }
814 else
815 {
816 const auto original_size = size();
817 // TODO we need a nicer way to check for valid iterators
818 const auto index = position - cbegin();
819 Assert(position == cend() || index < size(),
820 ExcMessage("out of range"));
821 const auto n_new_elements =
822 internal_append<InputIterator>(first, last);
823 Assert(position + n_new_elements <= end(), ExcInternalError());
824 std::rotate(begin() + index, begin() + original_size, end());
825 return begin() + index;
826 }
827 }
828
833 insert(const_iterator position, std::initializer_list<T> init)
834 {
835 return insert(position, init.begin(), init.end());
836 }
837
843 {
844 const auto index = position - cbegin();
845 AssertIndexRange(index, size());
846 Assert(begin() + index + 1 <= end(), ExcInternalError());
847 std::move(begin() + index + 1, end(), begin() + index);
848 pop_back();
849
850 return begin() + index;
851 }
852
858 {
859 const auto original_size = size();
860 const auto distance = std::distance(first, last);
861 const auto first_index = first - begin();
862 const auto last_index = last - cbegin();
863 Assert(first_index <= last_index,
864 ExcMessage("The given range is not valid."));
865 std::rotate(begin() + first_index, begin() + last_index, end());
866 internal_resize<true>(size() - distance);
867 Assert(size() + distance == original_size, ExcInternalError());
868
869 return begin() + first_index;
870 }
871
875 void
876 swap(inplace_vector &other) noexcept(
877 std::is_nothrow_swappable_v<T> &&std::is_nothrow_move_constructible_v<T>)
878 {
879 if (std::addressof(other) == this)
880 return;
881
882 auto &smaller = size() < other.size() ? *this : other;
883 const auto smaller_size = smaller.size();
884 auto &larger = size() < other.size() ? other : *this;
885
886 // Do the same thing as GCC: copy or move elements from the larger to the
887 // smaller and then swap elements with the same indices.
888 for (std::size_t i = smaller.size(); i < larger.size(); ++i)
889 {
890 if constexpr (std::is_nothrow_move_constructible_v<T>)
891 smaller.push_back(std::move(larger[i]));
892 else
893 smaller.push_back(larger[i]);
894 }
895 larger.resize(smaller_size);
896 using std::swap;
897 for (std::size_t i = 0; i < smaller_size; ++i)
898 swap(smaller[i], larger[i]);
899 }
900
904 friend void
906 std::is_nothrow_swappable_v<T> &&std::is_nothrow_move_constructible_v<T>)
907 {
908 x.swap(y);
909 }
910
914 constexpr void
915 clear() noexcept
916 {
918 }
919
921 private:
934 {
935 public:
936 using value_type = const T;
937 using reference = const T &;
938 using iterator_category = std::input_iterator_tag;
939
941 : ptr(value)
942 , index(index)
943 {}
944
946 operator*() const
947 {
948 return *ptr;
949 }
950
951 bool
952 operator==(const SingleInputIterator &other) const
953 {
954 return ptr == other.ptr && index == other.index;
955 }
956
957 bool
958 operator!=(const SingleInputIterator &other) const
959 {
960 return !(*this == other);
961 }
962
965 {
966 ++index;
967 return *this;
968 }
969
970 private:
971 const T *ptr;
972
973 std::size_t index;
974 };
975
979 template <bool check = false, typename... Args>
980 constexpr void
981 internal_resize(const size_type n, Args &&...args) noexcept(!check)
982 {
984 static_assert(std::is_constructible_v<T, Args...>);
985 if constexpr (check)
986 if (n > N)
987 throw std::bad_alloc();
988
989 // Here and elsewhere we avoid std::uninitialized_copy() etc. so that we
990 // maintain the invariant that n_elements is always correct
991 if (n < size())
992 for (size_type i = size(); i > n; --i)
993 {
994 Assert(size() > 0, ExcInternalError());
995 back().~T();
996 --n_elements;
997 }
998 else
999 for (size_type i = size(); i < n; ++i)
1000 {
1002 new (end()) T(std::forward<Args>(args)...);
1003 ++n_elements;
1004 }
1005 }
1006
1011 template <typename InputIterator, bool check = false, bool move = false>
1012 void
1013 internal_assign(InputIterator first, InputIterator last) noexcept(
1014 !check && (move ? std::is_nothrow_move_assignable_v<T> :
1015 std::is_nothrow_copy_assignable_v<T>))
1016 {
1017 static_assert(std::is_convertible_v<decltype(*first), T>);
1018 size_type i = 0;
1019 while (i < size() && first != last)
1020 {
1021 if constexpr (move)
1022 elements[i] = std::move(*first);
1023 else
1024 elements[i] = *first;
1025 ++i;
1026 ++first;
1027 }
1028 if (first == last)
1029 resize(i);
1030 else
1031 internal_append<InputIterator, check, move>(first, last);
1032 }
1033
1038 template <typename InputIterator, bool check = false, bool move = false>
1039 constexpr size_type
1040 internal_append(InputIterator first, InputIterator last) noexcept(
1041 !check && (move ? std::is_nothrow_move_constructible_v<T> :
1042 std::is_nothrow_copy_constructible_v<T>))
1043 {
1044 static_assert(std::is_convertible_v<decltype(*first), T>);
1045
1046 // TODO: for constexpr-ification with C++17 we need to find a way to copy
1047 // trivial values over without using new() (since that is not constexpr
1048 // until C++26)
1049
1050 size_type count = 0;
1051 while (first != last)
1052 {
1054 if constexpr (check)
1055 if (size() == N)
1056 throw std::bad_alloc();
1057 if constexpr (move)
1058 new (end()) T(std::move(*first));
1059 else
1060 new (end()) T(*first);
1061 ++n_elements;
1062 ++first;
1063 ++count;
1064 }
1065 return count;
1066 }
1067
1072 union
1073 {
1074 T elements[N > 0 ? N : 1];
1075 };
1076
1078 std::conditional_t<N <= std::numeric_limits<std::uint8_t>::max(),
1079 std::uint8_t,
1080 std::uint16_t>;
1081 static_assert(
1082 N <= std::numeric_limits<buffer_size_type>::max(),
1083 "This class only supports objects of size <= the maximum size of a "
1084 "std::uint16_t (65535).");
1085
1090 };
1091
1101 template <typename T, std::size_t N>
1102 bool
1104 {
1105 return (a.size() == b.size()) && std::equal(a.begin(), a.end(), b.begin());
1106 }
1107
1113 template <typename T, std::size_t N>
1114 bool
1116 {
1117 return !(a == b);
1118 }
1119
1125 template <typename T, std::size_t N>
1126 bool
1128 {
1129 return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
1130 }
1131
1137 template <typename T, std::size_t N>
1138 bool
1140 {
1141 return b < a;
1142 }
1143
1149 template <typename T, std::size_t N>
1150 bool
1151 operator<=(const inplace_vector<T, N> &a, const inplace_vector<T, N> &b)
1152 {
1153 return !(b < a);
1154 }
1155
1161 template <typename T, std::size_t N>
1162 bool
1164 {
1165 return !(a < b);
1166 }
1174 template <typename T, std::size_t N, typename U = T>
1175 std::size_t
1177 {
1178 auto it = std::remove(vec.begin(), vec.end(), value);
1179 const auto count = std::distance(it, vec.end());
1180 Assert(vec.size() >= count, ExcInternalError());
1181 vec.resize(vec.size() - count);
1182 return count;
1183 }
1184
1190 template <typename T, std::size_t N, typename Predicate>
1191 std::size_t
1193 {
1194 auto it = std::remove_if(vec.begin(), vec.end(), pred);
1195 const auto count = std::distance(it, vec.end());
1196 Assert(vec.size() >= count, ExcInternalError());
1197 vec.resize(vec.size() - count);
1198 return count;
1199 }
1200#else
1201 using std::erase;
1202 using std::erase_if;
1203 using std::inplace_vector;
1204#endif
1205} // namespace std_cxx26
1206
1208
1209namespace boost
1210{
1211 namespace serialization
1212 {
1218 template <class Archive, typename T, std::size_t N>
1219 inline void
1220 serialize(Archive &ar,
1222 const unsigned int file_version)
1223 {
1224 boost::serialization::split_free(ar, t, file_version);
1225 }
1226
1232 template <class Archive, typename T, std::size_t N>
1233 inline void
1234 save(Archive &ar,
1235 const ::std_cxx26::inplace_vector<T, N> &vec,
1236 const unsigned int /*version*/)
1237 {
1238 const boost::serialization::collection_size_type count(vec.size());
1239 ar << count;
1240 if (!vec.empty())
1241 ar << boost::serialization::make_array(vec.data(), count);
1242 }
1243
1244 template <class Archive, typename T, std::size_t N>
1245 inline void
1246 load(Archive &ar,
1248 const unsigned int /*version*/)
1249 {
1250 boost::serialization::collection_size_type count(vec.size());
1251 ar >> count;
1252 vec.resize(count);
1253 if (!vec.empty())
1254 ar >> boost::serialization::make_array(vec.data(), count);
1255 }
1256 } // namespace serialization
1257} // namespace boost
1258
1259#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)