Reference documentation for deal.II version 9.5.0
\(\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\}}\)
Loading...
Searching...
No Matches
array_view.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2004 - 2023 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
33template <class T>
34class AlignedVector;
35
36template <int N, typename T>
37class Table;
38
39template <typename number>
41
42
84template <typename ElementType, typename MemorySpaceType = MemorySpace::Host>
86{
87public:
92 using value_type = ElementType;
93
98
102 using const_iterator = const ElementType *;
103
108
129
139 ArrayView(const ArrayView<typename std::remove_cv<value_type>::type,
140 MemorySpaceType> &view);
141
146 explicit ArrayView(value_type &element);
147
163 const std::vector<typename std::remove_cv<value_type>::type> &vector);
164
179 ArrayView(std::vector<typename std::remove_cv<value_type>::type> &vector);
180
195 template <std::size_t N>
196 ArrayView(value_type (&array)[N]);
197
206 template <std::size_t N>
208 const std::array<typename std::remove_cv<value_type>::type, N> &vector);
209
218 template <std::size_t N>
219 ArrayView(std::array<typename std::remove_cv<value_type>::type, N> &vector);
220
240 void
242
256 bool
258 const ArrayView<const value_type, MemorySpaceType> &other_view) const;
259
273 bool
274 operator==(const ArrayView<typename std::remove_cv<value_type>::type,
275 MemorySpaceType> &other_view) const;
276
293 bool
295 const ArrayView<const value_type, MemorySpaceType> &other_view) const;
296
310 bool
311 operator!=(const ArrayView<typename std::remove_cv<value_type>::type,
312 MemorySpaceType> &other_view) const;
313
318 std::size_t
319 size() const;
320
324 bool
325 empty() const;
326
332 data() const noexcept;
333
338 begin() const;
339
344 end() const;
345
350 cbegin() const;
351
356 cend() const;
357
370 value_type &
371 operator[](const std::size_t i) const;
372
373private:
379
384
385 friend class ArrayView<const ElementType, MemorySpaceType>;
386};
387
388
389
390//---------------------------------------------------------------------------
391
392
393template <typename ElementType, typename MemorySpaceType>
394inline ArrayView<ElementType, MemorySpaceType>::ArrayView()
395 : starting_element(nullptr)
396 , n_elements(0)
397{}
398
399
400
401template <typename ElementType, typename MemorySpaceType>
404 const std::size_t n_elements)
407{}
408
409
410
411template <typename ElementType, typename MemorySpaceType>
412inline void
414 const std::size_t n_elements)
415{
416 this->starting_element = starting_element;
417 this->n_elements = n_elements;
418}
419
420
421
422template <typename ElementType, typename MemorySpaceType>
424 : starting_element(&element)
425 , n_elements(1)
426{}
427
428
429
430template <typename ElementType, typename MemorySpaceType>
432 const ArrayView<typename std::remove_cv<value_type>::type, MemorySpaceType>
433 &view)
434 : starting_element(view.starting_element)
435 , n_elements(view.n_elements)
436{}
437
438
439
440template <typename ElementType, typename MemorySpaceType>
442 const std::vector<typename std::remove_cv<value_type>::type> &vector)
443 : // use delegating constructor
444 ArrayView(vector.data(), vector.size())
445{
446 // the following static_assert is not strictly necessary because,
447 // if we got a const std::vector reference argument but ElementType
448 // is not itself const, then the call to the forwarding constructor
449 // above will already have failed: vector.data() will have returned
450 // a const pointer, but we need a non-const pointer.
451 //
452 // nevertheless, leave the static_assert in since it provides a
453 // more descriptive error message that will simply come after the first
454 // error produced above
455 static_assert(std::is_const<value_type>::value == true,
456 "This constructor may only be called if the ArrayView "
457 "object has a const value_type. In other words, you can "
458 "only create an ArrayView to const values from a const "
459 "std::vector.");
460}
461
462
463
464template <typename ElementType, typename MemorySpaceType>
466 std::vector<typename std::remove_cv<value_type>::type> &vector)
467 : // use delegating constructor
468 ArrayView(vector.data(), vector.size())
469{}
470
471
472
473template <typename ElementType, typename MemorySpaceType>
474template <std::size_t N>
476 const std::array<typename std::remove_cv<value_type>::type, N> &vector)
477 : // use delegating constructor
478 ArrayView(vector.data(), vector.size())
479{
480 // the following static_assert is not strictly necessary because,
481 // if we got a const std::array reference argument but ElementType
482 // is not itself const, then the call to the forwarding constructor
483 // above will already have failed: vector.data() will have returned
484 // a const pointer, but we need a non-const pointer.
485 //
486 // nevertheless, leave the static_assert in since it provides a
487 // more descriptive error message that will simply come after the first
488 // error produced above
489 static_assert(std::is_const<value_type>::value == true,
490 "This constructor may only be called if the ArrayView "
491 "object has a const value_type. In other words, you can "
492 "only create an ArrayView to const values from a const "
493 "std::array.");
494}
495
496
497
498template <typename ElementType, typename MemorySpaceType>
499template <std::size_t N>
501 ElementType (&array)[N])
502 : ArrayView(&array[0], N)
503{}
504
505
506
507template <typename ElementType, typename MemorySpaceType>
508template <std::size_t N>
510 std::array<typename std::remove_cv<value_type>::type, N> &vector)
511 : // use delegating constructor
512 ArrayView(vector.data(), vector.size())
513{}
514
515
516
517template <typename ElementType, typename MemorySpaceType>
518inline bool
520 const ArrayView<const value_type, MemorySpaceType> &other_view) const
521{
522 return (other_view.data() == starting_element) &&
523 (other_view.size() == n_elements);
524}
525
526
527
528template <typename ElementType, typename MemorySpaceType>
529inline bool
531 const ArrayView<typename std::remove_cv<value_type>::type, MemorySpaceType>
532 &other_view) const
533{
534 return (other_view.data() == starting_element) &&
535 (other_view.size() == n_elements);
536}
537
538
539
540template <typename ElementType, typename MemorySpaceType>
541inline bool
543 const ArrayView<const value_type, MemorySpaceType> &other_view) const
544{
545 return !(*this == other_view);
546}
547
548
549
550template <typename ElementType, typename MemorySpaceType>
554{
555 if (n_elements == 0)
556 return nullptr;
557 else
558 return starting_element;
559}
560
561
562
563template <typename ElementType, typename MemorySpaceType>
564inline bool
566 const ArrayView<typename std::remove_cv<value_type>::type, MemorySpaceType>
567 &other_view) const
568{
569 return !(*this == other_view);
570}
571
572
573
574template <typename ElementType, typename MemorySpaceType>
575inline std::size_t
577{
578 return n_elements;
579}
580
581
582
583template <typename ElementType, typename MemorySpaceType>
584inline bool
586{
587 return n_elements == 0;
588}
589
590
591
592template <typename ElementType, typename MemorySpaceType>
595{
596 return starting_element;
597}
598
599
600
601template <typename ElementType, typename MemorySpaceType>
604{
605 return starting_element + n_elements;
606}
607
608
609
610template <typename ElementType, typename MemorySpaceType>
613{
614 return starting_element;
615}
616
617
618
619template <typename ElementType, typename MemorySpaceType>
622{
623 return starting_element + n_elements;
624}
625
626
627
628template <typename ElementType, typename MemorySpaceType>
631{
632 AssertIndexRange(i, n_elements);
633
634 return *(starting_element + i);
635}
636
637
638
639#ifndef DOXYGEN
640namespace internal
641{
642 namespace ArrayViewHelper
643 {
649 template <class Iterator>
650 bool
651 is_contiguous(const Iterator &first, const Iterator &last)
652 {
653 const auto n = std::distance(first, last);
654 for (typename std::decay<decltype(n)>::type i = 0; i < n; ++i)
655 if (std::addressof(*(std::next(first, i))) !=
656 std::next(std::addressof(*first), i))
657 return false;
658 return true;
659 }
660
661
672 template <class T>
673 constexpr bool
674 is_contiguous(T *, T *)
675 {
676 return true;
677 }
678 } // namespace ArrayViewHelper
679} // namespace internal
680#endif
681
682
683
700template <typename Iterator, typename MemorySpaceType = MemorySpace::Host>
701ArrayView<typename std::remove_reference<
702 typename std::iterator_traits<Iterator>::reference>::type,
703 MemorySpaceType>
704make_array_view(const Iterator begin, const Iterator end)
705{
706 static_assert(
707 std::is_same<typename std::iterator_traits<Iterator>::iterator_category,
708 typename std::random_access_iterator_tag>::value
709#ifdef DEAL_II_HAVE_CXX20
710 ||
711 std::is_same<typename std::iterator_traits<Iterator>::iterator_category,
712 typename std::contiguous_iterator_tag>::value
713#endif
714 ,
715 "The provided iterator needs to be a random access iterator.");
716 Assert(begin <= end,
718 "The beginning of the array view needs to be before the end."));
719 Assert(internal::ArrayViewHelper::is_contiguous(begin, end),
720 ExcMessage("The provided range isn't contiguous in memory!"));
721 // the reference type, not the value type, knows the constness of the iterator
722 return ArrayView<typename std::remove_reference<
723 typename std::iterator_traits<Iterator>::reference>::type,
724 MemorySpaceType>(std::addressof(*begin), end - begin);
725}
726
727
728
738template <typename ElementType, typename MemorySpaceType = MemorySpace::Host>
740make_array_view(ElementType *const begin, ElementType *const end)
741{
742 Assert(begin <= end,
744 "The beginning of the array view needs to be before the end."));
745 return ArrayView<ElementType, MemorySpaceType>(begin, end - begin);
746}
747
748
749
760template <typename Number, typename MemorySpaceType>
763{
764 return make_array_view(array_view.cbegin(), array_view.cend());
765}
766
767
768
779template <typename Number, typename MemorySpaceType>
782{
783 return make_array_view(array_view.begin(), array_view.end());
784}
785
786
787
809template <int rank, int dim, typename Number>
812{
813 return make_array_view(tensor.begin_raw(), tensor.end_raw());
814}
815
816
817
839template <int rank, int dim, typename Number>
842{
843 return make_array_view(tensor.begin_raw(), tensor.end_raw());
844}
845
846
847
869template <int rank, int dim, typename Number>
872{
873 return make_array_view(tensor.begin_raw(), tensor.end_raw());
874}
875
876
877
900template <int rank, int dim, typename Number>
903{
904 return make_array_view(tensor.begin_raw(), tensor.end_raw());
905}
906
907
908
922template <typename ElementType, int N>
923inline ArrayView<ElementType> make_array_view(ElementType (&array)[N])
924{
925 return ArrayView<ElementType>(array, N);
926}
927
928
929
944template <typename ElementType>
947{
948 return ArrayView<ElementType>(vector.begin(), vector.size());
949}
950
951
952
967template <typename ElementType>
970{
971 return ArrayView<const ElementType>(vector.begin(), vector.size());
972}
973
974
975
990template <typename ElementType>
992make_array_view(std::vector<ElementType> &vector)
993{
994 return ArrayView<ElementType>(vector.data(), vector.size());
995}
996
997
998
1013template <typename ElementType>
1015make_array_view(const std::vector<ElementType> &vector)
1016{
1017 return ArrayView<const ElementType>(vector.data(), vector.size());
1018}
1019
1020
1021
1041template <typename ElementType>
1043make_array_view(std::vector<ElementType> &vector,
1044 const std::size_t starting_index,
1045 const std::size_t size_of_view)
1046{
1047 Assert(starting_index + size_of_view <= vector.size(),
1048 ExcMessage("The starting index and size of the view you want to "
1049 "create would lead to a view that extends beyond the end "
1050 "of the given vector."));
1051 return ArrayView<ElementType>(&vector[starting_index], size_of_view);
1052}
1053
1054
1055
1075template <typename ElementType>
1077make_array_view(const std::vector<ElementType> &vector,
1078 const std::size_t starting_index,
1079 const std::size_t size_of_view)
1080{
1081 Assert(starting_index + size_of_view <= vector.size(),
1082 ExcMessage("The starting index and size of the view you want to "
1083 "create would lead to a view that extends beyond the end "
1084 "of the given vector."));
1085 return ArrayView<const ElementType>(&vector[starting_index], size_of_view);
1086}
1087
1088
1089
1097template <typename ElementType>
1100{
1101 return ArrayView<ElementType>(vector.data(), vector.size());
1102}
1103
1104
1105
1113template <typename ElementType>
1116{
1117 return ArrayView<const ElementType>(vector.data(), vector.size());
1118}
1119
1120
1121
1129template <typename ElementType>
1132 const std::size_t starting_index,
1133 const std::size_t size_of_view)
1134{
1135 Assert(starting_index + size_of_view <= vector.size(),
1136 ExcMessage("The starting index and size of the view you want to "
1137 "create would lead to a view that extends beyond the end "
1138 "of the given vector."));
1139 return ArrayView<ElementType>(&vector[starting_index], size_of_view);
1140}
1141
1142
1143
1151template <typename ElementType>
1154 const std::size_t starting_index,
1155 const std::size_t size_of_view)
1156{
1157 Assert(starting_index + size_of_view <= vector.size(),
1158 ExcMessage("The starting index and size of the view you want to "
1159 "create would lead to a view that extends beyond the end "
1160 "of the given vector."));
1161 return ArrayView<const ElementType>(&vector[starting_index], size_of_view);
1162}
1163
1164
1165
1180template <typename ElementType, std::size_t N>
1182make_array_view(std::array<ElementType, N> &array)
1183{
1184 return ArrayView<ElementType>(array);
1185}
1186
1187
1188
1203template <typename ElementType, std::size_t N>
1205make_array_view(const std::array<ElementType, N> &array)
1206{
1207 return ArrayView<const ElementType>(array);
1208}
1209
1210
1211
1228template <typename ElementType>
1231 const typename Table<2, ElementType>::size_type row)
1232{
1233 AssertIndexRange(row, table.size()[0]);
1234 return ArrayView<ElementType>(&table[row][0], table.size()[1]);
1235}
1236
1237
1238
1255template <typename ElementType>
1258{
1259 return ArrayView<ElementType>(&table[0][0], table.n_elements());
1260}
1261
1262
1263
1280template <typename ElementType>
1283{
1284 return ArrayView<const ElementType>(&table[0][0], table.n_elements());
1285}
1286
1287
1305template <typename ElementType>
1308{
1309 return ArrayView<ElementType>(&matrix(0, 0), matrix.n_elements());
1310}
1311
1312
1313
1330template <typename ElementType>
1333{
1334 return ArrayView<const ElementType>(&matrix(0, 0), matrix.n_elements());
1335}
1336
1337
1338
1355template <typename ElementType>
1358 const typename Table<2, ElementType>::size_type row)
1359{
1360 AssertIndexRange(row, table.size()[0]);
1361 return ArrayView<const ElementType>(&table[row][0], table.size()[1]);
1362}
1363
1364
1365
1385template <typename ElementType>
1388 const typename Table<2, ElementType>::size_type row,
1389 const typename Table<2, ElementType>::size_type starting_column,
1390 const std::size_t size_of_view)
1391{
1392 AssertIndexRange(row, table.size()[0]);
1393 AssertIndexRange(starting_column, table.size()[1]);
1394 Assert(starting_column + size_of_view <= table.size()[1],
1395 ExcMessage("The starting index and size of the view you want to "
1396 "create would lead to a view that extends beyond the end "
1397 "of a column of the given table."));
1398 return ArrayView<ElementType>(&table[row][starting_column], size_of_view);
1399}
1400
1401
1402
1422template <typename ElementType>
1425 const typename Table<2, ElementType>::size_type row,
1426 const typename Table<2, ElementType>::size_type starting_column,
1427 const std::size_t size_of_view)
1428{
1429 AssertIndexRange(row, table.size()[0]);
1430 AssertIndexRange(starting_column, table.size()[1]);
1431 Assert(starting_column + size_of_view <= table.size()[1],
1432 ExcMessage("The starting index and size of the view you want to "
1433 "create would lead to a view that extends beyond the end "
1434 "of a column of the given table."));
1435 return ArrayView<const ElementType>(&table[row][starting_column],
1436 size_of_view);
1437}
1438
1439
1440
1441/*
1442 * Create a view that doesn't allow the container it points to to be modified.
1443 * This is useful if the object passed in is not `const` already and a function
1444 * requires a view to constant memory in its signature.
1445 *
1446 * This function returns an object of type `ArrayView<const T>` where `T` is the
1447 * element type of the container.
1448 *
1449 * @relatesalso ArrayView
1450 */
1451template <typename Container>
1452inline auto
1453make_const_array_view(const Container &container)
1454 -> decltype(make_array_view(container))
1455{
1456 return make_array_view(container);
1457}
1458
1459
1461
1462#endif
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:704
auto make_const_array_view(const Container &container) -> decltype(make_array_view(container))
pointer data()
size_type size() const
ArrayView< const ElementType > make_array_view(const Vector< ElementType > &vector)
Definition array_view.h:969
ArrayView(value_type &element)
Definition array_view.h:423
iterator begin() const
Definition array_view.h:594
ArrayView(const ArrayView< typename std::remove_cv< value_type >::type, MemorySpaceType > &view)
Definition array_view.h:431
ArrayView< Number, MemorySpaceType > make_array_view(ArrayView< Number, MemorySpaceType > &array_view)
Definition array_view.h:781
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:704
value_type * iterator
Definition array_view.h:97
ArrayView< Number > make_array_view(SymmetricTensor< rank, dim, Number > &tensor)
Definition array_view.h:902
value_type & operator[](const std::size_t i) const
Definition array_view.h:630
ArrayView< const ElementType > make_array_view(const LAPACKFullMatrix< ElementType > &matrix)
ArrayView< ElementType > make_array_view(std::array< ElementType, N > &array)
bool empty() const
Definition array_view.h:585
ArrayView< const Number > make_array_view(const Tensor< rank, dim, Number > &tensor)
Definition array_view.h:811
ArrayView< const Number > make_array_view(const SymmetricTensor< rank, dim, Number > &tensor)
Definition array_view.h:871
ArrayView< ElementType > make_array_view(LAPACKFullMatrix< ElementType > &matrix)
ArrayView< ElementType > make_array_view(ElementType(&array)[N])
Definition array_view.h:923
ArrayView< ElementType, MemorySpaceType > make_array_view(ElementType *const begin, ElementType *const end)
Definition array_view.h:740
bool operator!=(const ArrayView< typename std::remove_cv< value_type >::type, MemorySpaceType > &other_view) const
Definition array_view.h:565
const_iterator cend() const
Definition array_view.h:621
iterator end() const
Definition array_view.h:603
ArrayView< const ElementType > make_array_view(const std::vector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table)
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)
ArrayView(const std::array< typename std::remove_cv< value_type >::type, N > &vector)
Definition array_view.h:475
ArrayView< ElementType > make_array_view(std::vector< ElementType > &vector)
Definition array_view.h:992
ArrayView(std::vector< typename std::remove_cv< value_type >::type > &vector)
Definition array_view.h:465
bool operator==(const ArrayView< const value_type, MemorySpaceType > &other_view) const
Definition array_view.h:519
ArrayView< ElementType > make_array_view(std::vector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
bool operator!=(const ArrayView< const value_type, MemorySpaceType > &other_view) const
Definition array_view.h:542
const_iterator cbegin() const
Definition array_view.h:612
ArrayView(const std::vector< typename std::remove_cv< value_type >::type > &vector)
Definition array_view.h:441
ArrayView(value_type(&array)[N])
Definition array_view.h:500
ArrayView< Number > make_array_view(Tensor< rank, dim, Number > &tensor)
Definition array_view.h:841
value_type * data() const noexcept
Definition array_view.h:553
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)
void reinit(value_type *starting_element, const std::size_t n_elements)
Definition array_view.h:413
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table)
value_type * starting_element
Definition array_view.h:378
std::size_t size() const
Definition array_view.h:576
bool operator==(const ArrayView< typename std::remove_cv< value_type >::type, MemorySpaceType > &other_view) const
Definition array_view.h:530
ElementType value_type
Definition array_view.h:92
ArrayView(value_type *starting_element, const std::size_t n_elements)
Definition array_view.h:402
std::size_t n_elements
Definition array_view.h:383
ArrayView< const Number, MemorySpaceType > make_array_view(const ArrayView< Number, MemorySpaceType > &array_view)
Definition array_view.h:762
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
ArrayView< const ElementType > make_array_view(const AlignedVector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
ArrayView< const ElementType > make_array_view(const AlignedVector< ElementType > &vector)
const ElementType * const_iterator
Definition array_view.h:102
ArrayView< ElementType > make_array_view(Vector< ElementType > &vector)
Definition array_view.h:946
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
ArrayView< const ElementType > make_array_view(const std::vector< ElementType > &vector)
ArrayView< ElementType > make_array_view(AlignedVector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
ArrayView< const ElementType > make_array_view(const std::array< ElementType, N > &array)
ArrayView< ElementType > make_array_view(AlignedVector< ElementType > &vector)
ArrayView(std::array< typename std::remove_cv< value_type >::type, N > &vector)
Definition array_view.h:509
Number * begin_raw()
Number * end_raw()
Number * begin_raw()
Number * end_raw()
size_type size() const
iterator begin()
#define DEAL_II_DEPRECATED
Definition config.h:172
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
Point< 2 > first
Definition grid_out.cc:4615
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcMessage(std::string arg1)
STL namespace.
#define DEAL_II_HOST_DEVICE
Definition numbers.h:35