Reference documentation for deal.II version Git 5b8b897cb2 2021-04-22 22:24:19 -0400
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
aligned_vector.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #ifndef dealii_aligned_vector_h
18 #define dealii_aligned_vector_h
19 
20 #include <deal.II/base/config.h>
21 
24 #include <deal.II/base/parallel.h>
25 #include <deal.II/base/utilities.h>
26 
27 // boost::serialization::make_array used to be in array.hpp, but was
28 // moved to a different file in BOOST 1.64
29 #include <boost/version.hpp>
30 #if BOOST_VERSION >= 106400
31 # include <boost/serialization/array_wrapper.hpp>
32 #else
33 # include <boost/serialization/array.hpp>
34 #endif
35 #include <boost/serialization/split_member.hpp>
36 
37 #include <cstring>
38 #include <memory>
39 #include <type_traits>
40 
41 
42 
44 
45 
61 template <class T>
63 {
64 public:
69  using value_type = T;
70  using pointer = value_type *;
71  using const_pointer = const value_type *;
72  using iterator = value_type *;
73  using const_iterator = const value_type *;
74  using reference = value_type &;
75  using const_reference = const value_type &;
76  using size_type = std::size_t;
77 
81  AlignedVector();
82 
89  explicit AlignedVector(const size_type size, const T &init = T());
90 
95 
101  AlignedVector(const AlignedVector<T> &vec);
102 
107  AlignedVector(AlignedVector<T> &&vec) noexcept;
108 
114  AlignedVector &
115  operator=(const AlignedVector<T> &vec);
116 
120  AlignedVector &
121  operator=(AlignedVector<T> &&vec) noexcept;
122 
145  void
146  resize_fast(const size_type new_size);
147 
160  void
161  resize(const size_type new_size);
162 
178  void
179  resize(const size_type new_size, const T &init);
180 
201  void
202  reserve(const size_type new_allocated_size);
203 
208  void
209  clear();
210 
216  void
217  push_back(const T in_data);
218 
222  reference
223  back();
224 
229  back() const;
230 
235  template <typename ForwardIterator>
236  void
237  insert_back(ForwardIterator begin, ForwardIterator end);
238 
248  void
249  fill();
250 
259  void
260  fill(const T &element);
261 
265  void
266  swap(AlignedVector<T> &vec);
267 
271  bool
272  empty() const;
273 
277  size_type
278  size() const;
279 
284  size_type
285  capacity() const;
286 
290  reference operator[](const size_type index);
291 
295  const_reference operator[](const size_type index) const;
296 
300  pointer
301  data();
302 
307  data() const;
308 
312  iterator
313  begin();
314 
318  iterator
319  end();
320 
325  begin() const;
326 
331  end() const;
332 
338  size_type
339  memory_consumption() const;
340 
346  template <class Archive>
347  void
348  save(Archive &ar, const unsigned int version) const;
349 
355  template <class Archive>
356  void
357  load(Archive &ar, const unsigned int version);
358 
359 #ifdef DOXYGEN
360 
365  template <class Archive>
366  void
367  serialize(Archive &archive, const unsigned int version);
368 #else
369  // This macro defines the serialize() method that is compatible with
370  // the templated save() and load() method that have been implemented.
371  BOOST_SERIALIZATION_SPLIT_MEMBER()
372 #endif
373 
374 private:
378  std::unique_ptr<T[], void (*)(T *)> elements;
379 
384 
389 };
390 
391 
392 // ------------------------------- inline functions --------------------------
393 
399 namespace internal
400 {
416  template <typename T>
418  {
419  static const std::size_t minimum_parallel_grain_size =
420  160000 / sizeof(T) + 1;
421 
422  public:
432  AlignedVectorCopy(const T *const source_begin,
433  const T *const source_end,
434  T *const destination)
435  : source_(source_begin)
436  , destination_(destination)
437  {
438  Assert(source_end >= source_begin, ExcInternalError());
439  Assert(source_end == source_begin || destination != nullptr,
440  ExcInternalError());
441  const std::size_t size = source_end - source_begin;
442  if (size < minimum_parallel_grain_size)
443  AlignedVectorCopy::apply_to_subrange(0, size);
444  else
445  apply_parallel(0, size, minimum_parallel_grain_size);
446  }
447 
452  virtual void
453  apply_to_subrange(const std::size_t begin,
454  const std::size_t end) const override
455  {
456  if (end == begin)
457  return;
458 
459  // for classes trivial assignment can use memcpy. cast element to
460  // (void*) to silence compiler warning for virtual classes (they will
461  // never arrive here because they are non-trivial).
462 
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));
467  else
468  for (std::size_t i = begin; i < end; ++i)
469  new (&destination_[i]) T(source_[i]);
470  }
471 
472  private:
473  const T *const source_;
474  T *const destination_;
475  };
476 
477 
483  template <typename T>
485  {
486  static const std::size_t minimum_parallel_grain_size =
487  160000 / sizeof(T) + 1;
488 
489  public:
499  AlignedVectorMove(T *const source_begin,
500  T *const source_end,
501  T *const destination)
502  : source_(source_begin)
503  , destination_(destination)
504  {
505  Assert(source_end >= source_begin, ExcInternalError());
506  Assert(source_end == source_begin || destination != nullptr,
507  ExcInternalError());
508  const std::size_t size = source_end - source_begin;
509  if (size < minimum_parallel_grain_size)
510  AlignedVectorMove::apply_to_subrange(0, size);
511  else
512  apply_parallel(0, size, minimum_parallel_grain_size);
513  }
514 
519  virtual void
520  apply_to_subrange(const std::size_t begin,
521  const std::size_t end) const override
522  {
523  if (end == begin)
524  return;
525 
526  // for classes trivial assignment can use memcpy. cast element to
527  // (void*) to silence compiler warning for virtual classes (they will
528  // never arrive here because they are non-trivial).
529 
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));
534  else
535  for (std::size_t i = begin; i < end; ++i)
536  {
537  // initialize memory (copy construct by placement new), and
538  // destruct the source
539  new (&destination_[i]) T(std::move(source_[i]));
540  source_[i].~T();
541  }
542  }
543 
544  private:
545  T *const source_;
546  T *const destination_;
547  };
548 
549 
561  template <typename T, bool initialize_memory>
563  {
564  static const std::size_t minimum_parallel_grain_size =
565  160000 / sizeof(T) + 1;
566 
567  public:
572  AlignedVectorSet(const std::size_t size,
573  const T & element,
574  T *const destination)
575  : element_(element)
576  , destination_(destination)
577  , trivial_element(false)
578  {
579  if (size == 0)
580  return;
581  Assert(destination != nullptr, ExcInternalError());
582 
583  // do not use memcmp for long double because on some systems it does not
584  // completely fill its memory and may lead to false positives in
585  // e.g. valgrind
586  if (std::is_trivial<T>::value == true &&
587  std::is_same<T, long double>::value == false)
588  {
589  const unsigned char zero[sizeof(T)] = {};
590  // cast element to (void*) to silence compiler warning for virtual
591  // classes (they will never arrive here because they are
592  // non-trivial).
593  if (std::memcmp(zero,
594  static_cast<const void *>(&element),
595  sizeof(T)) == 0)
596  trivial_element = true;
597  }
598  if (size < minimum_parallel_grain_size)
599  AlignedVectorSet::apply_to_subrange(0, size);
600  else
601  apply_parallel(0, size, minimum_parallel_grain_size);
602  }
603 
607  virtual void
608  apply_to_subrange(const std::size_t begin,
609  const std::size_t end) const override
610  {
611  // for classes with trivial assignment of zero can use memset. cast
612  // element to (void*) to silence compiler warning for virtual
613  // classes (they will never arrive here because they are
614  // non-trivial).
615  if (std::is_trivial<T>::value == true && trivial_element)
616  std::memset(static_cast<void *>(destination_ + begin),
617  0,
618  (end - begin) * sizeof(T));
619  else
620  copy_construct_or_assign(
621  begin, end, std::integral_constant<bool, initialize_memory>());
622  }
623 
624  private:
625  const T & element_;
626  mutable T *destination_;
628 
629  // copy assignment operation
630  void
631  copy_construct_or_assign(const std::size_t begin,
632  const std::size_t end,
633  std::integral_constant<bool, false>) const
634  {
635  for (std::size_t i = begin; i < end; ++i)
636  destination_[i] = element_;
637  }
638 
639  // copy constructor (memory initialization)
640  void
641  copy_construct_or_assign(const std::size_t begin,
642  const std::size_t end,
643  std::integral_constant<bool, true>) const
644  {
645  for (std::size_t i = begin; i < end; ++i)
646  new (&destination_[i]) T(element_);
647  }
648  };
649 
650 
651 
663  template <typename T, bool initialize_memory>
666  {
667  static const std::size_t minimum_parallel_grain_size =
668  160000 / sizeof(T) + 1;
669 
670  public:
675  AlignedVectorDefaultInitialize(const std::size_t size, T *const destination)
676  : destination_(destination)
677  {
678  if (size == 0)
679  return;
680  Assert(destination != nullptr, ExcInternalError());
681 
682  if (size < minimum_parallel_grain_size)
683  AlignedVectorDefaultInitialize::apply_to_subrange(0, size);
684  else
685  apply_parallel(0, size, minimum_parallel_grain_size);
686  }
687 
691  virtual void
692  apply_to_subrange(const std::size_t begin,
693  const std::size_t end) const override
694  {
695  // for classes with trivial assignment of zero can use memset. cast
696  // element to (void*) to silence compiler warning for virtual
697  // classes (they will never arrive here because they are
698  // non-trivial).
699  if (std::is_trivial<T>::value == true)
700  std::memset(static_cast<void *>(destination_ + begin),
701  0,
702  (end - begin) * sizeof(T));
703  else
704  default_construct_or_assign(
705  begin, end, std::integral_constant<bool, initialize_memory>());
706  }
707 
708  private:
709  mutable T *destination_;
710 
711  // copy assignment operation
712  void
714  const std::size_t end,
715  std::integral_constant<bool, false>) const
716  {
717  for (std::size_t i = begin; i < end; ++i)
718  destination_[i] = std::move(T());
719  }
720 
721  // copy constructor (memory initialization)
722  void
724  const std::size_t end,
725  std::integral_constant<bool, true>) const
726  {
727  for (std::size_t i = begin; i < end; ++i)
728  new (&destination_[i]) T;
729  }
730  };
731 
732 } // end of namespace internal
733 
734 
735 #ifndef DOXYGEN
736 
737 
738 template <class T>
740  : elements(nullptr, [](T *) { Assert(false, ExcInternalError()); })
741  , used_elements_end(nullptr)
742  , allocated_elements_end(nullptr)
743 {}
744 
745 
746 
747 template <class T>
748 inline AlignedVector<T>::AlignedVector(const size_type size, const T &init)
749  : elements(nullptr, [](T *) { Assert(false, ExcInternalError()); })
750  , used_elements_end(nullptr)
751  , allocated_elements_end(nullptr)
752 {
753  if (size > 0)
754  resize(size, init);
755 }
756 
757 
758 
759 template <class T>
761 {
762  clear();
763 }
764 
765 
766 
767 template <class T>
769  : elements(nullptr, [](T *) { Assert(false, ExcInternalError()); })
770  , used_elements_end(nullptr)
771  , allocated_elements_end(nullptr)
772 {
773  // copy the data from vec
774  reserve(vec.size());
776  internal::AlignedVectorCopy<T>(vec.elements.get(),
777  vec.used_elements_end,
778  elements.get());
779 }
780 
781 
782 
783 template <class T>
785  : elements(std::move(vec.elements))
786  , used_elements_end(vec.used_elements_end)
787  , allocated_elements_end(vec.allocated_elements_end)
788 {
789  vec.elements = nullptr;
790  vec.used_elements_end = nullptr;
791  vec.allocated_elements_end = nullptr;
792 }
793 
794 
795 
796 template <class T>
797 inline AlignedVector<T> &
799 {
800  resize(0);
801  resize_fast(vec.used_elements_end - vec.elements.get());
802  internal::AlignedVectorCopy<T>(vec.elements.get(),
803  vec.used_elements_end,
804  elements.get());
805  return *this;
806 }
807 
808 
809 
810 template <class T>
811 inline AlignedVector<T> &
813 {
814  clear();
815 
816  // Move the actual data
817  elements = std::move(vec.elements);
818 
819  // Then also steal the other pointers and clear them in the original object:
820  used_elements_end = vec.used_elements_end;
821  allocated_elements_end = vec.allocated_elements_end;
822 
823  vec.used_elements_end = nullptr;
824  vec.allocated_elements_end = nullptr;
825 
826  return *this;
827 }
828 
829 
830 
831 template <class T>
832 inline void
834 {
835  const size_type old_size = size();
836 
837  if (new_size == 0)
838  clear();
839  else if (new_size == old_size)
840  {} // nothing to do here
841  else if (new_size < old_size)
842  {
843  // call destructor on fields that are released. doing it backward
844  // releases the elements in reverse order as compared to how they were
845  // created
846  if (std::is_trivial<T>::value == false)
847  {
848  while (used_elements_end != elements.get() + new_size)
849  (--used_elements_end)->~T();
850  }
851  else
852  used_elements_end = elements.get() + new_size;
853  }
854  else // new_size > old_size
855  {
856  // Allocate more space, and claim that space as used
857  reserve(new_size);
858  used_elements_end = elements.get() + new_size;
859 
860  // need to still set the values in case the class is non-trivial because
861  // virtual classes etc. need to run their (default) constructor
862  if (std::is_trivial<T>::value == false)
864  new_size - old_size, elements.get() + old_size);
865  }
866 }
867 
868 
869 
870 template <class T>
871 inline void
872 AlignedVector<T>::resize(const size_type new_size)
873 {
874  const size_type old_size = size();
875 
876  if (new_size == 0)
877  clear();
878  else if (new_size == old_size)
879  {} // nothing to do here
880  else if (new_size < old_size)
881  {
882  // call destructor on fields that are released. doing it backward
883  // releases the elements in reverse order as compared to how they were
884  // created
885  if (std::is_trivial<T>::value == false)
886  {
887  while (used_elements_end != elements.get() + new_size)
888  (--used_elements_end)->~T();
889  }
890  else
891  used_elements_end = elements.get() + new_size;
892  }
893  else // new_size > old_size
894  {
895  // Allocate more space, and claim that space as used
896  reserve(new_size);
897  used_elements_end = elements.get() + new_size;
898 
899  // finally set the values to the default initializer
901  new_size - old_size, elements.get() + old_size);
902  }
903 }
904 
905 
906 
907 template <class T>
908 inline void
909 AlignedVector<T>::resize(const size_type new_size, const T &init)
910 {
911  const size_type old_size = size();
912 
913  if (new_size == 0)
914  clear();
915  else if (new_size == old_size)
916  {} // nothing to do here
917  else if (new_size < old_size)
918  {
919  // call destructor on fields that are released. doing it backward
920  // releases the elements in reverse order as compared to how they were
921  // created
922  if (std::is_trivial<T>::value == false)
923  {
924  while (used_elements_end != elements.get() + new_size)
925  (--used_elements_end)->~T();
926  }
927  else
928  used_elements_end = elements.get() + new_size;
929  }
930  else // new_size > old_size
931  {
932  // Allocate more space, and claim that space as used
933  reserve(new_size);
934  used_elements_end = elements.get() + new_size;
935 
936  // finally set the desired init values
937  ::internal::AlignedVectorSet<T, true>(new_size - old_size,
938  init,
939  elements.get() + old_size);
940  }
941 }
942 
943 
944 
945 template <class T>
946 inline void
947 AlignedVector<T>::reserve(const size_type new_allocated_size)
948 {
949  const size_type old_size = used_elements_end - elements.get();
950  const size_type old_allocated_size = allocated_elements_end - elements.get();
951  if (new_allocated_size > old_allocated_size)
952  {
953  // if we continuously increase the size of the vector, we might be
954  // reallocating a lot of times. therefore, try to increase the size more
955  // aggressively
956  const size_type new_size =
957  std::max(new_allocated_size, 2 * old_allocated_size);
958 
959  // allocate and align along 64-byte boundaries (this is enough for all
960  // levels of vectorization currently supported by deal.II)
961  T *new_data_ptr;
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) {
965  std::free(ptr);
966  });
967 
968  // copy whatever elements we need to retain
969  if (new_allocated_size > 0)
971  elements.get() + old_size,
972  new_data.get());
973 
974  // Now reset all of the member variables of the current object
975  // based on the allocation above. Assigning to a std::unique_ptr
976  // object also releases the previously pointed to memory.
977  elements = std::move(new_data);
978  used_elements_end = elements.get() + old_size;
979  allocated_elements_end = elements.get() + new_size;
980  }
981  else if (new_allocated_size == 0)
982  clear();
983  else // size_alloc < allocated_size
984  {} // nothing to do here
985 }
986 
987 
988 
989 template <class T>
990 inline void
992 {
993  if (elements != nullptr)
994  {
995  if (std::is_trivial<T>::value == false)
996  while (used_elements_end != elements.get())
997  (--used_elements_end)->~T();
998  }
999  elements = nullptr;
1000  used_elements_end = nullptr;
1001  allocated_elements_end = nullptr;
1002 }
1003 
1004 
1005 
1006 template <class T>
1007 inline void
1008 AlignedVector<T>::push_back(const T in_data)
1009 {
1012  reserve(std::max(2 * capacity(), static_cast<size_type>(16)));
1013  if (std::is_trivial<T>::value == false)
1014  new (used_elements_end++) T(in_data);
1015  else
1016  *used_elements_end++ = in_data;
1017 }
1018 
1019 
1020 
1021 template <class T>
1022 inline typename AlignedVector<T>::reference
1024 {
1025  AssertIndexRange(0, size());
1026  T *field = used_elements_end - 1;
1027  return *field;
1028 }
1029 
1030 
1031 
1032 template <class T>
1033 inline typename AlignedVector<T>::const_reference
1034 AlignedVector<T>::back() const
1035 {
1036  AssertIndexRange(0, size());
1037  const T *field = used_elements_end - 1;
1038  return *field;
1039 }
1040 
1041 
1042 
1043 template <class T>
1044 template <typename ForwardIterator>
1045 inline void
1046 AlignedVector<T>::insert_back(ForwardIterator begin, ForwardIterator end)
1047 {
1048  const unsigned int old_size = size();
1049  reserve(old_size + (end - begin));
1050  for (; begin != end; ++begin, ++used_elements_end)
1051  {
1052  if (std::is_trivial<T>::value == false)
1053  new (used_elements_end) T;
1055  }
1056 }
1057 
1058 
1059 
1060 template <class T>
1061 inline void
1063 {
1065  elements.get());
1066 }
1067 
1068 
1069 
1070 template <class T>
1071 inline void
1073 {
1075 }
1076 
1077 
1078 
1079 template <class T>
1080 inline void
1082 {
1083  std::swap(elements, vec.elements);
1084  std::swap(used_elements_end, vec.used_elements_end);
1085  std::swap(allocated_elements_end, vec.allocated_elements_end);
1086 }
1087 
1088 
1089 
1090 template <class T>
1091 inline bool
1093 {
1094  return used_elements_end == elements.get();
1095 }
1096 
1097 
1098 
1099 template <class T>
1100 inline typename AlignedVector<T>::size_type
1101 AlignedVector<T>::size() const
1102 {
1103  return used_elements_end - elements.get();
1104 }
1105 
1106 
1107 
1108 template <class T>
1109 inline typename AlignedVector<T>::size_type
1111 {
1112  return allocated_elements_end - elements.get();
1113 }
1114 
1115 
1116 
1117 template <class T>
1119  operator[](const size_type index)
1120 {
1121  AssertIndexRange(index, size());
1122  return elements[index];
1123 }
1124 
1125 
1126 
1127 template <class T>
1129  operator[](const size_type index) const
1130 {
1131  AssertIndexRange(index, size());
1132  return elements[index];
1133 }
1134 
1135 
1136 
1137 template <typename T>
1138 inline typename AlignedVector<T>::pointer
1140 {
1141  return elements.get();
1142 }
1143 
1144 
1145 
1146 template <typename T>
1147 inline typename AlignedVector<T>::const_pointer
1148 AlignedVector<T>::data() const
1149 {
1150  return elements.get();
1151 }
1152 
1153 
1154 
1155 template <class T>
1156 inline typename AlignedVector<T>::iterator
1158 {
1159  return elements.get();
1160 }
1161 
1162 
1163 
1164 template <class T>
1165 inline typename AlignedVector<T>::iterator
1167 {
1168  return used_elements_end;
1169 }
1170 
1171 
1172 
1173 template <class T>
1174 inline typename AlignedVector<T>::const_iterator
1176 {
1177  return elements.get();
1178 }
1179 
1180 
1181 
1182 template <class T>
1183 inline typename AlignedVector<T>::const_iterator
1184 AlignedVector<T>::end() const
1185 {
1186  return used_elements_end;
1187 }
1188 
1189 
1190 
1191 template <class T>
1192 template <class Archive>
1193 inline void
1194 AlignedVector<T>::save(Archive &ar, const unsigned int) const
1195 {
1196  size_type vec_size(size());
1197  ar & vec_size;
1198  if (vec_size > 0)
1199  ar &boost::serialization::make_array(elements.get(), vec_size);
1200 }
1201 
1202 
1203 
1204 template <class T>
1205 template <class Archive>
1206 inline void
1207 AlignedVector<T>::load(Archive &ar, const unsigned int)
1208 {
1209  size_type vec_size = 0;
1210  ar & vec_size;
1211 
1212  if (vec_size > 0)
1213  {
1214  reserve(vec_size);
1215  ar &boost::serialization::make_array(elements.get(), vec_size);
1216  used_elements_end = elements.get() + vec_size;
1217  }
1218 }
1219 
1220 
1221 
1222 template <class T>
1223 inline typename AlignedVector<T>::size_type
1225 {
1226  size_type memory = sizeof(*this);
1227  for (const T *t = elements.get(); t != used_elements_end; ++t)
1228  memory += ::MemoryConsumption::memory_consumption(*t);
1229  memory += sizeof(T) * (allocated_elements_end - used_elements_end);
1230  return memory;
1231 }
1232 
1233 
1234 #endif // ifndef DOXYGEN
1235 
1236 
1242 template <class T>
1243 bool
1245 {
1246  if (lhs.size() != rhs.size())
1247  return false;
1248  for (typename AlignedVector<T>::const_iterator lit = lhs.begin(),
1249  rit = rhs.begin();
1250  lit != lhs.end();
1251  ++lit, ++rit)
1252  if (*lit != *rit)
1253  return false;
1254  return true;
1255 }
1256 
1257 
1258 
1264 template <class T>
1265 bool
1267 {
1268  return !(operator==(lhs, rhs));
1269 }
1270 
1271 
1273 
1274 #endif
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)
Definition: utilities.cc:1050
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
value_type * pointer
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
#define AssertIndexRange(index, range)
Definition: exceptions.h:1698
pointer data()
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)
value_type * iterator
reference operator[](const size_type index)
void serialize(Archive &archive, const unsigned int version)
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
static const char T
#define Assert(cond, exc)
Definition: exceptions.h:1473
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:396
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
value_type & reference
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
iterator end()
AlignedVectorMove(T *const source_begin, T *const source_end, T *const destination)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:395
AlignedVectorCopy(const T *const source_begin, const T *const source_end, T *const destination)
void resize_fast(const size_type new_size)
iterator begin()
AlignedVectorSet(const std::size_t size, const T &element, T *const destination)
size_type size() const
unsigned int minimum_parallel_grain_size
Definition: parallel.cc:34
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
void free(T *&pointer)
Definition: cuda.h:97
const value_type * const_pointer
bool empty() const
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)
reference back()
static ::ExceptionBase & ExcInternalError()