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),
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),
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),
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),
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;
706 : data_begin(nullptr)
708 , allocated_end(nullptr)
726 : data_begin(nullptr)
728 , allocated_end(nullptr)
732 data_end = allocated_end;
740 : data_begin(vec.data_begin)
741 , data_end(vec.data_end)
742 , allocated_end(vec.allocated_end)
745 vec.data_end =
nullptr;
746 vec.allocated_end =
nullptr;
769 data_begin = vec.data_begin;
770 data_end = vec.data_end;
771 allocated_end = vec.allocated_end;
773 vec.data_begin =
nullptr;
774 vec.data_end =
nullptr;
775 vec.allocated_end =
nullptr;
786 const size_type old_size = size();
787 if (std::is_trivial<T>::value ==
false && size_in < old_size)
792 while (data_end != data_begin + size_in)
796 data_end = data_begin + size_in;
800 if (std::is_trivial<T>::value ==
false && size_in > old_size)
802 size_in - old_size, data_begin + old_size);
811 const size_type old_size = size();
812 if (std::is_trivial<T>::value ==
false && size_in < old_size)
817 while (data_end != data_begin + size_in)
821 data_end = data_begin + size_in;
824 if (size_in > old_size)
826 size_in - old_size, data_begin + old_size);
835 const size_type old_size = size();
836 if (std::is_trivial<T>::value ==
false && size_in < old_size)
841 while (data_end != data_begin + size_in)
845 data_end = data_begin + size_in;
848 if (size_in > old_size)
851 data_begin + old_size);
860 const size_type old_size = data_end - data_begin;
861 const size_type allocated_size = allocated_end - data_begin;
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);
883 data_end = data_begin + old_size;
884 allocated_end = data_begin + new_size;
885 if (data_end != data_begin)
895 else if (size_alloc == 0)
905 if (data_begin !=
nullptr)
907 if (std::is_trivial<T>::value ==
false)
908 while (data_end != data_begin)
913 data_begin =
nullptr;
915 allocated_end =
nullptr;
925 if (data_end == allocated_end)
926 reserve(std::max(2 * capacity(), static_cast<size_type>(16)));
927 if (std::is_trivial<T>::value ==
false)
928 new (data_end++) T(in_data);
930 *data_end++ = in_data;
936 inline typename AlignedVector<T>::reference
940 T *field = data_end - 1;
947 inline typename AlignedVector<T>::const_reference
951 const T *field = data_end - 1;
958 template <
typename ForwardIterator>
962 const unsigned int old_size = size();
963 reserve(old_size + (end - begin));
964 for (; begin != end; ++begin, ++data_end)
966 if (std::is_trivial<T>::value ==
false)
1008 return data_end == data_begin;
1014 inline typename AlignedVector<T>::size_type
1017 return data_end - data_begin;
1023 inline typename AlignedVector<T>::size_type
1026 return allocated_end - data_begin;
1036 return data_begin[index];
1046 return data_begin[index];
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);
1130 data_end = data_begin + vec_size;
1137 inline typename AlignedVector<T>::size_type
1140 size_type memory =
sizeof(*this);
1141 for (
const T *t = data_begin; t != data_end; ++t)
1143 memory +=
sizeof(T) * (allocated_end - data_end);
1148 #endif // ifndef DOXYGEN 1162 for (
typename AlignedVector<T>::const_iterator lit = lhs.
begin(),
1182 return !(operator==(lhs, rhs));
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()