Reference documentation for deal.II version GIT a2efd28e10 2023-02-01 14:45:02+00:00
\(\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\}}\)
array_view.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2021 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 #ifndef dealii_array_view_h
17 #define dealii_array_view_h
18 
19 #include <deal.II/base/config.h>
20 
24 #include <deal.II/base/tensor.h>
25 
26 #include <array>
27 #include <type_traits>
28 #include <vector>
29 
31 
32 // Forward declaration
33 template <int N, typename T>
34 class Table;
35 
36 template <typename number>
37 class LAPACKFullMatrix;
38 
39 
81 template <typename ElementType, typename MemorySpaceType = MemorySpace::Host>
82 class ArrayView
83 {
84 public:
90 
94  using iterator = value_type *;
95 
99  using const_iterator = const ElementType *;
100 
105 
126 
136  ArrayView(const ArrayView<typename std::remove_cv<value_type>::type,
137  MemorySpaceType> &view);
138 
143  explicit ArrayView(value_type &element);
144 
160  const std::vector<typename std::remove_cv<value_type>::type> &vector);
161 
176  ArrayView(std::vector<typename std::remove_cv<value_type>::type> &vector);
177 
192  template <std::size_t N>
193  ArrayView(value_type (&array)[N]);
194 
203  template <std::size_t N>
205  const std::array<typename std::remove_cv<value_type>::type, N> &vector);
206 
215  template <std::size_t N>
216  ArrayView(std::array<typename std::remove_cv<value_type>::type, N> &vector);
217 
237  void
239 
253  bool
255  const ArrayView<const value_type, MemorySpaceType> &other_view) const;
256 
270  bool
271  operator==(const ArrayView<typename std::remove_cv<value_type>::type,
272  MemorySpaceType> &other_view) const;
273 
290  bool
292  const ArrayView<const value_type, MemorySpaceType> &other_view) const;
293 
307  bool
308  operator!=(const ArrayView<typename std::remove_cv<value_type>::type,
309  MemorySpaceType> &other_view) const;
310 
315  std::size_t
316  size() const;
317 
322  value_type *
323  data() const noexcept;
324 
328  iterator
329  begin() const;
330 
334  iterator
335  end() const;
336 
341  cbegin() const;
342 
347  cend() const;
348 
361  value_type &
362  operator[](const std::size_t i) const;
363 
364 private:
370 
374  std::size_t n_elements;
375 
376  friend class ArrayView<const ElementType, MemorySpaceType>;
377 };
378 
379 
380 
381 //---------------------------------------------------------------------------
382 
383 
384 template <typename ElementType, typename MemorySpaceType>
385 inline ArrayView<ElementType, MemorySpaceType>::ArrayView()
386  : starting_element(nullptr)
387  , n_elements(0)
388 {}
389 
390 
391 
392 template <typename ElementType, typename MemorySpaceType>
395  const std::size_t n_elements)
398 {}
399 
400 
401 
402 template <typename ElementType, typename MemorySpaceType>
403 inline void
405  const std::size_t n_elements)
406 {
407  this->starting_element = starting_element;
408  this->n_elements = n_elements;
409 }
410 
411 
412 
413 template <typename ElementType, typename MemorySpaceType>
415  : starting_element(&element)
416  , n_elements(1)
417 {}
418 
419 
420 
421 template <typename ElementType, typename MemorySpaceType>
423  const ArrayView<typename std::remove_cv<value_type>::type, MemorySpaceType>
424  &view)
425  : starting_element(view.starting_element)
426  , n_elements(view.n_elements)
427 {}
428 
429 
430 
431 template <typename ElementType, typename MemorySpaceType>
433  const std::vector<typename std::remove_cv<value_type>::type> &vector)
434  : // use delegating constructor
435  ArrayView(vector.data(), vector.size())
436 {
437  // the following static_assert is not strictly necessary because,
438  // if we got a const std::vector reference argument but ElementType
439  // is not itself const, then the call to the forwarding constructor
440  // above will already have failed: vector.data() will have returned
441  // a const pointer, but we need a non-const pointer.
442  //
443  // nevertheless, leave the static_assert in since it provides a
444  // more descriptive error message that will simply come after the first
445  // error produced above
446  static_assert(std::is_const<value_type>::value == true,
447  "This constructor may only be called if the ArrayView "
448  "object has a const value_type. In other words, you can "
449  "only create an ArrayView to const values from a const "
450  "std::vector.");
451 }
452 
453 
454 
455 template <typename ElementType, typename MemorySpaceType>
457  std::vector<typename std::remove_cv<value_type>::type> &vector)
458  : // use delegating constructor
459  ArrayView(vector.data(), vector.size())
460 {}
461 
462 
463 
464 template <typename ElementType, typename MemorySpaceType>
465 template <std::size_t N>
467  const std::array<typename std::remove_cv<value_type>::type, N> &vector)
468  : // use delegating constructor
469  ArrayView(vector.data(), vector.size())
470 {
471  // the following static_assert is not strictly necessary because,
472  // if we got a const std::array reference argument but ElementType
473  // is not itself const, then the call to the forwarding constructor
474  // above will already have failed: vector.data() will have returned
475  // a const pointer, but we need a non-const pointer.
476  //
477  // nevertheless, leave the static_assert in since it provides a
478  // more descriptive error message that will simply come after the first
479  // error produced above
480  static_assert(std::is_const<value_type>::value == true,
481  "This constructor may only be called if the ArrayView "
482  "object has a const value_type. In other words, you can "
483  "only create an ArrayView to const values from a const "
484  "std::array.");
485 }
486 
487 
488 
489 template <typename ElementType, typename MemorySpaceType>
490 template <std::size_t N>
492  ElementType (&array)[N])
493  : ArrayView(&array[0], N)
494 {}
495 
496 
497 
498 template <typename ElementType, typename MemorySpaceType>
499 template <std::size_t N>
501  std::array<typename std::remove_cv<value_type>::type, N> &vector)
502  : // use delegating constructor
503  ArrayView(vector.data(), vector.size())
504 {}
505 
506 
507 
508 template <typename ElementType, typename MemorySpaceType>
509 inline bool
511  const ArrayView<const value_type, MemorySpaceType> &other_view) const
512 {
513  return (other_view.data() == starting_element) &&
514  (other_view.size() == n_elements);
515 }
516 
517 
518 
519 template <typename ElementType, typename MemorySpaceType>
520 inline bool
522  const ArrayView<typename std::remove_cv<value_type>::type, MemorySpaceType>
523  &other_view) const
524 {
525  return (other_view.data() == starting_element) &&
526  (other_view.size() == n_elements);
527 }
528 
529 
530 
531 template <typename ElementType, typename MemorySpaceType>
532 inline bool
534  const ArrayView<const value_type, MemorySpaceType> &other_view) const
535 {
536  return !(*this == other_view);
537 }
538 
539 
540 
541 template <typename ElementType, typename MemorySpaceType>
544 {
545  if (n_elements == 0)
546  return nullptr;
547  else
548  return starting_element;
549 }
550 
551 
552 
553 template <typename ElementType, typename MemorySpaceType>
554 inline bool
556  const ArrayView<typename std::remove_cv<value_type>::type, MemorySpaceType>
557  &other_view) const
558 {
559  return !(*this == other_view);
560 }
561 
562 
563 
564 template <typename ElementType, typename MemorySpaceType>
565 inline std::size_t
567 {
568  return n_elements;
569 }
570 
571 
572 
573 template <typename ElementType, typename MemorySpaceType>
576 {
577  return starting_element;
578 }
579 
580 
581 
582 template <typename ElementType, typename MemorySpaceType>
585 {
586  return starting_element + n_elements;
587 }
588 
589 
590 
591 template <typename ElementType, typename MemorySpaceType>
594 {
595  return starting_element;
596 }
597 
598 
599 
600 template <typename ElementType, typename MemorySpaceType>
603 {
604  return starting_element + n_elements;
605 }
606 
607 
608 
609 template <typename ElementType, typename MemorySpaceType>
612 {
613  AssertIndexRange(i, n_elements);
614 
615  return *(starting_element + i);
616 }
617 
618 
619 
620 #ifndef DOXYGEN
621 namespace internal
622 {
623  namespace ArrayViewHelper
624  {
630  template <class Iterator>
631  bool
632  is_contiguous(const Iterator &first, const Iterator &last)
633  {
634  const auto n = std::distance(first, last);
635  for (typename std::decay<decltype(n)>::type i = 0; i < n; ++i)
636  if (std::addressof(*(std::next(first, i))) !=
637  std::next(std::addressof(*first), i))
638  return false;
639  return true;
640  }
641 
642 
653  template <class T>
654  constexpr bool
655  is_contiguous(T *, T *)
656  {
657  return true;
658  }
659  } // namespace ArrayViewHelper
660 } // namespace internal
661 #endif
662 
663 
664 
681 template <typename Iterator, typename MemorySpaceType = MemorySpace::Host>
682 ArrayView<typename std::remove_reference<
683  typename std::iterator_traits<Iterator>::reference>::type,
684  MemorySpaceType>
685 make_array_view(const Iterator begin, const Iterator end)
686 {
687  static_assert(
688  std::is_same<typename std::iterator_traits<Iterator>::iterator_category,
689  typename std::random_access_iterator_tag>::value,
690  "The provided iterator needs to be a random access iterator.");
691  Assert(begin <= end,
692  ExcMessage(
693  "The beginning of the array view needs to be before the end."));
694  Assert(internal::ArrayViewHelper::is_contiguous(begin, end),
695  ExcMessage("The provided range isn't contiguous in memory!"));
696  // the reference type, not the value type, knows the constness of the iterator
697  return ArrayView<typename std::remove_reference<
698  typename std::iterator_traits<Iterator>::reference>::type,
699  MemorySpaceType>(std::addressof(*begin), end - begin);
700 }
701 
702 
703 
713 template <typename ElementType, typename MemorySpaceType = MemorySpace::Host>
716 {
717  Assert(begin <= end,
718  ExcMessage(
719  "The beginning of the array view needs to be before the end."));
721 }
722 
723 
724 
735 template <typename Number, typename MemorySpaceType>
738 {
739  return make_array_view(array_view.cbegin(), array_view.cend());
740 }
741 
742 
743 
754 template <typename Number, typename MemorySpaceType>
757 {
758  return make_array_view(array_view.begin(), array_view.end());
759 }
760 
761 
762 
784 template <int rank, int dim, typename Number>
787 {
788  return make_array_view(tensor.begin_raw(), tensor.end_raw());
789 }
790 
791 
792 
814 template <int rank, int dim, typename Number>
817 {
818  return make_array_view(tensor.begin_raw(), tensor.end_raw());
819 }
820 
821 
822 
844 template <int rank, int dim, typename Number>
847 {
848  return make_array_view(tensor.begin_raw(), tensor.end_raw());
849 }
850 
851 
852 
875 template <int rank, int dim, typename Number>
878 {
879  return make_array_view(tensor.begin_raw(), tensor.end_raw());
880 }
881 
882 
883 
897 template <typename ElementType, int N>
899 {
900  return ArrayView<ElementType>(array, N);
901 }
902 
903 
904 
919 template <typename ElementType>
922 {
923  return ArrayView<ElementType>(vector.begin(), vector.size());
924 }
925 
926 
927 
942 template <typename ElementType>
945 {
946  return ArrayView<const ElementType>(vector.begin(), vector.size());
947 }
948 
949 
950 
965 template <typename ElementType>
967 make_array_view(std::vector<ElementType> &vector)
968 {
969  return ArrayView<ElementType>(vector.data(), vector.size());
970 }
971 
972 
973 
988 template <typename ElementType>
990 make_array_view(const std::vector<ElementType> &vector)
991 {
992  return ArrayView<const ElementType>(vector.data(), vector.size());
993 }
994 
995 
996 
1016 template <typename ElementType>
1018 make_array_view(std::vector<ElementType> &vector,
1019  const std::size_t starting_index,
1020  const std::size_t size_of_view)
1021 {
1022  Assert(starting_index + size_of_view <= vector.size(),
1023  ExcMessage("The starting index and size of the view you want to "
1024  "create would lead to a view that extends beyond the end "
1025  "of the given vector."));
1026  return ArrayView<ElementType>(&vector[starting_index], size_of_view);
1027 }
1028 
1029 
1030 
1050 template <typename ElementType>
1052 make_array_view(const std::vector<ElementType> &vector,
1053  const std::size_t starting_index,
1054  const std::size_t size_of_view)
1055 {
1056  Assert(starting_index + size_of_view <= vector.size(),
1057  ExcMessage("The starting index and size of the view you want to "
1058  "create would lead to a view that extends beyond the end "
1059  "of the given vector."));
1060  return ArrayView<const ElementType>(&vector[starting_index], size_of_view);
1061 }
1062 
1063 
1064 
1079 template <typename ElementType, std::size_t N>
1081 make_array_view(std::array<ElementType, N> &array)
1082 {
1083  return ArrayView<ElementType>(array);
1084 }
1085 
1086 
1087 
1102 template <typename ElementType, std::size_t N>
1104 make_array_view(const std::array<ElementType, N> &array)
1105 {
1106  return ArrayView<const ElementType>(array);
1107 }
1108 
1109 
1110 
1127 template <typename ElementType>
1130  const typename Table<2, ElementType>::size_type row)
1131 {
1132  AssertIndexRange(row, table.size()[0]);
1133  return ArrayView<ElementType>(&table[row][0], table.size()[1]);
1134 }
1135 
1136 
1137 
1154 template <typename ElementType>
1157 {
1158  return ArrayView<ElementType>(&table[0][0], table.n_elements());
1159 }
1160 
1161 
1162 
1179 template <typename ElementType>
1182 {
1183  return ArrayView<const ElementType>(&table[0][0], table.n_elements());
1184 }
1185 
1186 
1204 template <typename ElementType>
1207 {
1208  return ArrayView<ElementType>(&matrix(0, 0), matrix.n_elements());
1209 }
1210 
1211 
1212 
1229 template <typename ElementType>
1232 {
1233  return ArrayView<const ElementType>(&matrix(0, 0), matrix.n_elements());
1234 }
1235 
1236 
1237 
1254 template <typename ElementType>
1257  const typename Table<2, ElementType>::size_type row)
1258 {
1259  AssertIndexRange(row, table.size()[0]);
1260  return ArrayView<const ElementType>(&table[row][0], table.size()[1]);
1261 }
1262 
1263 
1264 
1284 template <typename ElementType>
1287  const typename Table<2, ElementType>::size_type row,
1288  const typename Table<2, ElementType>::size_type starting_column,
1289  const std::size_t size_of_view)
1290 {
1291  AssertIndexRange(row, table.size()[0]);
1292  AssertIndexRange(starting_column, table.size()[1]);
1293  Assert(starting_column + size_of_view <= table.size()[1],
1294  ExcMessage("The starting index and size of the view you want to "
1295  "create would lead to a view that extends beyond the end "
1296  "of a column of the given table."));
1297  return ArrayView<ElementType>(&table[row][starting_column], size_of_view);
1298 }
1299 
1300 
1301 
1321 template <typename ElementType>
1324  const typename Table<2, ElementType>::size_type row,
1325  const typename Table<2, ElementType>::size_type starting_column,
1326  const std::size_t size_of_view)
1327 {
1328  AssertIndexRange(row, table.size()[0]);
1329  AssertIndexRange(starting_column, table.size()[1]);
1330  Assert(starting_column + size_of_view <= table.size()[1],
1331  ExcMessage("The starting index and size of the view you want to "
1332  "create would lead to a view that extends beyond the end "
1333  "of a column of the given table."));
1334  return ArrayView<const ElementType>(&table[row][starting_column],
1335  size_of_view);
1336 }
1337 
1338 
1339 
1340 /*
1341  * Create a view that doesn't allow the container it points to to be modified.
1342  * This is useful if the object passed in is not `const` already and a function
1343  * requires a view to constant memory in its signature.
1344  *
1345  * This function returns an object of type `ArrayView<const T>` where `T` is the
1346  * element type of the container.
1347  *
1348  * @relatesalso ArrayView
1349  */
1350 template <typename Container>
1351 inline auto
1352 make_const_array_view(const Container &container)
1353  -> decltype(make_array_view(container))
1354 {
1355  return make_array_view(container);
1356 }
1357 
1358 
1360 
1361 #endif
auto make_const_array_view(const Container &container) -> decltype(make_array_view(container))
Definition: array_view.h:1352
ArrayView< const ElementType > make_array_view(const Vector< ElementType > &vector)
Definition: array_view.h:944
ArrayView(value_type &element)
Definition: array_view.h:414
iterator begin() const
Definition: array_view.h:575
ArrayView(const ArrayView< typename std::remove_cv< value_type >::type, MemorySpaceType > &view)
Definition: array_view.h:422
ArrayView< Number, MemorySpaceType > make_array_view(ArrayView< Number, MemorySpaceType > &array_view)
Definition: array_view.h:756
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
Definition: array_view.h:685
value_type * iterator
Definition: array_view.h:94
ArrayView< Number > make_array_view(SymmetricTensor< rank, dim, Number > &tensor)
Definition: array_view.h:877
value_type & operator[](const std::size_t i) const
Definition: array_view.h:611
ArrayView< const ElementType > make_array_view(const LAPACKFullMatrix< ElementType > &matrix)
Definition: array_view.h:1231
ArrayView< ElementType > make_array_view(std::array< ElementType, N > &array)
Definition: array_view.h:1081
ArrayView< const Number > make_array_view(const Tensor< rank, dim, Number > &tensor)
Definition: array_view.h:786
ArrayView< const Number > make_array_view(const SymmetricTensor< rank, dim, Number > &tensor)
Definition: array_view.h:846
ArrayView< ElementType > make_array_view(LAPACKFullMatrix< ElementType > &matrix)
Definition: array_view.h:1206
ArrayView< ElementType > make_array_view(ElementType(&array)[N])
Definition: array_view.h:898
ArrayView< ElementType, MemorySpaceType > make_array_view(ElementType *const begin, ElementType *const end)
Definition: array_view.h:715
bool operator!=(const ArrayView< typename std::remove_cv< value_type >::type, MemorySpaceType > &other_view) const
Definition: array_view.h:555
const_iterator cend() const
Definition: array_view.h:602
iterator end() const
Definition: array_view.h:584
ArrayView< const ElementType > make_array_view(const std::vector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
Definition: array_view.h:1052
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table)
Definition: array_view.h:1181
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row, const typename Table< 2, ElementType >::size_type starting_column, const std::size_t size_of_view)
Definition: array_view.h:1323
ArrayView(const std::array< typename std::remove_cv< value_type >::type, N > &vector)
Definition: array_view.h:466
ArrayView< ElementType > make_array_view(std::vector< ElementType > &vector)
Definition: array_view.h:967
ArrayView(std::vector< typename std::remove_cv< value_type >::type > &vector)
Definition: array_view.h:456
bool operator==(const ArrayView< const value_type, MemorySpaceType > &other_view) const
Definition: array_view.h:510
ArrayView< ElementType > make_array_view(std::vector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
Definition: array_view.h:1018
bool operator!=(const ArrayView< const value_type, MemorySpaceType > &other_view) const
Definition: array_view.h:533
const_iterator cbegin() const
Definition: array_view.h:593
ArrayView(const std::vector< typename std::remove_cv< value_type >::type > &vector)
Definition: array_view.h:432
ArrayView(value_type(&array)[N])
Definition: array_view.h:491
ArrayView< Number > make_array_view(Tensor< rank, dim, Number > &tensor)
Definition: array_view.h:816
value_type * data() const noexcept
Definition: array_view.h:543
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row, const typename Table< 2, ElementType >::size_type starting_column, const std::size_t size_of_view)
Definition: array_view.h:1286
void reinit(value_type *starting_element, const std::size_t n_elements)
Definition: array_view.h:404
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table)
Definition: array_view.h:1156
value_type * starting_element
Definition: array_view.h:369
std::size_t size() const
Definition: array_view.h:566
bool operator==(const ArrayView< typename std::remove_cv< value_type >::type, MemorySpaceType > &other_view) const
Definition: array_view.h:521
ElementType value_type
Definition: array_view.h:89
ArrayView(value_type *starting_element, const std::size_t n_elements)
Definition: array_view.h:393
std::size_t n_elements
Definition: array_view.h:374
ArrayView< const Number, MemorySpaceType > make_array_view(const ArrayView< Number, MemorySpaceType > &array_view)
Definition: array_view.h:737
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
Definition: array_view.h:1256
const ElementType * const_iterator
Definition: array_view.h:99
ArrayView< ElementType > make_array_view(Vector< ElementType > &vector)
Definition: array_view.h:921
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
Definition: array_view.h:1129
ArrayView< const ElementType > make_array_view(const std::vector< ElementType > &vector)
Definition: array_view.h:990
ArrayView< const ElementType > make_array_view(const std::array< ElementType, N > &array)
Definition: array_view.h:1104
ArrayView(std::array< typename std::remove_cv< value_type >::type, N > &vector)
Definition: array_view.h:500
Number * begin_raw()
Number * end_raw()
Definition: tensor.h:503
Number * end_raw()
Number * begin_raw()
Definition: vector.h:109
size_type size() const
iterator begin()
#define DEAL_II_DEPRECATED
Definition: config.h:162
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:461
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:462
Point< 2 > first
Definition: grid_out.cc:4605
#define Assert(cond, exc)
Definition: exceptions.h:1509
#define AssertIndexRange(index, range)
Definition: exceptions.h:1768
static ::ExceptionBase & ExcMessage(std::string arg1)
@ matrix
Contents is actually a matrix.
static const char T
static const char N
VectorType::value_type * begin(VectorType &V)
VectorType::value_type * end(VectorType &V)