From b2394b1518d3f797c2d74ff14d154bb3a4807371 Mon Sep 17 00:00:00 2001 From: Martin Kronbichler Date: Sat, 9 Jan 2016 20:56:54 +0100 Subject: [PATCH] Fix AlignedVector for classes that do not implement copy assignment operator. --- include/deal.II/base/aligned_vector.h | 74 +++++++++++++++++---------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/include/deal.II/base/aligned_vector.h b/include/deal.II/base/aligned_vector.h index 901a2059c9..a4d29d5039 100644 --- a/include/deal.II/base/aligned_vector.h +++ b/include/deal.II/base/aligned_vector.h @@ -103,6 +103,9 @@ public: * Change the size of the vector. It keeps old elements previously available * but does not initialize the newly allocated memory, leaving it in an * undefined state. + * + * @note This method can only be invoked for classes @p T that define a + * default constructor, @p T(). Otherwise, compilation will fail. */ void resize_fast (const size_type size); @@ -161,6 +164,9 @@ public: /** * Fills the vector with size() copies of the given input. * + * @note This method can only be invoked for classes that define the copy + * assignment operator. Otherwise, compilation will fail. + * * @dealiiOperationIsMultithreaded */ void fill (const T &element); @@ -293,15 +299,15 @@ namespace internal * elements, otherwise works in serial. Copies the data from the half-open * interval between @p source_begin and @p source_end to array starting at * @p destination (by calling the copy constructor with placement new). If - * copy_source is set to @p true, the elements from the source array are - * simply copied. If it is set to @p false, the data is moved between the - * two arrays by invoking the destructor on the source range (preparing - * for a subsequent call to free). + * the flag copy_source is set to @p true, the elements from the source + * array are simply copied. If it is set to @p false, the data is moved + * between the two arrays by invoking the destructor on the source range + * (preparing for a subsequent call to free). */ AlignedVectorMove (T *source_begin, T *source_end, T *destination, - bool copy_source) + const bool copy_source) : source_ (source_begin), destination_ (destination), @@ -339,9 +345,7 @@ namespace internal } else for (std::size_t i=begin; i + template class AlignedVectorSet : private parallel::ParallelForInteger { static const std::size_t minimum_parallel_grain_size = 160000/sizeof(T)+1; @@ -366,13 +376,11 @@ namespace internal */ AlignedVectorSet (const std::size_t size, const T &element, - T *destination, - const bool initialize_memory) + T *destination) : element_ (element), destination_ (destination), - trivial_element (false), - initialize_memory (initialize_memory) + trivial_element (false) { if (size == 0) return; @@ -396,8 +404,6 @@ namespace internal apply_parallel (0, size, minimum_parallel_grain_size); } - private: - /** * This sets elements on a subrange given by two integers. */ @@ -410,20 +416,33 @@ namespace internal // non-trivial). if (std_cxx11::is_trivial::value == true && trivial_element) std::memset ((void *)(destination_+begin), 0, (end-begin)*sizeof(T)); - else if (initialize_memory) - // initialize memory and set by copy constructor - for (std::size_t i=begin; i()); } + private: const T &element_; mutable T *destination_; bool trivial_element; - const bool initialize_memory; + + // copy assignment operation + void copy_construct_or_assign(const std::size_t begin, + const std::size_t end, + internal::bool2type) const + { + for (std::size_t i=begin; i) const + { + for (std::size_t i=begin; i::AlignedVector (const AlignedVector &vec) _end_allocated (0) { // copy the data from vec - resize_fast (vec._end_data - vec._data); + reserve (vec._end_data - vec._data); + _end_data = _end_allocated; internal::AlignedVectorMove (vec._data, vec._end_data, _data, true); } @@ -515,7 +535,7 @@ AlignedVector::resize_fast (const size_type size_in) // need to still set the values in case the class is non-trivial because // virtual classes etc. need to run their (default) constructor if (std_cxx11::is_trivial::value == false && size_in > old_size) - dealii::internal::AlignedVectorSet (size_in-old_size, T(), _data+old_size, true); + dealii::internal::AlignedVectorSet (size_in-old_size, T(), _data+old_size); } @@ -540,7 +560,7 @@ AlignedVector::resize (const size_type size_in, // finally set the desired init values if (size_in > old_size) - dealii::internal::AlignedVectorSet (size_in-old_size, init, _data+old_size, true); + dealii::internal::AlignedVectorSet (size_in-old_size, init, _data+old_size); } @@ -671,7 +691,7 @@ inline void AlignedVector::fill (const T &value) { - dealii::internal::AlignedVectorSet (size(), value, _data, false); + dealii::internal::AlignedVectorSet (size(), value, _data); } -- 2.39.5