From: Wolfgang Bangerth Date: Wed, 4 Oct 2017 15:28:37 +0000 (-0600) Subject: Use the correct move semantics in the correct places. X-Git-Tag: v9.0.0-rc1~987^2~5 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8a2548bd780236f1b917a2718c5ca93e9b54340;p=dealii.git Use the correct move semantics in the correct places. --- diff --git a/include/deal.II/base/aligned_vector.h b/include/deal.II/base/aligned_vector.h index fc54b7bc16..c18719e32e 100644 --- a/include/deal.II/base/aligned_vector.h +++ b/include/deal.II/base/aligned_vector.h @@ -327,7 +327,7 @@ private: namespace internal { /** - * Move and class that actually issues the copy commands in AlignedVector. + * A class that actually issues the copy commands in AlignedVector. * This class is based on the specialized for loop base class * ParallelForLoop in parallel.h whose purpose is the following: When * calling a parallel for loop on AlignedVector with apply_to_subranges, it @@ -342,6 +342,81 @@ namespace internal * @relates AlignedVector */ template + class AlignedVectorCopy : private parallel::ParallelForInteger + { + static const std::size_t minimum_parallel_grain_size = 160000/sizeof(T)+1; + public: + /** + * Constructor. Issues a parallel call if there are sufficiently many + * 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 + * 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). + */ + AlignedVectorCopy (T *source_begin, + T *source_end, + T *destination, + const bool copy_source) + : + source_ (source_begin), + destination_ (destination), + copy_source_ (copy_source) + { + Assert (source_end >= source_begin, ExcInternalError()); + const std::size_t size = source_end - source_begin; + if (size < minimum_parallel_grain_size) + apply_to_subrange (0, size); + else + apply_parallel (0, size, minimum_parallel_grain_size); + } + + /** + * This method moves elements from the source to the destination given in + * the constructor on a subrange given by two integers. + */ + virtual void apply_to_subrange (const std::size_t begin, + const std::size_t end) const + { + if (end == begin) + return; + + // for classes trivial assignment can use memcpy. cast element to + // (void*) to silence compiler warning for virtual classes (they will + // never arrive here because they are non-trivial). + + if (std::is_trivial::value == true) + std::memcpy ((void *)(destination_+begin), (void *)(source_+begin), + (end-begin)*sizeof(T)); + else if (copy_source_ == false) + for (std::size_t i=begin; i class AlignedVectorMove : private parallel::ParallelForInteger { static const std::size_t minimum_parallel_grain_size = 160000/sizeof(T)+1; @@ -400,7 +475,7 @@ namespace internal } else for (std::size_t i=begin; i::AlignedVector (const AlignedVector &vec) // copy the data from vec reserve (vec._end_data - vec._data); _end_data = _end_allocated; - internal::AlignedVectorMove (vec._data, vec._end_data, _data, true); + internal::AlignedVectorCopy (vec._data, vec._end_data, _data, true); } @@ -670,7 +746,7 @@ AlignedVector::operator = (const AlignedVector &vec) { resize(0); resize_fast (vec._end_data - vec._data); - internal::AlignedVectorMove (vec._data, vec._end_data, _data, true); + internal::AlignedVectorCopy (vec._data, vec._end_data, _data, true); return *this; }