From 913b3f9f518901a02e0d0503570bf8d30f3ef28d Mon Sep 17 00:00:00 2001 From: David Wells Date: Thu, 27 Jun 2024 14:02:30 -0400 Subject: [PATCH] AlignedVector: add a range constructor. --- include/deal.II/base/aligned_vector.h | 32 +++++++++++++++++++++++++++ tests/base/aligned_vector_01.cc | 25 ++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/deal.II/base/aligned_vector.h b/include/deal.II/base/aligned_vector.h index 1b24729fc3..84e74980d3 100644 --- a/include/deal.II/base/aligned_vector.h +++ b/include/deal.II/base/aligned_vector.h @@ -78,6 +78,21 @@ public: */ AlignedVector(); + /** + * Range constructor. + * + * @note Unlike std::vector, this constructor uses random-access iterators so + * that the copy may be parallelized. + * + * @dealiiOperationIsMultithreaded + */ + template < + typename RandomAccessIterator, + typename = std::enable_if_t::iterator_category, + std::random_access_iterator_tag>>> + AlignedVector(RandomAccessIterator begin, RandomAccessIterator end); + /** * Set the vector size to the given size and initializes all elements with * T(). @@ -1183,6 +1198,23 @@ inline AlignedVector::AlignedVector() +template +template +inline AlignedVector::AlignedVector(RandomAccessIterator begin, + RandomAccessIterator end) + : elements(nullptr, Deleter(this)) + , used_elements_end(nullptr) + , allocated_elements_end(nullptr) + , replicated_across_communicator(false) +{ + allocate_and_move(0u, end - begin, end - begin); + used_elements_end = allocated_elements_end; + dealii::internal::AlignedVectorCopyConstruct(begin, + end, + data()); +} + + template inline AlignedVector::AlignedVector(const size_type size, const T &init) : elements(nullptr, Deleter(this)) diff --git a/tests/base/aligned_vector_01.cc b/tests/base/aligned_vector_01.cc index cbd6f446e7..af0831ef6f 100644 --- a/tests/base/aligned_vector_01.cc +++ b/tests/base/aligned_vector_01.cc @@ -18,8 +18,9 @@ #include -#include "../tests.h" +#include +#include "../tests.h" void test() @@ -39,6 +40,28 @@ test() b.push_back(27); a.insert_back(b.begin(), b.end()); + // Check the range constructor with and without conversion. + { + VEC c(b.begin(), b.end()); + AssertThrow(c == b, ExcInternalError()); + + std::vector temp(b.begin(), b.end()); + VEC d(temp.begin(), temp.end()); + AssertThrow(c == d, ExcInternalError()); + } + + // Check the range constructor with a random-access iterator which is not + // contiguous + { + // Use a large enough deque to guarantee that we have multiple blocks + std::deque temp(8192); + std::iota(temp.begin(), temp.end(), 0u); + + VEC e(temp.begin(), temp.end()); + AssertThrow(std::equal(e.begin(), e.end(), temp.begin()), + ExcInternalError()); + } + deallog << "Insertion: "; for (unsigned int i = 0; i < a.size(); ++i) deallog << a[i] << ' '; -- 2.39.5