17 #ifndef dealii_aligned_vector_h 18 #define dealii_aligned_vector_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> 39 #include <type_traits> 235 template <
typename ForwardIterator>
260 fill(
const T &element);
346 template <
class Archive>
348 save(Archive &ar,
const unsigned int version)
const;
355 template <
class Archive>
357 load(Archive &ar,
const unsigned int version);
365 template <
class Archive>
367 serialize(Archive &archive,
const unsigned int version);
371 BOOST_SERIALIZATION_SPLIT_MEMBER()
416 template <
typename T>
420 160000 /
sizeof(
T) + 1;
433 const T *
const source_end,
434 T *
const destination)
435 : source_(source_begin)
436 , destination_(destination)
439 Assert(source_end == source_begin || destination !=
nullptr,
441 const std::size_t size = source_end - source_begin;
442 if (size < minimum_parallel_grain_size)
443 AlignedVectorCopy::apply_to_subrange(0, size);
445 apply_parallel(0, size, minimum_parallel_grain_size);
454 const std::size_t
end)
const override 463 if (std::is_trivial<T>::value ==
true)
464 std::memcpy(static_cast<void *>(destination_ + begin),
465 static_cast<const void *>(source_ + begin),
466 (end - begin) *
sizeof(
T));
468 for (std::size_t i = begin; i <
end; ++i)
469 new (&destination_[i])
T(source_[i]);
483 template <
typename T>
487 160000 /
sizeof(
T) + 1;
501 T *
const destination)
502 : source_(source_begin)
503 , destination_(destination)
506 Assert(source_end == source_begin || destination !=
nullptr,
508 const std::size_t size = source_end - source_begin;
509 if (size < minimum_parallel_grain_size)
510 AlignedVectorMove::apply_to_subrange(0, size);
512 apply_parallel(0, size, minimum_parallel_grain_size);
521 const std::size_t
end)
const override 530 if (std::is_trivial<T>::value ==
true)
531 std::memcpy(static_cast<void *>(destination_ + begin),
532 static_cast<void *>(source_ + begin),
533 (end - begin) *
sizeof(
T));
535 for (std::size_t i = begin; i <
end; ++i)
539 new (&destination_[i])
T(std::move(source_[i]));
561 template <
typename T,
bool initialize_memory>
565 160000 /
sizeof(
T) + 1;
574 T *
const destination)
576 , destination_(destination)
577 , trivial_element(false)
586 if (std::is_trivial<T>::value ==
true &&
587 std::is_same<T, long double>::value ==
false)
589 const unsigned char zero[
sizeof(
T)] = {};
593 if (std::memcmp(
zero,
594 static_cast<const void *>(&element),
596 trivial_element =
true;
598 if (size < minimum_parallel_grain_size)
599 AlignedVectorSet::apply_to_subrange(0, size);
601 apply_parallel(0, size, minimum_parallel_grain_size);
609 const std::size_t
end)
const override 615 if (std::is_trivial<T>::value ==
true && trivial_element)
616 std::memset(static_cast<void *>(destination_ + begin),
618 (end - begin) *
sizeof(
T));
620 copy_construct_or_assign(
621 begin, end, std::integral_constant<bool, initialize_memory>());
632 const std::size_t
end,
633 std::integral_constant<bool, false>)
const 635 for (std::size_t i = begin; i <
end; ++i)
636 destination_[i] = element_;
642 const std::size_t
end,
643 std::integral_constant<bool, true>)
const 645 for (std::size_t i = begin; i <
end; ++i)
646 new (&destination_[i])
T(element_);
663 template <
typename T,
bool initialize_memory>
668 160000 /
sizeof(
T) + 1;
676 : destination_(destination)
682 if (size < minimum_parallel_grain_size)
683 AlignedVectorDefaultInitialize::apply_to_subrange(0, size);
685 apply_parallel(0, size, minimum_parallel_grain_size);
693 const std::size_t
end)
const override 699 if (std::is_trivial<T>::value ==
true)
700 std::memset(static_cast<void *>(destination_ + begin),
702 (end - begin) *
sizeof(
T));
704 default_construct_or_assign(
705 begin, end, std::integral_constant<bool, initialize_memory>());
714 const std::size_t
end,
715 std::integral_constant<bool, false>)
const 717 for (std::size_t i = begin; i <
end; ++i)
718 destination_[i] = std::move(
T());
724 const std::size_t
end,
725 std::integral_constant<bool, true>)
const 727 for (std::size_t i = begin; i <
end; ++i)
728 new (&destination_[i])
T;
777 vec.used_elements_end,
789 vec.elements =
nullptr;
790 vec.used_elements_end =
nullptr;
791 vec.allocated_elements_end =
nullptr;
801 resize_fast(vec.used_elements_end - vec.elements.get());
803 vec.used_elements_end,
823 vec.used_elements_end =
nullptr;
824 vec.allocated_elements_end =
nullptr;
839 else if (new_size == old_size)
841 else if (new_size < old_size)
846 if (std::is_trivial<T>::value ==
false)
862 if (std::is_trivial<T>::value ==
false)
864 new_size - old_size,
elements.get() + old_size);
878 else if (new_size == old_size)
880 else if (new_size < old_size)
885 if (std::is_trivial<T>::value ==
false)
901 new_size - old_size,
elements.get() + old_size);
915 else if (new_size == old_size)
917 else if (new_size < old_size)
922 if (std::is_trivial<T>::value ==
false)
951 if (new_allocated_size > old_allocated_size)
957 std::max(new_allocated_size, 2 * old_allocated_size);
963 reinterpret_cast<void **>(&new_data_ptr), 64, new_size *
sizeof(
T));
964 std::unique_ptr<T[], void (*)(T *)> new_data(new_data_ptr, [](
T *ptr) {
969 if (new_allocated_size > 0)
981 else if (new_allocated_size == 0)
995 if (std::is_trivial<T>::value ==
false)
1013 if (std::is_trivial<T>::value ==
false)
1044 template <
typename ForwardIterator>
1048 const unsigned int old_size =
size();
1049 reserve(old_size + (end - begin));
1052 if (std::is_trivial<T>::value ==
false)
1137 template <
typename T>
1146 template <
typename T>
1192 template <
class Archive>
1199 ar &boost::serialization::make_array(
elements.get(), vec_size);
1205 template <
class Archive>
1215 ar &boost::serialization::make_array(
elements.get(), vec_size);
1234 #endif // ifndef DOXYGEN 1246 if (lhs.size() != rhs.size())
void resize(const size_type new_size)
void default_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, false >) const
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 push_back(const T in_data)
reference operator[](const size_type index)
void serialize(Archive &archive, const unsigned int version)
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
#define Assert(cond, exc)
#define DEAL_II_NAMESPACE_CLOSE
void copy_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, true >) const
std::unique_ptr< T[], void(*)(T *)> elements
void insert_back(ForwardIterator begin, ForwardIterator end)
const value_type * const_iterator
size_type memory_consumption() const
void copy_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, false >) const
void default_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, true >) const
void swap(AlignedVector< T > &vec)
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
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)
#define DEAL_II_NAMESPACE_OPEN
AlignedVectorCopy(const T *const source_begin, const T *const source_end, T *const destination)
void resize_fast(const size_type new_size)
AlignedVectorSet(const std::size_t size, const T &element, T *const destination)
unsigned int minimum_parallel_grain_size
bool operator!=(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
T * allocated_elements_end
AlignedVectorDefaultInitialize(const std::size_t size, T *const destination)
static const types::blas_int zero
const value_type * const_pointer
void reserve(const size_type new_allocated_size)
const value_type & const_reference
size_type capacity() const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()