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);
263 reference operator[](const size_type index);
306 template <class Archive>
308 save(Archive &ar, const
unsigned int version) const;
314 template <class Archive>
316 load(Archive &ar, const
unsigned int version);
318 BOOST_SERIALIZATION_SPLIT_MEMBER()
362 template <
typename T>
365 static const std::size_t minimum_parallel_grain_size =
366 160000 /
sizeof(T) + 1;
379 const T *
const source_end,
380 T *
const destination)
381 : source_(source_begin)
382 , destination_(destination)
385 Assert(source_end == source_begin || destination !=
nullptr,
387 const std::size_t size = source_end - source_begin;
388 if (size < minimum_parallel_grain_size)
389 apply_to_subrange(0, size);
391 apply_parallel(0, size, minimum_parallel_grain_size);
400 const std::size_t end)
const override 409 if (std::is_trivial<T>::value ==
true)
410 std::memcpy((
void *)(destination_ + begin),
411 (
void *)(source_ + begin),
412 (end - begin) *
sizeof(T));
414 for (std::size_t i = begin; i <
end; ++i)
415 new (&destination_[i]) T(source_[i]);
419 const T *
const source_;
420 T *
const destination_;
429 template <
typename T>
432 static const std::size_t minimum_parallel_grain_size =
433 160000 /
sizeof(T) + 1;
447 T *
const destination)
448 : source_(source_begin)
449 , destination_(destination)
452 Assert(source_end == source_begin || destination !=
nullptr,
454 const std::size_t size = source_end - source_begin;
455 if (size < minimum_parallel_grain_size)
456 apply_to_subrange(0, size);
458 apply_parallel(0, size, minimum_parallel_grain_size);
467 const std::size_t end)
const override 476 if (std::is_trivial<T>::value ==
true)
477 std::memcpy((
void *)(destination_ + begin),
478 (
void *)(source_ + begin),
479 (end - begin) *
sizeof(T));
481 for (std::size_t i = begin; i <
end; ++i)
485 new (&destination_[i]) T(std::move(source_[i]));
492 T *
const destination_;
507 template <
typename T,
bool initialize_memory>
510 static const std::size_t minimum_parallel_grain_size =
511 160000 /
sizeof(T) + 1;
520 T *
const destination)
522 , destination_(destination)
523 , trivial_element(false)
532 if (std::is_trivial<T>::value ==
true &&
533 std::is_same<T, long double>::value ==
false)
535 const unsigned char zero[
sizeof(T)] = {};
539 if (std::memcmp(zero, (
void *)&element,
sizeof(T)) == 0)
540 trivial_element =
true;
542 if (size < minimum_parallel_grain_size)
543 apply_to_subrange(0, size);
545 apply_parallel(0, size, minimum_parallel_grain_size);
553 const std::size_t end)
const override 559 if (std::is_trivial<T>::value ==
true && trivial_element)
560 std::memset((
void *)(destination_ + begin),
562 (end - begin) *
sizeof(T));
564 copy_construct_or_assign(
565 begin, end, std::integral_constant<bool, initialize_memory>());
570 mutable T *destination_;
571 bool trivial_element;
575 copy_construct_or_assign(
const std::size_t begin,
576 const std::size_t end,
577 std::integral_constant<bool, false>)
const 579 for (std::size_t i = begin; i <
end; ++i)
580 destination_[i] = element_;
585 copy_construct_or_assign(
const std::size_t begin,
586 const std::size_t end,
587 std::integral_constant<bool, true>)
const 589 for (std::size_t i = begin; i <
end; ++i)
590 new (&destination_[i]) T(element_);
607 template <
typename T,
bool initialize_memory>
610 static const std::size_t minimum_parallel_grain_size =
611 160000 /
sizeof(T) + 1;
619 : destination_(destination)
625 if (size < minimum_parallel_grain_size)
626 apply_to_subrange(0, size);
628 apply_parallel(0, size, minimum_parallel_grain_size);
636 const std::size_t end)
const override 642 if (std::is_trivial<T>::value ==
true)
643 std::memset((
void *)(destination_ + begin),
645 (end - begin) *
sizeof(T));
647 default_construct_or_assign(
648 begin, end, std::integral_constant<bool, initialize_memory>());
652 mutable T *destination_;
656 default_construct_or_assign(
const std::size_t begin,
657 const std::size_t end,
658 std::integral_constant<bool, false>)
const 660 for (std::size_t i = begin; i <
end; ++i)
661 destination_[i] = std::move(T());
666 default_construct_or_assign(
const std::size_t begin,
667 const std::size_t end,
668 std::integral_constant<bool, true>)
const 670 for (std::size_t i = begin; i <
end; ++i)
671 new (&destination_[i]) T;
772 const size_type old_size =
size();
773 if (std::is_trivial<T>::value ==
false && size_in < old_size)
786 if (std::is_trivial<T>::value ==
false && size_in > old_size)
798 const size_type old_size =
size();
799 if (std::is_trivial<T>::value ==
false && size_in < old_size)
811 if (size_in > old_size)
823 const size_type old_size =
size();
824 if (std::is_trivial<T>::value ==
false && size_in < old_size)
836 if (size_in > old_size)
850 if (size_alloc > allocated_size)
855 size_type new_size = size_alloc;
856 if (size_alloc < (2 * allocated_size))
857 new_size = 2 * allocated_size;
859 const size_type size_actual_allocate = new_size *
sizeof(T);
866 size_actual_allocate);
883 else if (size_alloc == 0)
893 if (
_data !=
nullptr)
895 if (std::is_trivial<T>::value ==
false)
915 if (std::is_trivial<T>::value ==
false)
924 inline typename AlignedVector<T>::reference
935 inline typename AlignedVector<T>::const_reference
946 template <
typename ForwardIterator>
950 const unsigned int old_size =
size();
951 reserve(old_size + (end - begin));
954 if (std::is_trivial<T>::value ==
false)
1001 inline typename AlignedVector<T>::size_type
1010 inline typename AlignedVector<T>::size_type
1023 return _data[index];
1033 return _data[index];
1039 inline typename AlignedVector<T>::iterator
1048 inline typename AlignedVector<T>::iterator
1057 inline typename AlignedVector<T>::const_iterator
1066 inline typename AlignedVector<T>::const_iterator
1075 template <
class Archive>
1079 size_type vec_size(
size());
1082 ar &boost::serialization::make_array(
_data, vec_size);
1088 template <
class Archive>
1092 size_type vec_size = 0;
1098 ar &boost::serialization::make_array(
_data, vec_size);
1106 inline typename AlignedVector<T>::size_type
1109 size_type memory =
sizeof(*this);
1117 #endif // ifndef DOXYGEN 1131 for (
typename AlignedVector<T>::const_iterator lit = lhs.
begin(),
1155 DEAL_II_NAMESPACE_CLOSE
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
size_type capacity() const
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
#define AssertIndexRange(index, range)
size_type memory_consumption() const
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)
void save(Archive &ar, const unsigned int version) const
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
#define Assert(cond, exc)
void posix_memalign(void **memptr, size_t alignment, size_t size)
void insert_back(ForwardIterator begin, ForwardIterator end)
void swap(Vector< Number > &u, Vector< Number > &v)
void swap(AlignedVector< T > &vec)
void resize_fast(const size_type size)
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)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static::ExceptionBase & ExcInternalError()