17 #ifndef dealii_aligned_vector_h 18 #define dealii_aligned_vector_h 20 #include <deal.II/base/config.h> 21 #include <deal.II/base/exceptions.h> 22 #include <deal.II/base/memory_consumption.h> 23 #include <deal.II/base/utilities.h> 24 #include <deal.II/base/parallel.h> 28 #include <boost/version.hpp> 29 #if BOOST_VERSION >= 106400 30 # include <boost/serialization/array_wrapper.hpp> 32 # include <boost/serialization/array.hpp> 34 #include <boost/serialization/split_member.hpp> 37 #include <type_traits> 41 DEAL_II_NAMESPACE_OPEN
74 typedef std::size_t size_type;
144 void resize (
const size_type size_in);
161 void resize (
const size_type size_in,
172 void reserve (
const size_type size_alloc);
201 template <
typename ForwardIterator>
203 ForwardIterator
end);
224 void fill (
const T &element);
239 size_type
size ()
const;
289 template <
class Archive>
290 void save (Archive &ar,
const unsigned int version)
const;
296 template <
class Archive>
297 void load (Archive &ar,
const unsigned int version);
299 BOOST_SERIALIZATION_SPLIT_MEMBER()
344 template <
typename T>
347 static const std::size_t minimum_parallel_grain_size = 160000/
sizeof(T)+1;
359 const T *
const source_end,
360 T *
const destination)
362 source_ (source_begin),
363 destination_ (destination)
367 const std::size_t
size = source_end - source_begin;
368 if (
size < minimum_parallel_grain_size)
369 apply_to_subrange (0,
size);
371 apply_parallel (0,
size, minimum_parallel_grain_size);
379 const std::size_t
end)
const 388 if (std::is_trivial<T>::value ==
true)
389 std::memcpy ((
void *)(destination_+
begin), (
void *)(source_+
begin),
392 for (std::size_t i=
begin; i<
end; ++i)
393 new (&destination_[i]) T(source_[i]);
397 const T *
const source_;
398 T *
const destination_;
407 template <
typename T>
410 static const std::size_t minimum_parallel_grain_size = 160000/
sizeof(T)+1;
423 T *
const destination)
425 source_ (source_begin),
426 destination_ (destination)
430 const std::size_t
size = source_end - source_begin;
431 if (
size < minimum_parallel_grain_size)
432 apply_to_subrange (0,
size);
434 apply_parallel (0,
size, minimum_parallel_grain_size);
442 const std::size_t
end)
const 451 if (std::is_trivial<T>::value ==
true)
452 std::memcpy ((
void *)(destination_+
begin), (
void *)(source_+
begin),
455 for (std::size_t i=
begin; i<
end; ++i)
459 new (&destination_[i]) T(std::move(source_[i]));
466 T *
const destination_;
481 template <
typename T,
bool initialize_memory>
484 static const std::size_t minimum_parallel_grain_size = 160000/
sizeof(T)+1;
492 T *
const destination)
495 destination_ (destination),
496 trivial_element (false)
505 if (std::is_trivial<T>::value ==
true &&
506 std::is_same<T,long double>::value ==
false)
508 const unsigned char zero [
sizeof(T)] = {};
512 if (std::memcmp(zero, (
void *)&element,
sizeof(T)) == 0)
513 trivial_element =
true;
515 if (
size < minimum_parallel_grain_size)
516 apply_to_subrange (0,
size);
518 apply_parallel (0,
size, minimum_parallel_grain_size);
525 const std::size_t
end)
const 531 if (std::is_trivial<T>::value ==
true && trivial_element)
532 std::memset ((
void *)(destination_+
begin), 0, (
end-
begin)*
sizeof(T));
534 copy_construct_or_assign(
begin,
end,
535 std::integral_constant<bool, initialize_memory>());
540 mutable T *destination_;
541 bool trivial_element;
544 void copy_construct_or_assign(
const std::size_t
begin,
545 const std::size_t
end,
546 std::integral_constant<bool, false>)
const 548 for (std::size_t i=
begin; i<
end; ++i)
549 destination_[i] = element_;
553 void copy_construct_or_assign(
const std::size_t
begin,
554 const std::size_t
end,
555 std::integral_constant<bool, true>)
const 557 for (std::size_t i=
begin; i<
end; ++i)
558 new (&destination_[i]) T(element_);
575 template <
typename T,
bool initialize_memory>
578 static const std::size_t minimum_parallel_grain_size = 160000/
sizeof(T)+1;
585 T *
const destination)
587 destination_ (destination)
593 if (
size < minimum_parallel_grain_size)
594 apply_to_subrange (0,
size);
596 apply_parallel (0,
size, minimum_parallel_grain_size);
603 const std::size_t
end)
const 609 if (std::is_trivial<T>::value ==
true)
610 std::memset ((
void *)(destination_+
begin), 0, (
end-
begin)*
sizeof(T));
612 default_construct_or_assign(
begin,
end,
613 std::integral_constant<bool, initialize_memory>());
617 mutable T *destination_;
620 void default_construct_or_assign(
const std::size_t
begin,
621 const std::size_t
end,
622 std::integral_constant<bool, false>)
const 624 for (std::size_t i=
begin; i<
end; ++i)
625 destination_[i] = std::move(T());
629 void default_construct_or_assign(
const std::size_t
begin,
630 const std::size_t
end,
631 std::integral_constant<bool, true>)
const 633 for (std::size_t i=
begin; i<
end; ++i)
634 new (&destination_[i]) T;
662 _end_allocated (nullptr)
685 _end_allocated (nullptr)
689 _end_data = _end_allocated;
700 _end_data (vec._end_data),
701 _end_allocated (vec._end_allocated)
704 vec._end_data =
nullptr;
705 vec._end_allocated =
nullptr;
731 _end_data = vec._end_data;
732 _end_allocated = vec._end_allocated;
735 vec._end_data =
nullptr;
736 vec._end_allocated =
nullptr;
749 if (std::is_trivial<T>::value ==
false && size_in < old_size)
754 while (_end_data != _data+size_in)
758 _end_data = _data + size_in;
762 if (std::is_trivial<T>::value ==
false && size_in > old_size)
774 if (std::is_trivial<T>::value ==
false && size_in < old_size)
779 while (_end_data != _data+size_in)
783 _end_data = _data + size_in;
786 if (size_in > old_size)
799 if (std::is_trivial<T>::value ==
false && size_in < old_size)
804 while (_end_data != _data+size_in)
808 _end_data = _data + size_in;
811 if (size_in > old_size)
822 const size_type old_size = _end_data - _data;
823 const size_type allocated_size = _end_allocated - _data;
824 if (size_alloc > allocated_size)
830 if (size_alloc < (2 * allocated_size))
831 new_size = 2 * allocated_size;
833 const size_type size_actual_allocate = new_size *
sizeof(T);
843 _end_data = _data + old_size;
844 _end_allocated = _data + new_size;
845 if (_end_data != _data)
854 else if (size_alloc == 0)
865 if (_data !=
nullptr)
867 if (std::is_trivial<T>::value ==
false)
868 while (_end_data != _data)
875 _end_allocated =
nullptr;
886 if (_end_data == _end_allocated)
887 reserve (std::max(2*capacity(),static_cast<size_type>(16)));
888 if (std::is_trivial<T>::value ==
false)
889 new (_end_data++) T(in_data);
891 *_end_data++ = in_data;
898 typename AlignedVector<T>::reference
902 T *field = _end_data - 1;
910 typename AlignedVector<T>::const_reference
914 const T *field = _end_data - 1;
921 template <
typename ForwardIterator>
927 const unsigned int old_size = size();
928 reserve (old_size + (end-begin));
929 for ( ; begin != end; ++begin, ++_end_data)
931 if (std::is_trivial<T>::value ==
false)
976 return _end_data == _data;
983 typename AlignedVector<T>::size_type
986 return _end_data - _data;
993 typename AlignedVector<T>::size_type
996 return _end_allocated - _data;
1001 template <
class T >
1003 typename AlignedVector<T>::reference
1007 return _data[index];
1012 template <
class T >
1014 typename AlignedVector<T>::const_reference
1018 return _data[index];
1023 template <
class T >
1025 typename AlignedVector<T>::iterator
1033 template <
class T >
1035 typename AlignedVector<T>::iterator
1043 template <
class T >
1045 typename AlignedVector<T>::const_iterator
1053 template <
class T >
1055 typename AlignedVector<T>::const_iterator
1063 template <
class T >
1064 template <
class Archive >
1072 ar &boost::serialization::make_array(_data, vec_size);
1077 template <
class T >
1078 template <
class Archive >
1089 ar &boost::serialization::make_array(_data, vec_size);
1090 _end_data = _data + vec_size;
1096 template <
class T >
1098 typename AlignedVector<T>::size_type
1102 for (
const T *t = _data ; t != _end_data; ++t)
1104 memory +=
sizeof(T) * (_end_allocated-_end_data);
1109 #endif // ifndef DOXYGEN 1117 template <
class T >
1123 for (
typename AlignedVector<T>::const_iterator lit = lhs.
begin(),
1124 rit = rhs.
begin(); lit != lhs.
end(); ++lit, ++rit)
1138 template <
class T >
1142 return !(operator==(lhs, rhs));
1146 DEAL_II_NAMESPACE_CLOSE
types::global_dof_index size_type
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const
#define AssertIndexRange(index, range)
void load(Archive &ar, const unsigned int version)
AlignedVector & operator=(const AlignedVector< T > &vec)
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)
#define Assert(cond, exc)
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const
void posix_memalign(void **memptr, size_t alignment, size_t size)
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
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)
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const
AlignedVectorSet(const std::size_t size, const T &element, T *const destination)
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()