void
insert_back(ForwardIterator begin, ForwardIterator end);
+ /**
+ * Insert the range specified by @p begin and @p end after the element @p position.
+ *
+ * @note Unlike std::vector, this function uses random-access iterators so
+ * that the copy may be parallelized.
+ *
+ * @dealiiOperationIsMultithreaded
+ */
+ template <
+ typename RandomAccessIterator,
+ typename = std::enable_if_t<std::is_convertible_v<
+ typename std::iterator_traits<RandomAccessIterator>::iterator_category,
+ std::random_access_iterator_tag>>>
+ iterator
+ insert(const_iterator position,
+ RandomAccessIterator begin,
+ RandomAccessIterator end);
+
/**
* Fills the vector with size() copies of a default constructed object.
*
+template <class T>
+template <typename RandomAccessIterator, typename>
+inline typename AlignedVector<T>::iterator
+AlignedVector<T>::insert(const_iterator position,
+ RandomAccessIterator begin,
+ RandomAccessIterator end)
+{
+ Assert(replicated_across_communicator == false,
+ ExcAlignedVectorChangeAfterReplication());
+ Assert(this->begin() <= position && position <= this->end(),
+ ExcMessage("The position iterator is not valid."));
+ const auto offset = position - this->begin();
+
+ const size_type old_size = size();
+ const size_type range_size = end - begin;
+ const size_type new_size = old_size + range_size;
+ if (range_size != 0)
+ {
+ // This is similar to allocate_and_move(), except that we need to move
+ // whatever was before position and whatever is after it into two
+ // different places
+ T *new_data_ptr = nullptr;
+ Utilities::System::posix_memalign(
+ reinterpret_cast<void **>(&new_data_ptr), 64, new_size * sizeof(T));
+
+ // Correctly handle the case where the range is inside the present array
+ // by creating a temporary.
+ AlignedVector<T> temporary(begin, end);
+ dealii::internal::AlignedVectorMoveConstruct<T *, T>(
+ elements.get(), elements.get() + offset, new_data_ptr);
+ dealii::internal::AlignedVectorMoveConstruct<T *, T>(
+ temporary.begin(), temporary.end(), new_data_ptr + offset);
+ dealii::internal::AlignedVectorMoveConstruct<T *, T>(
+ elements.get() + offset,
+ elements.get() + old_size,
+ new_data_ptr + offset + range_size);
+
+ Deleter deleter(this);
+ elements = decltype(elements)(new_data_ptr, std::move(deleter));
+ used_elements_end = elements.get() + new_size;
+ allocated_elements_end = elements.get() + new_size;
+ }
+ return this->begin() + offset;
+}
+
+
+
template <class T>
inline void
AlignedVector<T>::fill()
ExcInternalError());
}
- deallog << "Insertion: ";
+ // Also check large insertions for equality and iterator position
+ {
+ std::deque<unsigned int> temp(8192);
+ std::iota(temp.begin(), temp.end(), 0u);
+
+ VEC f(temp.begin(), temp.begin() + temp.size() / 4);
+ const auto it0 =
+ f.insert(f.end(), temp.begin() + temp.size() / 2, temp.end());
+ AssertThrow(static_cast<std::size_t>(it0 - f.begin()) == temp.size() / 4,
+ ExcInternalError());
+ AssertThrow(*it0 == temp[temp.size() / 2], ExcInternalError());
+ AssertThrow(*(it0 - 1) == temp[temp.size() / 4 - 1], ExcInternalError());
+ AssertThrow(f.back() == temp.back(), ExcInternalError());
+
+ const auto it1 = f.insert(f.begin() + temp.size() / 4,
+ temp.begin() + temp.size() / 4,
+ temp.begin() + temp.size() / 2);
+ AssertThrow(static_cast<std::size_t>(it1 - f.begin()) == temp.size() / 4,
+ ExcInternalError());
+ AssertThrow(*it1 == temp[temp.size() / 4], ExcInternalError());
+ AssertThrow(std::equal(f.begin(), f.end(), temp.begin()),
+ ExcInternalError());
+ }
+
+ deallog << "back Insertion: ";
+ for (unsigned int i = 0; i < a.size(); ++i)
+ deallog << a[i] << ' ';
+ deallog << std::endl;
+
+ {
+ AlignedVector<unsigned short> temp(4);
+ std::fill(temp.begin(), temp.end(), 42u);
+ a.insert(a.begin() + 4, temp.begin(), temp.end());
+ }
+ deallog << "Insertion at position 4: ";
+
for (unsigned int i = 0; i < a.size(); ++i)
deallog << a[i] << ' ';
deallog << std::endl;