Reference documentation for deal.II version 9.0.0
array_view.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2004 - 2018 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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_array_view_h
17 #define dealii_array_view_h
18 
19 #include <deal.II/base/config.h>
20 #include <deal.II/base/exceptions.h>
21 #include <deal.II/base/table.h>
22 #include <deal.II/lac/lapack_full_matrix.h>
23 #include <deal.II/base/tensor.h>
25 
26 #include <type_traits>
27 #include <vector>
28 
29 DEAL_II_NAMESPACE_OPEN
30 
31 
72 template <typename ElementType>
73 class ArrayView
74 {
75 public:
80  typedef ElementType value_type;
81 
85  typedef value_type *iterator;
86 
90  typedef const ElementType *const_iterator;
91 
112  const std::size_t n_elements);
113 
123  ArrayView (const ArrayView<typename std::remove_cv<value_type>::type> &view);
124 
139  ArrayView (const std::vector<typename std::remove_cv<value_type>::type> &vector);
140 
155  ArrayView (std::vector<typename std::remove_cv<value_type>::type> &vector);
156 
162  bool operator == (const ArrayView<const value_type> &other_view) const;
163 
169  bool operator ==
170  (const ArrayView<typename std::remove_cv<value_type>::type> &other_view) const;
171 
177  bool operator != (const ArrayView<const value_type> &other_view) const;
178 
184  bool operator !=
185  (const ArrayView<typename std::remove_cv<value_type>::type> &other_view) const;
186 
191  std::size_t size() const;
192 
197  value_type *data() const noexcept;
198 
202  iterator begin() const;
203 
207  iterator end() const;
208 
212  const_iterator cbegin() const;
213 
217  const_iterator cend() const;
218 
228  value_type &operator[] (const std::size_t i) const;
229 
230 private:
236 
240  const std::size_t n_elements;
241 
242  friend class ArrayView<const ElementType>;
243 };
244 
245 
246 
247 //---------------------------------------------------------------------------
248 
249 
250 
251 template <typename ElementType>
252 inline
254  const std::size_t n_elements)
255  :
258 {}
259 
260 
261 
262 template <typename ElementType>
263 inline
265 ArrayView(const ArrayView<typename std::remove_cv<value_type>::type> &view)
266  :
268  n_elements(view.n_elements)
269 {}
270 
271 
272 
273 template <typename ElementType>
274 inline
276 ArrayView (const std::vector<typename std::remove_cv<value_type>::type> &vector)
277  :
278  // use delegating constructor
279  ArrayView (vector.data(), vector.size())
280 {
281  // the following static_assert is not strictly necessary because,
282  // if we got a const std::vector reference argument but ElementType
283  // is not itself const, then the call to the forwarding constructor
284  // above will already have failed: vector.data() will have returned
285  // a const pointer, but we need a non-const pointer.
286  //
287  // nevertheless, leave the static_assert in since it provides a
288  // more descriptive error message that will simply come after the first
289  // error produced above
290  static_assert (std::is_const<value_type>::value == true,
291  "This constructor may only be called if the ArrayView "
292  "object has a const value_type. In other words, you can "
293  "only create an ArrayView to const values from a const "
294  "std::vector.");
295 }
296 
297 
298 
299 template <typename ElementType>
300 inline
302 ArrayView (std::vector<typename std::remove_cv<value_type>::type> &vector)
303  :
304  // use delegating constructor
305  ArrayView (vector.data(), vector.size())
306 {}
307 
308 
309 
310 template <typename ElementType>
311 inline
312 bool
314 {
315  return (other_view.data() == starting_element)
316  && (other_view.size() == n_elements);
317 }
318 
319 
320 
321 template <typename ElementType>
322 inline
323 bool
326 {
327  return (other_view.data() == starting_element)
328  && (other_view.size() == n_elements);
329 }
330 
331 
332 
333 template <typename ElementType>
334 inline
335 bool
337 {
338  return !(*this == other_view);
339 }
340 
341 
342 
343 template <typename ElementType>
344 inline
347 {
348  if (n_elements==0)
349  return nullptr;
350  else
351  return starting_element;
352 }
353 
354 
355 
356 template <typename ElementType>
357 inline
358 bool
361 {
362  return !(*this == other_view);
363 }
364 
365 
366 
367 template <typename ElementType>
368 inline
369 std::size_t
371 {
372  return n_elements;
373 }
374 
375 template <typename ElementType>
376 inline
379 {
380  return starting_element;
381 }
382 
383 
384 
385 template <typename ElementType>
386 inline
389 {
390  return starting_element + n_elements;
391 }
392 
393 
394 
395 template <typename ElementType>
396 inline
399 {
400  return starting_element;
401 }
402 
403 
404 
405 template <typename ElementType>
406 inline
409 {
410  return starting_element + n_elements;
411 }
412 
413 
414 
415 template <typename ElementType>
416 inline
418 ArrayView<ElementType>::operator[](const std::size_t i) const
419 {
420  Assert (i<n_elements, ExcIndexRange(i, 0, n_elements));
421 
422  return *(starting_element + i);
423 }
424 
425 
426 
427 #ifndef DOXYGEN
428 namespace internal
429 {
430  namespace ArrayViewHelper
431  {
437  template <class Iterator>
438  bool is_contiguous(const Iterator &first, const Iterator &last)
439  {
440  const auto n = std::distance(first, last);
441  for (typename std::decay<decltype(n)>::type i = 0; i < n; ++i)
442  if (std::addressof(*(std::next(first, i))) != std::next(std::addressof(*first), i))
443  return false;
444  return true;
445  }
446 
447 
458  template <class T>
459  constexpr
460  bool is_contiguous(T *,
461  T *)
462  {
463  return true;
464  }
465  }
466 }
467 #endif
468 
469 
470 
471 
488 template <typename Iterator>
490 make_array_view (const Iterator begin, const Iterator end)
491 {
492  static_assert(std::is_same<typename std::iterator_traits<Iterator>::iterator_category,
493  typename std::random_access_iterator_tag>::value,
494  "The provided iterator should be a random access iterator.");
495  Assert(begin <= end,
496  ExcMessage("The beginning of the array view should be before the end."));
497  Assert(internal::ArrayViewHelper::is_contiguous(begin, end),
498  ExcMessage("The provided range isn't contiguous in memory!"));
499  // the reference type, not the value type, knows the constness of the iterator
500  return ArrayView<typename std::remove_reference
501  <typename std::iterator_traits<Iterator>::reference>::type>
502  (std::addressof(*begin), end - begin);
503 }
504 
505 
506 
516 template <typename ElementType>
518 make_array_view (ElementType *const begin, ElementType *const end)
519 {
520  Assert(begin <= end,
521  ExcMessage("The beginning of the array view should be before the end."));
522  return ArrayView<ElementType>(begin, end - begin);
523 }
524 
525 
526 
537 template <typename Number>
538 inline
541 {
542  return make_array_view (array_view.cbegin(), array_view.cend());
543 }
544 
545 
546 
557 template <typename Number>
558 inline
561 {
562  return make_array_view (array_view.begin(), array_view.end());
563 }
564 
565 
566 
583 template <int rank, int dim, typename Number>
584 inline
587 {
588  return make_array_view (tensor.begin_raw(), tensor.end_raw());
589 }
590 
591 
592 
609 template <int rank, int dim, typename Number>
610 inline
613 {
614  return make_array_view (tensor.begin_raw(), tensor.end_raw());
615 }
616 
617 
618 
635 template <int rank, int dim, typename Number>
636 inline
639 {
640  return make_array_view (tensor.begin_raw(), tensor.end_raw());
641 }
642 
643 
644 
662 template <int rank, int dim, typename Number>
663 inline
666 {
667  return make_array_view (tensor.begin_raw(), tensor.end_raw());
668 }
669 
670 
671 
685 template <typename ElementType, int N>
686 inline
688 make_array_view (ElementType (&array)[N])
689 {
690  return ArrayView<ElementType> (array, N);
691 }
692 
693 
694 
709 template <typename ElementType>
710 inline
712 make_array_view (Vector<ElementType> &vector)
713 {
714  return ArrayView<ElementType> (vector.begin(), vector.size());
715 }
716 
717 
718 
733 template <typename ElementType>
734 inline
736 make_array_view (const Vector<ElementType> &vector)
737 {
738  return ArrayView<const ElementType> (vector.begin(), vector.size());
739 }
740 
741 
742 
757 template <typename ElementType>
758 inline
760 make_array_view (std::vector<ElementType> &vector)
761 {
762  return ArrayView<ElementType> (vector.data(), vector.size());
763 }
764 
765 
766 
781 template <typename ElementType>
782 inline
784 make_array_view (const std::vector<ElementType> &vector)
785 {
786  return ArrayView<const ElementType> (vector.data(), vector.size());
787 }
788 
789 
790 
810 template <typename ElementType>
811 inline
813 make_array_view (std::vector<ElementType> &vector,
814  const std::size_t starting_index,
815  const std::size_t size_of_view)
816 {
817  Assert (starting_index + size_of_view <= vector.size(),
818  ExcMessage ("The starting index and size of the view you want to "
819  "create would lead to a view that extends beyond the end "
820  "of the given vector."));
821  return ArrayView<ElementType> (&vector[starting_index], size_of_view);
822 }
823 
824 
825 
845 template <typename ElementType>
846 inline
848 make_array_view (const std::vector<ElementType> &vector,
849  const std::size_t starting_index,
850  const std::size_t size_of_view)
851 {
852  Assert (starting_index + size_of_view <= vector.size(),
853  ExcMessage ("The starting index and size of the view you want to "
854  "create would lead to a view that extends beyond the end "
855  "of the given vector."));
856  return ArrayView<const ElementType> (&vector[starting_index], size_of_view);
857 }
858 
859 
860 
877 template <typename ElementType>
878 inline
881  const typename Table<2,ElementType>::size_type row)
882 {
883  AssertIndexRange (row, table.size()[0]);
884  return ArrayView<ElementType> (&table[row][0], table.size()[1]);
885 }
886 
887 
888 
905 template <typename ElementType>
906 inline
909 {
910  return ArrayView<ElementType> (&table[0][0], table.n_elements());
911 }
912 
913 
914 
931 template <typename ElementType>
932 inline
935 {
936  return ArrayView<const ElementType> (&table[0][0], table.n_elements());
937 }
938 
939 
957 template <typename ElementType>
958 inline
961 {
962  return ArrayView<ElementType> (&matrix(0,0), matrix.n_elements());
963 }
964 
965 
966 
983 template <typename ElementType>
984 inline
987 {
988  return ArrayView<const ElementType> (&matrix(0,0), matrix.n_elements());
989 }
990 
991 
992 
1009 template <typename ElementType>
1010 inline
1013  const typename Table<2,ElementType>::size_type row)
1014 {
1015  AssertIndexRange (row, table.size()[0]);
1016  return ArrayView<const ElementType> (&table[row][0], table.size()[1]);
1017 }
1018 
1019 
1020 
1040 template <typename ElementType>
1041 inline
1044  const typename Table<2,ElementType>::size_type row,
1045  const typename Table<2,ElementType>::size_type starting_column,
1046  const std::size_t size_of_view)
1047 {
1048  AssertIndexRange (row, table.size()[0]);
1049  AssertIndexRange (starting_column, table.size()[1]);
1050  Assert (starting_column + size_of_view <= table.size()[1],
1051  ExcMessage ("The starting index and size of the view you want to "
1052  "create would lead to a view that extends beyond the end "
1053  "of a column of the given table."));
1054  return ArrayView<ElementType> (&table[row][starting_column], size_of_view);
1055 }
1056 
1057 
1058 
1078 template <typename ElementType>
1079 inline
1082  const typename Table<2,ElementType>::size_type row,
1083  const typename Table<2,ElementType>::size_type starting_column,
1084  const std::size_t size_of_view)
1085 {
1086  AssertIndexRange (row, table.size()[0]);
1087  AssertIndexRange (starting_column, table.size()[1]);
1088  Assert (starting_column + size_of_view <= table.size()[1],
1089  ExcMessage ("The starting index and size of the view you want to "
1090  "create would lead to a view that extends beyond the end "
1091  "of a column of the given table."));
1092  return ArrayView<const ElementType> (&table[row][starting_column], size_of_view);
1093 }
1094 
1095 
1096 
1097 DEAL_II_NAMESPACE_CLOSE
1098 
1099 #endif
ArrayView< ElementType > make_array_view(LAPACKFullMatrix< ElementType > &matrix)
Definition: array_view.h:960
ArrayView< const ElementType > make_array_view(const LAPACKFullMatrix< ElementType > &matrix)
Definition: array_view.h:986
ArrayView< const Number > make_array_view(const ArrayView< Number > &array_view)
Definition: array_view.h:540
iterator begin() const
Definition: array_view.h:378
ArrayView< ElementType > make_array_view(ElementType(&array)[N])
Definition: array_view.h:688
ArrayView< const Number > make_array_view(const Tensor< rank, dim, Number > &tensor)
Definition: array_view.h:586
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:813
const std::size_t n_elements
Definition: array_view.h:240
ElementType value_type
Definition: array_view.h:80
#define AssertIndexRange(index, range)
Definition: exceptions.h:1284
bool operator==(const ArrayView< const value_type > &other_view) const
Definition: array_view.h:313
STL namespace.
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
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:1081
const_iterator cend() const
Definition: array_view.h:408
ArrayView< Number > make_array_view(SymmetricTensor< rank, dim, Number > &tensor)
Definition: array_view.h:665
ArrayView< ElementType > make_array_view(Vector< ElementType > &vector)
Definition: array_view.h:712
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type > make_array_view(const Iterator begin, const Iterator end)
Definition: array_view.h:490
value_type & operator[](const std::size_t i) const
Definition: array_view.h:418
static ::ExceptionBase & ExcMessage(std::string arg1)
ArrayView< ElementType > make_array_view(ElementType *const begin, ElementType *const end)
Definition: array_view.h:518
Number * begin_raw()
#define Assert(cond, exc)
Definition: exceptions.h:1142
iterator end() const
Definition: array_view.h:388
Number * end_raw()
Definition: tensor.h:1127
Number * end_raw()
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
Definition: array_view.h:880
std::size_t size() const
Definition: array_view.h:370
value_type * iterator
Definition: array_view.h:85
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:848
ArrayView< const Number > make_array_view(const SymmetricTensor< rank, dim, Number > &tensor)
Definition: array_view.h:638
size_type size(const unsigned int i) const
ArrayView< const ElementType > make_array_view(const Vector< ElementType > &vector)
Definition: array_view.h:736
ArrayView< ElementType > make_array_view(std::vector< ElementType > &vector)
Definition: array_view.h:760
const_iterator cbegin() const
Definition: array_view.h:398
ArrayView(value_type *starting_element, const std::size_t n_elements)
Definition: array_view.h:253
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
Definition: array_view.h:1012
value_type * data() const noexcept
Definition: array_view.h:346
ArrayView< Number > make_array_view(ArrayView< Number > &array_view)
Definition: array_view.h:560
Number * begin_raw()
Definition: tensor.h:1107
const ElementType * const_iterator
Definition: array_view.h:90
Definition: table.h:34
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:1043
bool operator!=(const ArrayView< const value_type > &other_view) const
Definition: array_view.h:336
AlignedVector< T >::size_type size_type
Definition: table.h:413
ArrayView< Number > make_array_view(Tensor< rank, dim, Number > &tensor)
Definition: array_view.h:612
ArrayView< const ElementType > make_array_view(const std::vector< ElementType > &vector)
Definition: array_view.h:784
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table)
Definition: array_view.h:934
value_type *const starting_element
Definition: array_view.h:235
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table)
Definition: array_view.h:908