17 #ifndef dealii_aligned_vector_h 18 #define dealii_aligned_vector_h 20 #include <deal.II/base/config.h> 22 #include <deal.II/base/exceptions.h> 23 #include <deal.II/base/memory_consumption.h> 24 #include <deal.II/base/parallel.h> 25 #include <deal.II/base/utilities.h> 29 #include <boost/version.hpp> 30 #if BOOST_VERSION >= 106400 31 # include <boost/serialization/array_wrapper.hpp> 33 # include <boost/serialization/array.hpp> 35 #include <boost/serialization/split_member.hpp> 38 #include <type_traits> 42 DEAL_II_NAMESPACE_OPEN
75 using size_type = std::size_t;
146 resize(
const size_type size_in);
164 resize(
const size_type size_in,
const T &init);
175 reserve(
const size_type size_alloc);
208 template <
typename ForwardIterator>
233 fill(
const T &element);
268 const_reference
operator[](
const size_type index)
const;
318 template <
class Archive>
320 save(Archive &ar,
const unsigned int version)
const;
326 template <
class Archive>
328 load(Archive &ar,
const unsigned int version);
330 BOOST_SERIALIZATION_SPLIT_MEMBER()
374 template <
typename T>
377 static const std::size_t minimum_parallel_grain_size =
378 160000 /
sizeof(T) + 1;
391 const T *
const source_end,
392 T *
const destination)
393 : source_(source_begin)
394 , destination_(destination)
397 Assert(source_end == source_begin || destination !=
nullptr,
399 const std::size_t size = source_end - source_begin;
400 if (size < minimum_parallel_grain_size)
401 AlignedVectorCopy::apply_to_subrange(0, size);
403 apply_parallel(0, size, minimum_parallel_grain_size);
412 const std::size_t
end)
const override 421 if (std::is_trivial<T>::value ==
true)
422 std::memcpy(static_cast<void *>(destination_ + begin),
423 static_cast<const void *>(source_ + begin),
424 (end - begin) *
sizeof(T));
426 for (std::size_t i = begin; i <
end; ++i)
427 new (&destination_[i]) T(source_[i]);
431 const T *
const source_;
432 T *
const destination_;
441 template <
typename T>
444 static const std::size_t minimum_parallel_grain_size =
445 160000 /
sizeof(T) + 1;
459 T *
const destination)
460 : source_(source_begin)
461 , destination_(destination)
464 Assert(source_end == source_begin || destination !=
nullptr,
466 const std::size_t size = source_end - source_begin;
467 if (size < minimum_parallel_grain_size)
468 apply_to_subrange(0, size);
470 apply_parallel(0, size, minimum_parallel_grain_size);
479 const std::size_t
end)
const override 488 if (std::is_trivial<T>::value ==
true)
489 std::memcpy(static_cast<void *>(destination_ + begin),
490 static_cast<void *>(source_ + begin),
491 (end - begin) *
sizeof(T));
493 for (std::size_t i = begin; i <
end; ++i)
497 new (&destination_[i]) T(std::move(source_[i]));
504 T *
const destination_;
519 template <
typename T,
bool initialize_memory>
522 static const std::size_t minimum_parallel_grain_size =
523 160000 /
sizeof(T) + 1;
532 T *
const destination)
534 , destination_(destination)
535 , trivial_element(false)
544 if (std::is_trivial<T>::value ==
true &&
545 std::is_same<T, long double>::value ==
false)
547 const unsigned char zero[
sizeof(T)] = {};
551 if (std::memcmp(zero,
552 static_cast<const void *>(&element),
554 trivial_element =
true;
556 if (size < minimum_parallel_grain_size)
557 apply_to_subrange(0, size);
559 apply_parallel(0, size, minimum_parallel_grain_size);
567 const std::size_t
end)
const override 573 if (std::is_trivial<T>::value ==
true && trivial_element)
574 std::memset(static_cast<void *>(destination_ + begin),
576 (end - begin) *
sizeof(T));
578 copy_construct_or_assign(
579 begin, end, std::integral_constant<bool, initialize_memory>());
584 mutable T *destination_;
585 bool trivial_element;
589 copy_construct_or_assign(
const std::size_t
begin,
590 const std::size_t
end,
591 std::integral_constant<bool, false>)
const 593 for (std::size_t i = begin; i <
end; ++i)
594 destination_[i] = element_;
599 copy_construct_or_assign(
const std::size_t begin,
600 const std::size_t end,
601 std::integral_constant<bool, true>)
const 603 for (std::size_t i = begin; i <
end; ++i)
604 new (&destination_[i]) T(element_);
621 template <
typename T,
bool initialize_memory>
624 static const std::size_t minimum_parallel_grain_size =
625 160000 /
sizeof(T) + 1;
633 : destination_(destination)
639 if (size < minimum_parallel_grain_size)
640 apply_to_subrange(0, size);
642 apply_parallel(0, size, minimum_parallel_grain_size);
650 const std::size_t
end)
const override 656 if (std::is_trivial<T>::value ==
true)
657 std::memset(static_cast<void *>(destination_ + begin),
659 (end - begin) *
sizeof(T));
661 default_construct_or_assign(
662 begin, end, std::integral_constant<bool, initialize_memory>());
666 mutable T *destination_;
670 default_construct_or_assign(
const std::size_t
begin,
671 const std::size_t
end,
672 std::integral_constant<bool, false>)
const 674 for (std::size_t i = begin; i <
end; ++i)
675 destination_[i] = std::move(T());
680 default_construct_or_assign(
const std::size_t begin,
681 const std::size_t end,
682 std::integral_constant<bool, true>)
const 684 for (std::size_t i = begin; i <
end; ++i)
685 new (&destination_[i]) T;
786 const size_type old_size =
size();
787 if (std::is_trivial<T>::value ==
false && size_in < old_size)
800 if (std::is_trivial<T>::value ==
false && size_in > old_size)
811 const size_type old_size =
size();
812 if (std::is_trivial<T>::value ==
false && size_in < old_size)
824 if (size_in > old_size)
835 const size_type old_size =
size();
836 if (std::is_trivial<T>::value ==
false && size_in < old_size)
848 if (size_in > old_size)
862 if (size_alloc > allocated_size)
867 size_type new_size = size_alloc;
868 if (size_alloc < (2 * allocated_size))
869 new_size = 2 * allocated_size;
871 const size_type size_actual_allocate = new_size *
sizeof(T);
878 size_actual_allocate);
895 else if (size_alloc == 0)
907 if (std::is_trivial<T>::value ==
false)
927 if (std::is_trivial<T>::value ==
false)
936 inline typename AlignedVector<T>::reference
947 inline typename AlignedVector<T>::const_reference
958 template <
typename ForwardIterator>
962 const unsigned int old_size =
size();
963 reserve(old_size + (end - begin));
966 if (std::is_trivial<T>::value ==
false)
1014 inline typename AlignedVector<T>::size_type
1023 inline typename AlignedVector<T>::size_type
1051 template <
typename T>
1052 inline typename AlignedVector<T>::pointer
1060 template <
typename T>
1061 inline typename AlignedVector<T>::const_pointer
1070 inline typename AlignedVector<T>::iterator
1079 inline typename AlignedVector<T>::iterator
1088 inline typename AlignedVector<T>::const_iterator
1097 inline typename AlignedVector<T>::const_iterator
1106 template <
class Archive>
1110 size_type vec_size(
size());
1113 ar &boost::serialization::make_array(
data_begin, vec_size);
1119 template <
class Archive>
1123 size_type vec_size = 0;
1129 ar &boost::serialization::make_array(
data_begin, vec_size);
1137 inline typename AlignedVector<T>::size_type
1140 size_type memory =
sizeof(*this);
1148 #endif // ifndef DOXYGEN 1162 for (
typename AlignedVector<T>::const_iterator lit = lhs.
begin(),
1186 DEAL_II_NAMESPACE_CLOSE
void posix_memalign(void **memptr, std::size_t alignment, std::size_t size)
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
#define AssertIndexRange(index, range)
void load(Archive &ar, const unsigned int version)
AlignedVector & operator=(const AlignedVector< T > &vec)
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
void reserve(const size_type size_alloc)
void push_back(const T in_data)
void resize(const size_type size_in)
reference operator[](const size_type index)
typename VectorType::value_type value_type
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
#define Assert(cond, exc)
void insert_back(ForwardIterator begin, ForwardIterator end)
size_type memory_consumption() const
void swap(Vector< Number > &u, Vector< Number > &v)
void swap(AlignedVector< T > &vec)
void resize_fast(const size_type size)
void save(Archive &ar, const unsigned int version) const
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
AlignedVectorMove(T *const source_begin, T *const source_end, T *const destination)
AlignedVectorCopy(const T *const source_begin, const T *const source_end, T *const destination)
AlignedVectorSet(const std::size_t size, const T &element, T *const destination)
bool operator!=(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
AlignedVectorDefaultInitialize(const std::size_t size, T *const destination)
size_type capacity() const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()