14#ifndef dealii_cxx26_inplace_vector_h
15#define dealii_cxx26_inplace_vector_h
20#ifdef DEAL_II_HAVE_CXX26
21# include <inplace_vector>
32# include <initializer_list>
34# include <type_traits>
37#include <boost/serialization/array_wrapper.hpp>
38#include <boost/serialization/collection_size_type.hpp>
39#include <boost/serialization/split_free.hpp>
45#ifndef DEAL_II_HAVE_CXX26
47 "The current operation requires more capacity than the "
48 "container can provide.");
78 template <
typename T, std::
size_t N>
118 internal_resize<true>(n);
128 throw std::bad_alloc();
136 template <
class InputIterator>
142 if constexpr (std::is_integral_v<InputIterator>)
144 static_cast<const T &
>(last));
146 internal_append<InputIterator, true, false>(
first, last);
149# ifdef DEAL_II_HAVE_CXX20
154 requires(std::is_trivially_copy_constructible_v<T>)
162 std::is_nothrow_copy_constructible_v<T>)
168# ifdef DEAL_II_HAVE_CXX20
173 requires(std::is_trivially_move_constructible_v<T>)
181 std::is_nothrow_move_constructible_v<T>)
184 internal_append<iterator, false, true>(other.begin(), other.end());
194 throw std::bad_alloc();
198# ifdef DEAL_II_HAVE_CXX20
203 requires(std::is_trivially_destructible_v<T>)
207# ifdef DEAL_II_HAVE_CXX20
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>))
242 if (std::addressof(other) !=
this)
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>)
265 std::is_nothrow_move_assignable_v<T>
266 &&std::is_nothrow_move_constructible_v<T>)
268 if (std::addressof(other) !=
this)
269 internal_assign<iterator, false, true>(other.begin(), other.end());
281 throw std::bad_alloc();
297 template <
class InputIterator>
301 if constexpr (std::is_integral_v<InputIterator>)
314 throw std::bad_alloc();
327 throw std::bad_alloc();
493 internal_resize<true>(n);
503 internal_resize<true>(n, value);
512 static constexpr void
516 throw std::bad_alloc();
523 static constexpr void
561 throw std::out_of_range(
"inplace_vector::at(): index " +
562 std::to_string(n) +
" out of range");
574 throw std::out_of_range(
"inplace_vector::at(): index " +
575 std::to_string(n) +
" out of range");
660 template <
class... Args>
664 internal_resize<true>(
size() + 1, std::forward<Args>(args)...);
677 internal_resize<true>(
size() + 1, value);
690 internal_resize<true>(
size() + 1, std::forward<T>(value));
702 internal_resize<true>(
size() - 1);
712 template <
class... Args>
717 internal_resize<false>(
size() + 1, std::forward<Args>(args)...);
731 internal_resize<false>(
size() + 1, value);
745 internal_resize<false>(
size() + 1, std::forward<T>(value));
753 template <
class... Args>
757 const auto index = position -
cbegin();
762 internal_resize<true>(
size() + 1, std::forward<Args>(args)...);
768 return begin() + index;
777 return emplace(position, value);
786 return emplace(position, std::move(value));
804 template <
typename InputIterator>
808 if constexpr (std::is_integral_v<InputIterator>)
812 static_cast<const T &
>(last));
816 const auto original_size =
size();
818 const auto index = position -
cbegin();
821 const auto n_new_elements =
822 internal_append<InputIterator>(
first, last);
824 std::rotate(
begin() + index,
begin() + original_size,
end());
825 return begin() + index;
835 return insert(position, init.begin(), init.end());
844 const auto index = position -
cbegin();
850 return begin() + index;
859 const auto original_size =
size();
860 const auto distance = std::distance(
first, last);
862 const auto last_index = last -
cbegin();
863 Assert(first_index <= last_index,
865 std::rotate(
begin() + first_index,
begin() + last_index,
end());
866 internal_resize<true>(
size() - distance);
869 return begin() + first_index;
877 std::is_nothrow_swappable_v<T> &&std::is_nothrow_move_constructible_v<T>)
879 if (std::addressof(other) ==
this)
882 auto &smaller =
size() < other.size() ? *this : other;
883 const auto smaller_size = smaller.size();
884 auto &larger =
size() < other.size() ? other : *
this;
888 for (std::size_t i = smaller.size(); i < larger.size(); ++i)
890 if constexpr (std::is_nothrow_move_constructible_v<T>)
891 smaller.push_back(std::move(larger[i]));
893 smaller.push_back(larger[i]);
895 larger.resize(smaller_size);
897 for (std::size_t i = 0; i < smaller_size; ++i)
898 swap(smaller[i], larger[i]);
906 std::is_nothrow_swappable_v<T> &&std::is_nothrow_move_constructible_v<T>)
960 return !(*
this == other);
979 template <
bool check =
false,
typename... Args>
984 static_assert(std::is_constructible_v<T, Args...>);
987 throw std::bad_alloc();
1002 new (
end()) T(std::forward<Args>(args)...);
1011 template <
typename InputIterator,
bool check = false,
bool move = false>
1014 !check && (move ? std::is_nothrow_move_assignable_v<T> :
1015 std::is_nothrow_copy_assignable_v<T>))
1017 static_assert(std::is_convertible_v<
decltype(*first), T>);
1031 internal_append<InputIterator, check, move>(
first, last);
1038 template <
typename InputIterator,
bool check = false,
bool move = false>
1041 !check && (move ? std::is_nothrow_move_constructible_v<T> :
1042 std::is_nothrow_copy_constructible_v<T>))
1044 static_assert(std::is_convertible_v<
decltype(*first), T>);
1051 while (
first != last)
1054 if constexpr (check)
1056 throw std::bad_alloc();
1078 std::conditional_t<N <= std::numeric_limits<std::uint8_t>::max(),
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).");
1101 template <
typename T, std::
size_t N>
1105 return (a.
size() == b.size()) && std::equal(a.
begin(), a.
end(), b.begin());
1113 template <
typename T, std::
size_t N>
1125 template <
typename T, std::
size_t N>
1129 return std::lexicographical_compare(a.
begin(), a.
end(), b.begin(), b.end());
1137 template <
typename T, std::
size_t N>
1149 template <
typename T, std::
size_t N>
1161 template <
typename T, std::
size_t N>
1174 template <
typename T, std::
size_t N,
typename U = T>
1178 auto it = std::remove(vec.
begin(), vec.
end(), value);
1179 const auto count = std::distance(it, vec.
end());
1190 template <
typename T, std::
size_t N,
typename Predicate>
1194 auto it = std::remove_if(vec.
begin(), vec.
end(), pred);
1195 const auto count = std::distance(it, vec.
end());
1202 using std::erase_if;
1203 using std::inplace_vector;
1211 namespace serialization
1218 template <
class Archive,
typename T, std::
size_t N>
1222 const unsigned int file_version)
1224 boost::serialization::split_free(ar, t, file_version);
1232 template <
class Archive,
typename T, std::
size_t N>
1235 const ::std_cxx26::inplace_vector<T, N> &vec,
1236 const unsigned int )
1238 const boost::serialization::collection_size_type count(vec.size());
1241 ar << boost::serialization::make_array(vec.data(), count);
1244 template <
class Archive,
typename T, std::
size_t N>
1248 const unsigned int )
1250 boost::serialization::collection_size_type count(vec.
size());
1254 ar >> boost::serialization::make_array(vec.
data(), count);
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(size_type n)
inplace_vector & operator=(const inplace_vector &other)
const_pointer const_iterator
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
buffer_size_type n_elements
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
#define DEAL_II_NAMESPACE_CLOSE
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)