17 #ifndef dealii__aligned_vector_h 18 #define dealii__aligned_vector_h 20 #include <deal.II/base/config.h> 21 #include <deal.II/base/std_cxx11/type_traits.h> 22 #include <deal.II/base/exceptions.h> 23 #include <deal.II/base/memory_consumption.h> 24 #include <deal.II/base/utilities.h> 25 #include <deal.II/base/parallel.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> 41 DEAL_II_NAMESPACE_OPEN
74 typedef std::size_t size_type;
102 #ifdef DEAL_II_WITH_CXX11 120 #ifdef DEAL_II_WITH_CXX11 148 void resize (
const size_type size_in,
149 const T &init = T());
159 void reserve (
const size_type size_alloc);
188 template <
typename ForwardIterator>
190 ForwardIterator
end);
200 void fill (
const T &element);
215 size_type
size ()
const;
265 template <
class Archive>
266 void save (Archive &ar,
const unsigned int version)
const;
272 template <
class Archive>
273 void load (Archive &ar,
const unsigned int version);
275 BOOST_SERIALIZATION_SPLIT_MEMBER()
320 template <
typename T>
323 static const std::size_t minimum_parallel_grain_size = 160000/
sizeof(T)+1;
338 const bool copy_source)
340 source_ (source_begin),
341 destination_ (destination),
342 copy_source_ (copy_source)
345 const std::size_t
size = source_end - source_begin;
346 if (
size < minimum_parallel_grain_size)
347 apply_to_subrange (0,
size);
349 apply_parallel (0,
size, minimum_parallel_grain_size);
357 const std::size_t
end)
const 366 if (std_cxx11::is_trivial<T>::value ==
true)
367 std::memcpy ((
void *)(destination_+
begin), (
void *)(source_+
begin),
369 else if (copy_source_ ==
false)
370 for (std::size_t i=
begin; i<
end; ++i)
374 new (&destination_[i]) T(source_[i]);
378 for (std::size_t i=
begin; i<
end; ++i)
379 new (&destination_[i]) T(source_[i]);
385 const bool copy_source_;
399 template <
typename T,
bool initialize_memory>
402 static const std::size_t minimum_parallel_grain_size = 160000/
sizeof(T)+1;
413 destination_ (destination),
414 trivial_element (false)
422 if (std_cxx11::is_trivial<T>::value ==
true &&
425 const unsigned char zero [
sizeof(T)] = {};
429 if (std::memcmp(zero, (
void *)&element,
sizeof(T)) == 0)
430 trivial_element =
true;
432 if (
size < minimum_parallel_grain_size)
433 apply_to_subrange (0,
size);
435 apply_parallel (0,
size, minimum_parallel_grain_size);
442 const std::size_t
end)
const 448 if (std_cxx11::is_trivial<T>::value ==
true && trivial_element)
449 std::memset ((
void *)(destination_+
begin), 0, (
end-
begin)*
sizeof(T));
451 copy_construct_or_assign(
begin,
end,
457 mutable T *destination_;
458 bool trivial_element;
461 void copy_construct_or_assign(
const std::size_t
begin,
462 const std::size_t
end,
465 for (std::size_t i=
begin; i<
end; ++i)
466 destination_[i] = element_;
470 void copy_construct_or_assign(
const std::size_t
begin,
471 const std::size_t
end,
474 for (std::size_t i=
begin; i<
end; ++i)
475 new (&destination_[i]) T(element_);
530 _end_data = _end_allocated;
536 #ifdef DEAL_II_WITH_CXX11 542 _end_data (vec._end_data),
543 _end_allocated (vec._end_allocated)
546 vec._end_data =
nullptr;
547 vec._end_allocated =
nullptr;
566 #ifdef DEAL_II_WITH_CXX11 575 _end_data = vec._end_data;
576 _end_allocated = vec._end_allocated;
579 vec._end_data =
nullptr;
580 vec._end_allocated =
nullptr;
594 if (std_cxx11::is_trivial<T>::value ==
false && size_in < old_size)
599 while (_end_data != _data+size_in)
603 _end_data = _data + size_in;
607 if (std_cxx11::is_trivial<T>::value ==
false && size_in > old_size)
620 if (std_cxx11::is_trivial<T>::value ==
false && size_in < old_size)
625 while (_end_data != _data+size_in)
629 _end_data = _data + size_in;
632 if (size_in > old_size)
643 const size_type old_size = _end_data - _data;
644 const size_type allocated_size = _end_allocated - _data;
645 if (size_alloc > allocated_size)
651 if (size_alloc < (2 * allocated_size))
652 new_size = 2 * allocated_size;
654 const size_type size_actual_allocate = new_size *
sizeof(T);
663 std::swap (_data, new_data);
664 _end_data = _data + old_size;
665 _end_allocated = _data + new_size;
666 if (_end_data != _data)
675 else if (size_alloc == 0)
688 if (std_cxx11::is_trivial<T>::value ==
false)
689 while (_end_data != _data)
707 if (_end_data == _end_allocated)
708 reserve (std::max(2*capacity(),static_cast<size_type>(16)));
709 if (std_cxx11::is_trivial<T>::value ==
false)
710 new (_end_data++) T(in_data);
712 *_end_data++ = in_data;
719 typename AlignedVector<T>::reference
723 T *field = _end_data - 1;
731 typename AlignedVector<T>::const_reference
735 const T *field = _end_data - 1;
742 template <
typename ForwardIterator>
748 const unsigned int old_size = size();
749 reserve (old_size + (end-begin));
750 for ( ; begin != end; ++begin, ++_end_data)
752 if (std_cxx11::is_trivial<T>::value ==
false)
775 std::swap (_data, vec.
_data);
787 return _end_data == _data;
794 typename AlignedVector<T>::size_type
797 return _end_data - _data;
804 typename AlignedVector<T>::size_type
807 return _end_allocated - _data;
814 typename AlignedVector<T>::reference
825 typename AlignedVector<T>::const_reference
836 typename AlignedVector<T>::iterator
846 typename AlignedVector<T>::iterator
856 typename AlignedVector<T>::const_iterator
866 typename AlignedVector<T>::const_iterator
875 template <
class Archive >
883 ar &boost::serialization::make_array(_data, vec_size);
889 template <
class Archive >
900 ar &boost::serialization::make_array(_data, vec_size);
901 _end_data = _data + vec_size;
909 typename AlignedVector<T>::size_type
913 for (
const T *t = _data ; t != _end_data; ++t)
915 memory +=
sizeof(T) * (_end_allocated-_end_data);
920 #endif // ifndef DOXYGEN 934 for (
typename AlignedVector<T>::const_iterator lit = lhs.
begin(),
935 rit = rhs.
begin(); lit != lhs.
end(); ++lit, ++rit)
953 return !(operator==(lhs, rhs));
957 DEAL_II_NAMESPACE_CLOSE
types::global_dof_index size_type
#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)
reference operator[](const size_type index)
AlignedVectorSet(const std::size_t size, const T &element, T *destination)
#define Assert(cond, exc)
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const
void resize(const size_type size_in, const T &init=T())
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(AlignedVector< T > &vec)
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
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
void fill(const T &element)
AlignedVectorMove(T *source_begin, T *source_end, T *destination, const bool copy_source)
size_type capacity() const
static ::ExceptionBase & ExcInternalError()