Reference documentation for deal.II version GIT 112f7bbc69 2023-05-28 21:25: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\}}\)
tria_iterator.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2022 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_tria_iterator_h
17 #define dealii_tria_iterator_h
18 
19 
20 #include <deal.II/base/config.h>
21 
23 #include <deal.II/base/point.h>
24 
26 
27 #include <iterator>
28 #include <ostream>
29 
31 
32 // Forward declarations
33 #ifndef DOXYGEN
34 template <int dim, int spacedim>
35 DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim<dim, spacedim>))
36 class Triangulation;
37 template <int, int, int>
38 class TriaAccessorBase;
39 
40 template <typename>
41 class TriaIterator;
42 template <typename>
43 class TriaActiveIterator;
44 #endif
45 
46 
47 
48 // note: in non-debug mode, i.e. with optimizations, the file
49 // tria_iterator.templates.h is included at the end of this file.
50 // this includes a lot of templates and thus makes compilation
51 // slower, but at the same time allows for more aggressive
52 // inlining and thus faster code.
53 
54 
226 template <typename Accessor>
228 {
229 public:
235  using AccessorType = Accessor;
236 
242 
247 
260  explicit TriaRawIterator(const Accessor &a);
261 
266  template <typename OtherAccessor>
267  explicit TriaRawIterator(const OtherAccessor &a);
268 
276  const int level,
277  const int index,
278  const typename AccessorType::AccessorData *local_data = nullptr);
279 
289  template <typename OtherAccessor>
291 
298  const TriaAccessorBase<Accessor::structure_dimension,
299  Accessor::dimension,
300  Accessor::space_dimension> &tria_accessor,
301  const typename Accessor::AccessorData * local_data);
302 
307  template <typename OtherAccessor>
309 
314  template <typename OtherAccessor>
316 
333  const Accessor &
334  operator*() const;
335 
339  Accessor &
340  operator*();
341 
348  const Accessor *
349  operator->() const;
350 
354  Accessor *
355  operator->();
356 
357 
367  const Accessor &
368  access_any() const;
369 
377 
381  template <typename OtherAccessor = Accessor>
382  std::enable_if_t<std::is_convertible<OtherAccessor, Accessor>::value, bool>
384 
388  bool
389  operator!=(const TriaRawIterator &) const;
390 
416  bool
417  operator<(const TriaRawIterator &) const;
418 
423  bool
424  operator>(const TriaRawIterator &) const;
425 
436  operator++();
437 
451 
457  operator--();
458 
475  state() const;
476 
481  template <class StreamType>
482  void
483  print(StreamType &out) const;
484 
485 
490  std::size_t
491  memory_consumption() const;
492 
498  using iterator_category = std::bidirectional_iterator_tag;
499  using value_type = Accessor;
500  using difference_type = int;
501  using pointer = Accessor *;
502  using reference = Accessor &;
503 
512  Accessor,
513  << "You tried to dereference a cell iterator for which this "
514  << "is not possible. More information on this iterator: "
515  << "level=" << arg1.level() << ", index=" << arg1.index()
516  << ", state="
517  << (arg1.state() == IteratorState::valid ?
518  "valid" :
519  (arg1.state() == IteratorState::past_the_end ?
520  "past_the_end" :
521  "invalid")));
522 
527  Accessor,
528  << "You tried to dereference an iterator for which this "
529  << "is not possible. More information on this iterator: "
530  << "index=" << arg1.index() << ", state="
531  << (arg1.state() == IteratorState::valid ?
532  "valid" :
533  (arg1.state() == IteratorState::past_the_end ?
534  "past_the_end" :
535  "invalid")));
536 
545 
547 protected:
551  Accessor accessor;
552 
553 
554  // Make all other iterator class templates friends of this class. This is
555  // necessary for the implementation of conversion constructors.
556  //
557  // In fact, we would not need them to be friends if they were for different
558  // dimensions, but the compiler dislikes giving a fixed dimension and
559  // variable accessor since then it says that would be a partial
560  // specialization.
561  template <typename SomeAccessor>
562  friend class TriaRawIterator;
563  template <typename SomeAccessor>
564  friend class TriaIterator;
565  template <typename SomeAccessor>
566  friend class TriaActiveIterator;
567 };
568 
569 
577 template <typename Accessor>
578 class TriaIterator : public TriaRawIterator<Accessor>
579 {
580 public:
586 
591 
602 
614  const int level,
615  const int index,
616  const typename Accessor::AccessorData *local_data = nullptr);
617 
622  template <typename OtherAccessor>
623  explicit TriaIterator(const OtherAccessor &a);
624 
634  template <typename OtherAccessor>
636 
642  TriaIterator(const TriaAccessorBase<Accessor::structure_dimension,
643  Accessor::dimension,
644  Accessor::space_dimension> &tria_accessor,
645  const typename Accessor::AccessorData * local_data);
646 
652  template <typename OtherAccessor>
654 
659  template <typename OtherAccessor>
661 
667 
674 
679  template <class OtherAccessor>
682 
688  template <class OtherAccessor>
691 
703 
715 
722 
741 
746 };
747 
748 
758 template <typename Accessor>
759 class TriaActiveIterator : public TriaIterator<Accessor>
760 {
761 public:
767 
772 
783 
794 
806  const int level,
807  const int index,
808  const typename Accessor::AccessorData *local_data = nullptr);
809 
819  template <typename OtherAccessor>
821 
828  const TriaAccessorBase<Accessor::structure_dimension,
829  Accessor::dimension,
830  Accessor::space_dimension> &tria_accessor,
831  const typename Accessor::AccessorData * local_data);
832 
844  template <typename OtherAccessor>
846 
852 
859 
866 
871  template <class OtherAccessor>
874 
880  template <class OtherAccessor>
883 
889  template <class OtherAccessor>
892 
900 
916 
923 
941 
946 };
947 
948 
949 /*----------------------- Inline functions -------------------*/
950 
951 
952 template <typename Accessor>
954  : accessor(a)
955 {}
956 
957 
958 
959 template <typename Accessor>
960 template <typename OtherAccessor>
961 inline TriaRawIterator<Accessor>::TriaRawIterator(const OtherAccessor &a)
962  : accessor(a)
963 {}
964 
965 
966 
967 template <typename Accessor>
968 template <typename OtherAccessor>
971  : accessor(i.accessor)
972 {}
973 
974 
975 
976 template <typename Accessor>
977 template <typename OtherAccessor>
980  : accessor(i.accessor)
981 {}
982 
983 
984 
985 template <typename Accessor>
986 template <typename OtherAccessor>
989  : accessor(i.accessor)
990 {}
991 
992 
993 
994 template <typename Accessor>
995 inline const Accessor &
997 {
998  Assert(Accessor::structure_dimension != Accessor::dimension ||
999  state() == IteratorState::valid,
1000  ExcDereferenceInvalidCell(accessor));
1001  Assert(Accessor::structure_dimension == Accessor::dimension ||
1002  state() == IteratorState::valid,
1003  ExcDereferenceInvalidObject(accessor));
1004 
1005  return accessor;
1006 }
1007 
1008 
1009 
1010 template <typename Accessor>
1011 inline Accessor &
1013 {
1014  Assert(Accessor::structure_dimension != Accessor::dimension ||
1015  state() == IteratorState::valid,
1016  ExcDereferenceInvalidCell(accessor));
1017  Assert(Accessor::structure_dimension == Accessor::dimension ||
1018  state() == IteratorState::valid,
1019  ExcDereferenceInvalidObject(accessor));
1020 
1021  return accessor;
1022 }
1023 
1024 
1025 
1026 template <typename Accessor>
1027 inline const Accessor &
1029 {
1030  return accessor;
1031 }
1032 
1033 
1034 
1035 template <typename Accessor>
1036 inline const Accessor *
1038 {
1039  return &(this->operator*());
1040 }
1041 
1042 
1043 
1044 template <typename Accessor>
1045 inline Accessor *
1047 {
1048  return &(this->operator*());
1049 }
1050 
1051 
1052 
1053 template <typename Accessor>
1056 {
1057  return accessor.state();
1058 }
1059 
1060 
1061 
1062 template <typename Accessor>
1063 inline bool
1065  const TriaRawIterator<Accessor> &other) const
1066 {
1067  Assert(state() != IteratorState::invalid,
1068  ExcDereferenceInvalidObject(accessor));
1069  Assert(other.state() != IteratorState::invalid,
1071 
1072  Assert(&accessor.get_triangulation() == &other.accessor.get_triangulation(),
1073  ExcInvalidComparison());
1074 
1075  // Deal with iterators past end
1076  if (state() == IteratorState::past_the_end)
1077  return false;
1078  if (other.state() == IteratorState::past_the_end)
1079  return true;
1080 
1081  return ((**this) < (*other));
1082 }
1083 
1084 
1085 
1086 template <typename Accessor>
1087 inline bool
1089  const TriaRawIterator<Accessor> &other) const
1090 {
1091  return (other < *this);
1092 }
1093 
1094 
1095 
1096 template <typename Accessor>
1099 {
1100  Assert(state() == IteratorState::valid, ExcAdvanceInvalidObject());
1101 
1102  ++accessor;
1103  return *this;
1104 }
1105 
1106 
1107 
1108 template <typename Accessor>
1111 {
1112  Assert(state() == IteratorState::valid, ExcAdvanceInvalidObject());
1113 
1114  --accessor;
1115  return *this;
1116 }
1117 
1118 
1119 
1120 template <typename Accessor>
1121 template <class StreamType>
1122 inline void
1123 TriaRawIterator<Accessor>::print(StreamType &out) const
1124 {
1125  if (Accessor::structure_dimension == Accessor::dimension)
1126  out << accessor.level() << '.' << accessor.index();
1127  else
1128  out << accessor.index();
1129 }
1130 
1131 
1132 
1133 template <typename Accessor>
1134 inline std::size_t
1136 {
1137  return sizeof(TriaRawIterator<Accessor>);
1138 }
1139 
1140 
1141 
1142 template <typename Accessor>
1143 template <typename OtherAccessor>
1145  const TriaIterator<OtherAccessor> &i)
1146  : TriaRawIterator<Accessor>(i.accessor)
1147 {}
1148 
1149 
1150 
1151 template <typename Accessor>
1152 template <typename OtherAccessor>
1155  : TriaRawIterator<Accessor>(i.accessor)
1156 {}
1157 
1158 
1159 
1160 template <typename Accessor>
1161 template <typename OtherAccessor>
1164  : TriaRawIterator<Accessor>(i.accessor)
1165 {
1166 #ifdef DEBUG
1167  // do this like this, because:
1168  // if we write
1169  // "Assert (IteratorState::past_the_end || used)"
1170  // used() is called anyway, even if
1171  // state==IteratorState::past_the_end, and will then
1172  // throw the exception!
1173  if (this->state() != IteratorState::past_the_end)
1174  Assert(this->accessor.used(), ExcAssignmentOfUnusedObject());
1175 #endif
1176 }
1177 
1178 template <typename Accessor>
1179 template <typename OtherAccessor>
1181  : TriaRawIterator<Accessor>(a)
1182 {
1183 #ifdef DEBUG
1184  // do this like this, because:
1185  // if we write
1186  // "Assert (IteratorState::past_the_end || used)"
1187  // used() is called anyway, even if
1188  // state==IteratorState::past_the_end, and will then
1189  // throw the exception!
1190  if (this->state() != IteratorState::past_the_end)
1191  Assert(this->accessor.used(), ExcAssignmentOfUnusedObject());
1192 #endif
1193 }
1194 
1195 template <typename Accessor>
1196 template <typename OtherAccessor>
1199  : TriaIterator<Accessor>(i.accessor)
1200 {}
1201 
1202 
1203 
1204 template <typename Accessor>
1205 template <typename OtherAccessor>
1208  : TriaIterator<Accessor>(i)
1209 {
1210 #ifdef DEBUG
1211  // do this like this, because:
1212  // if we write
1213  // "Assert (IteratorState::past_the_end || !has_children())"
1214  // has_children() is called anyway, even if
1215  // state==IteratorState::past_the_end, and will then
1216  // throw the exception!
1217  if (this->state() != IteratorState::past_the_end)
1218  Assert(this->accessor.has_children() == false,
1220 #endif
1221 }
1222 
1223 
1224 
1230 template <typename Accessor>
1231 inline std::ostream &
1232 operator<<(std::ostream &out, const TriaRawIterator<Accessor> &i)
1233 {
1234  i.print(out);
1235  return out;
1236 }
1237 
1238 
1239 
1245 template <typename Accessor>
1246 inline std::ostream &
1247 operator<<(std::ostream &out, const TriaIterator<Accessor> &i)
1248 {
1249  i.print(out);
1250  return out;
1251 }
1252 
1253 
1254 
1260 template <typename Accessor>
1261 inline std::ostream &
1262 operator<<(std::ostream &out, const TriaActiveIterator<Accessor> &i)
1263 {
1264  i.print(out);
1265  return out;
1266 }
1267 
1268 
1270 
1271 
1272 // if in optimized mode: include more templates
1273 #ifndef DEBUG
1274 # include "tria_iterator.templates.h"
1275 #endif
1276 
1277 #endif
OutputOperator< VectorType > & operator<<(OutputOperator< VectorType > &out, unsigned int step)
Definition: operator.h:165
Point< dim, typename ProductType< Number, typename EnableIfScalar< OtherNumber >::type >::type > operator*(const OtherNumber) const
TriaActiveIterator< Accessor > operator--(int)
TriaActiveIterator< Accessor > & operator=(const TriaActiveIterator< OtherAccessor > &)
TriaActiveIterator(const TriaActiveIterator< Accessor > &)
TriaActiveIterator< Accessor > & operator=(const TriaActiveIterator< Accessor > &)
TriaActiveIterator< Accessor > & operator=(const TriaIterator< Accessor > &)
TriaActiveIterator(const TriaRawIterator< Accessor > &)
TriaActiveIterator< Accessor > & operator=(const TriaRawIterator< OtherAccessor > &)
TriaActiveIterator< Accessor > & operator=(const TriaRawIterator< Accessor > &)
TriaActiveIterator(const TriaAccessorBase< Accessor::structure_dimension, Accessor::dimension, Accessor::space_dimension > &tria_accessor, const typename Accessor::AccessorData *local_data)
TriaActiveIterator< Accessor > operator++(int)
TriaActiveIterator(const Triangulation< Accessor::dimension, Accessor::space_dimension > *parent, const int level, const int index, const typename Accessor::AccessorData *local_data=nullptr)
TriaActiveIterator< Accessor > & operator++()
TriaActiveIterator< Accessor > & operator--()
TriaActiveIterator< Accessor > & operator=(const TriaIterator< OtherAccessor > &)
TriaActiveIterator(const TriaIterator< Accessor > &)
typename TriaRawIterator< Accessor >::pointer pointer
TriaIterator(const TriaIterator< Accessor > &)
TriaIterator< Accessor > & operator=(const TriaIterator< OtherAccessor > &)
typename TriaRawIterator< Accessor >::iterator_category iterator_category
typename TriaRawIterator< Accessor >::value_type value_type
TriaIterator< Accessor > & operator--()
typename TriaRawIterator< Accessor >::difference_type difference_type
TriaIterator< Accessor > & operator=(const TriaRawIterator< Accessor > &)
TriaIterator(const TriaAccessorBase< Accessor::structure_dimension, Accessor::dimension, Accessor::space_dimension > &tria_accessor, const typename Accessor::AccessorData *local_data)
typename TriaRawIterator< Accessor >::reference reference
TriaIterator< Accessor > operator++(int)
TriaIterator< Accessor > operator--(int)
TriaIterator< Accessor > & operator=(const TriaRawIterator< OtherAccessor > &)
TriaIterator(const Triangulation< Accessor::dimension, Accessor::space_dimension > *parent, const int level, const int index, const typename Accessor::AccessorData *local_data=nullptr)
TriaIterator< Accessor > & operator=(const TriaIterator< Accessor > &)
TriaIterator(const TriaRawIterator< Accessor > &)
TriaIterator< Accessor > & operator++()
const Accessor * operator->() const
bool operator>(const TriaRawIterator &) const
const Accessor & operator*() const
Accessor value_type
std::size_t memory_consumption() const
TriaRawIterator(const Triangulation< Accessor::dimension, Accessor::space_dimension > *parent, const int level, const int index, const typename AccessorType::AccessorData *local_data=nullptr)
TriaRawIterator(const TriaAccessorBase< Accessor::structure_dimension, Accessor::dimension, Accessor::space_dimension > &tria_accessor, const typename Accessor::AccessorData *local_data)
TriaRawIterator & operator=(const TriaRawIterator &)
bool operator<(const TriaRawIterator &) const
std::enable_if_t< std::is_convertible< OtherAccessor, Accessor >::value, bool > operator==(const TriaRawIterator< OtherAccessor > &) const
TriaRawIterator(const TriaRawIterator &)
Accessor * pointer
IteratorState::IteratorStates state() const
void print(StreamType &out) const
friend class TriaRawIterator
Accessor AccessorType
bool operator!=(const TriaRawIterator &) const
TriaRawIterator operator++(int)
std::bidirectional_iterator_tag iterator_category
TriaRawIterator & operator++()
const Accessor & access_any() const
Accessor & reference
TriaRawIterator & operator--()
TriaRawIterator operator--(int)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:474
#define DEAL_II_CXX20_REQUIRES(condition)
Definition: config.h:162
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:475
unsigned int level
Definition: grid_out.cc:4618
#define DeclException0(Exception0)
Definition: exceptions.h:465
#define Assert(cond, exc)
Definition: exceptions.h:1614
static ::ExceptionBase & ExcAdvanceInvalidObject()
static ::ExceptionBase & ExcAssignmentOfUnusedObject()
static ::ExceptionBase & ExcDereferenceInvalidObject(AccessorType arg1)
static ::ExceptionBase & ExcDereferenceInvalidCell(Accessor arg1)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:510
static ::ExceptionBase & ExcDereferenceInvalidObject(Accessor arg1)
static ::ExceptionBase & ExcAssignmentOfInactiveObject()
static ::ExceptionBase & ExcInvalidComparison()
@ past_the_end
Iterator reached end of container.
@ valid
Iterator points to a valid object.
@ invalid
Iterator is invalid, probably due to an error.