Reference documentation for deal.II version GIT relicensing-233-g802318d791 2024-03-28 20:20: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\}}\)
Loading...
Searching...
No Matches
tria_iterator.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 1998 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_tria_iterator_h
16#define dealii_tria_iterator_h
17
18
19#include <deal.II/base/config.h>
20
22#include <deal.II/base/point.h>
23
25
26#include <iterator>
27#include <ostream>
28
30
31// Forward declarations
32#ifndef DOXYGEN
33template <int dim, int spacedim>
35class Triangulation;
36template <int, int, int>
38
39template <typename>
40class TriaIterator;
41template <typename>
43#endif
44
45
46
47// note: in non-debug mode, i.e. with optimizations, the file
48// tria_iterator.templates.h is included at the end of this file.
49// this includes a lot of templates and thus makes compilation
50// slower, but at the same time allows for more aggressive
51// inlining and thus faster code.
52
53
225template <typename Accessor>
227{
228public:
234 using AccessorType = Accessor;
235
241
246
259 explicit TriaRawIterator(const Accessor &a);
260
265 template <typename OtherAccessor>
266 explicit TriaRawIterator(const OtherAccessor &a);
267
275 const int level,
276 const int index,
277 const typename AccessorType::AccessorData *local_data = nullptr);
278
288 template <typename OtherAccessor>
290
297 const TriaAccessorBase<Accessor::structure_dimension,
298 Accessor::dimension,
299 Accessor::space_dimension> &tria_accessor,
300 const typename Accessor::AccessorData *local_data);
301
306 template <typename OtherAccessor>
308
313 template <typename OtherAccessor>
315
333 Accessor
334 operator*() const;
335
343 const Accessor *
344 operator->() const;
345
349 Accessor *
350 operator->();
351
352
362 const Accessor &
363 access_any() const;
364
372
376 template <typename OtherAccessor = Accessor>
377 std::enable_if_t<std::is_convertible_v<OtherAccessor, Accessor>, bool>
379
383 bool
385
411 bool
412 operator<(const TriaRawIterator &) const;
413
418 bool
419 operator>(const TriaRawIterator &) const;
420
431 operator++();
432
446
452 operator--();
453
470 state() const;
471
476 template <typename StreamType>
477 void
478 print(StreamType &out) const;
479
480
485 std::size_t
486 memory_consumption() const;
487
493 using iterator_category = std::bidirectional_iterator_tag;
494 using value_type = Accessor;
496 using pointer = Accessor *;
497 using reference = Accessor &;
498
507 Accessor,
508 << "You tried to dereference a cell iterator for which this "
509 << "is not possible. More information on this iterator: "
510 << "level=" << arg1.level() << ", index=" << arg1.index()
511 << ", state="
512 << (arg1.state() == IteratorState::valid ?
513 "valid" :
514 (arg1.state() == IteratorState::past_the_end ?
515 "past_the_end" :
516 "invalid")));
517
522 Accessor,
523 << "You tried to dereference an iterator for which this "
524 << "is not possible. More information on this iterator: "
525 << "index=" << arg1.index() << ", state="
526 << (arg1.state() == IteratorState::valid ?
527 "valid" :
528 (arg1.state() == IteratorState::past_the_end ?
529 "past_the_end" :
530 "invalid")));
531
540
542protected:
546 Accessor accessor;
547
548
549 // Make all other iterator class templates friends of this class. This is
550 // necessary for the implementation of conversion constructors.
551 //
552 // In fact, we would not need them to be friends if they were for different
553 // dimensions, but the compiler dislikes giving a fixed dimension and
554 // variable accessor since then it says that would be a partial
555 // specialization.
556 template <typename SomeAccessor>
557 friend class TriaRawIterator;
558 template <typename SomeAccessor>
559 friend class TriaIterator;
560 template <typename SomeAccessor>
561 friend class TriaActiveIterator;
562};
563
564
572template <typename Accessor>
573class TriaIterator : public TriaRawIterator<Accessor>
574{
575public:
581
586
597
609 const int level,
610 const int index,
611 const typename Accessor::AccessorData *local_data = nullptr);
612
617 template <typename OtherAccessor>
618 explicit TriaIterator(const OtherAccessor &a);
619
629 template <typename OtherAccessor>
631
637 TriaIterator(const TriaAccessorBase<Accessor::structure_dimension,
638 Accessor::dimension,
639 Accessor::space_dimension> &tria_accessor,
640 const typename Accessor::AccessorData *local_data);
641
647 template <typename OtherAccessor>
649
654 template <typename OtherAccessor>
656
662
669
674 template <class OtherAccessor>
677
683 template <class OtherAccessor>
686
698
710
717
736
741};
742
743
753template <typename Accessor>
754class TriaActiveIterator : public TriaIterator<Accessor>
755{
756public:
762
767
778
789
801 const int level,
802 const int index,
803 const typename Accessor::AccessorData *local_data = nullptr);
804
814 template <typename OtherAccessor>
816
823 const TriaAccessorBase<Accessor::structure_dimension,
824 Accessor::dimension,
825 Accessor::space_dimension> &tria_accessor,
826 const typename Accessor::AccessorData *local_data);
827
839 template <typename OtherAccessor>
841
847
854
861
866 template <class OtherAccessor>
869
875 template <class OtherAccessor>
878
884 template <class OtherAccessor>
887
895
911
918
936
941};
942
943
944/*----------------------- Inline functions -------------------*/
945
946
947template <typename Accessor>
949 : accessor(a)
950{}
951
952
953
954template <typename Accessor>
955template <typename OtherAccessor>
956inline TriaRawIterator<Accessor>::TriaRawIterator(const OtherAccessor &a)
957 : accessor(a)
958{}
959
960
961
962template <typename Accessor>
963template <typename OtherAccessor>
966 : accessor(i.accessor)
967{}
968
969
970
971template <typename Accessor>
972template <typename OtherAccessor>
975 : accessor(i.accessor)
976{}
977
978
979
980template <typename Accessor>
981template <typename OtherAccessor>
984 : accessor(i.accessor)
985{}
986
987
988
989template <typename Accessor>
990inline Accessor
992{
993 Assert(Accessor::structure_dimension != Accessor::dimension ||
994 state() == IteratorState::valid,
995 ExcDereferenceInvalidCell(accessor));
996 Assert(Accessor::structure_dimension == Accessor::dimension ||
997 state() == IteratorState::valid,
998 ExcDereferenceInvalidObject(accessor));
999
1000 return accessor;
1001}
1002
1003
1004
1005template <typename Accessor>
1006inline const Accessor &
1008{
1009 return accessor;
1010}
1011
1012
1013
1014template <typename Accessor>
1015inline const Accessor *
1017{
1018 return &accessor;
1019}
1020
1021
1022
1023template <typename Accessor>
1024inline Accessor *
1026{
1027 return &accessor;
1028}
1029
1030
1031
1032template <typename Accessor>
1035{
1036 return accessor.state();
1037}
1038
1039
1040
1041template <typename Accessor>
1042inline bool
1044 const TriaRawIterator<Accessor> &other) const
1045{
1046 Assert(state() != IteratorState::invalid,
1047 ExcDereferenceInvalidObject(accessor));
1049 ExcDereferenceInvalidObject(other.accessor));
1050
1051 Assert(&accessor.get_triangulation() == &other.accessor.get_triangulation(),
1052 ExcInvalidComparison());
1053
1054 // Deal with iterators past end
1055 if (state() == IteratorState::past_the_end)
1056 return false;
1057 if (other.state() == IteratorState::past_the_end)
1058 return true;
1059
1060 return ((**this) < (*other));
1061}
1062
1063
1064
1065template <typename Accessor>
1066inline bool
1068 const TriaRawIterator<Accessor> &other) const
1069{
1070 return (other < *this);
1071}
1072
1073
1074
1075template <typename Accessor>
1078{
1079 Assert(state() == IteratorState::valid, ExcAdvanceInvalidObject());
1080
1081 ++accessor;
1082 return *this;
1083}
1084
1085
1086
1087template <typename Accessor>
1090{
1091 Assert(state() == IteratorState::valid, ExcAdvanceInvalidObject());
1092
1093 --accessor;
1094 return *this;
1095}
1096
1097
1098
1099template <typename Accessor>
1100template <typename StreamType>
1101inline void
1103{
1104 if (Accessor::structure_dimension == Accessor::dimension)
1105 out << accessor.level() << '.' << accessor.index();
1106 else
1107 out << accessor.index();
1108}
1109
1110
1111
1112template <typename Accessor>
1113inline std::size_t
1118
1119
1120
1121template <typename Accessor>
1122template <typename OtherAccessor>
1125 : TriaRawIterator<Accessor>(i.accessor)
1126{}
1127
1128
1129
1130template <typename Accessor>
1131template <typename OtherAccessor>
1134 : TriaRawIterator<Accessor>(i.accessor)
1135{}
1136
1137
1138
1139template <typename Accessor>
1140template <typename OtherAccessor>
1143 : TriaRawIterator<Accessor>(i.accessor)
1144{
1145#ifdef DEBUG
1146 // do this like this, because:
1147 // if we write
1148 // "Assert (IteratorState::past_the_end || used)"
1149 // used() is called anyway, even if
1150 // state==IteratorState::past_the_end, and will then
1151 // throw the exception!
1152 if (this->state() != IteratorState::past_the_end)
1154#endif
1155}
1156
1157template <typename Accessor>
1158template <typename OtherAccessor>
1160 : TriaRawIterator<Accessor>(a)
1161{
1162#ifdef DEBUG
1163 // do this like this, because:
1164 // if we write
1165 // "Assert (IteratorState::past_the_end || used)"
1166 // used() is called anyway, even if
1167 // state==IteratorState::past_the_end, and will then
1168 // throw the exception!
1169 if (this->state() != IteratorState::past_the_end)
1171#endif
1172}
1173
1174template <typename Accessor>
1175template <typename OtherAccessor>
1180
1181
1182
1183template <typename Accessor>
1184template <typename OtherAccessor>
1187 : TriaIterator<Accessor>(i)
1188{
1189#ifdef DEBUG
1190 // do this like this, because:
1191 // if we write
1192 // "Assert (IteratorState::past_the_end || !has_children())"
1193 // has_children() is called anyway, even if
1194 // state==IteratorState::past_the_end, and will then
1195 // throw the exception!
1196 if (this->state() != IteratorState::past_the_end)
1197 Assert(this->accessor.has_children() == false,
1199#endif
1200}
1201
1202
1203
1209template <typename Accessor>
1210inline std::ostream &
1211operator<<(std::ostream &out, const TriaRawIterator<Accessor> &i)
1212{
1213 i.print(out);
1214 return out;
1215}
1216
1217
1218
1224template <typename Accessor>
1225inline std::ostream &
1226operator<<(std::ostream &out, const TriaIterator<Accessor> &i)
1227{
1228 i.print(out);
1229 return out;
1230}
1231
1232
1233
1239template <typename Accessor>
1240inline std::ostream &
1241operator<<(std::ostream &out, const TriaActiveIterator<Accessor> &i)
1242{
1243 i.print(out);
1244 return out;
1245}
1246
1247
1249
1250
1251// if in optimized mode: include more templates
1252#ifndef DEBUG
1253# include "tria_iterator.templates.h"
1254#endif
1255
1256#endif
TriaActiveIterator< Accessor > & operator=(const TriaIterator< OtherAccessor > &)
TriaActiveIterator(const TriaActiveIterator< Accessor > &)
typename TriaIterator< Accessor >::reference reference
TriaActiveIterator< Accessor > & operator=(const TriaRawIterator< Accessor > &)
TriaActiveIterator< Accessor > operator--(int)
TriaActiveIterator(const TriaRawIterator< Accessor > &)
TriaActiveIterator< Accessor > & operator=(const TriaActiveIterator< Accessor > &)
typename TriaIterator< Accessor >::difference_type difference_type
typename TriaIterator< Accessor >::pointer pointer
TriaActiveIterator< Accessor > & operator=(const TriaActiveIterator< OtherAccessor > &)
TriaActiveIterator< Accessor > & operator--()
TriaActiveIterator(const TriaAccessorBase< Accessor::structure_dimension, Accessor::dimension, Accessor::space_dimension > &tria_accessor, const typename Accessor::AccessorData *local_data)
TriaActiveIterator< Accessor > & operator=(const TriaIterator< Accessor > &)
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=(const TriaRawIterator< OtherAccessor > &)
typename TriaIterator< Accessor >::iterator_category iterator_category
TriaActiveIterator< Accessor > operator++(int)
typename TriaIterator< Accessor >::value_type value_type
TriaActiveIterator(const TriaIterator< Accessor > &)
typename TriaRawIterator< Accessor >::pointer pointer
TriaIterator(const TriaIterator< Accessor > &)
TriaIterator< Accessor > & operator++()
TriaIterator< Accessor > operator--(int)
typename TriaRawIterator< Accessor >::iterator_category iterator_category
TriaIterator< Accessor > & operator=(const TriaRawIterator< OtherAccessor > &)
typename TriaRawIterator< Accessor >::value_type value_type
TriaIterator< Accessor > operator++(int)
TriaIterator< Accessor > & operator=(const TriaIterator< Accessor > &)
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--()
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< OtherAccessor > &)
TriaIterator(const TriaRawIterator< Accessor > &)
const Accessor * operator->() const
TriaRawIterator & operator=(const TriaRawIterator &)
bool operator>(const TriaRawIterator &) const
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)
bool operator<(const TriaRawIterator &) const
TriaRawIterator(const TriaRawIterator &)
Accessor * pointer
IteratorState::IteratorStates state() const
Accessor operator*() const
std::enable_if_t< std::is_convertible_v< OtherAccessor, Accessor >, bool > operator==(const TriaRawIterator< OtherAccessor > &) 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:502
#define DEAL_II_CXX20_REQUIRES(condition)
Definition config.h:177
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:503
unsigned int level
Definition grid_out.cc:4616
static ::ExceptionBase & ExcAssignmentOfUnusedObject()
#define DeclException0(Exception0)
Definition exceptions.h:471
static ::ExceptionBase & ExcAssignmentOfInactiveObject()
#define Assert(cond, exc)
static ::ExceptionBase & ExcAdvanceInvalidObject()
static ::ExceptionBase & ExcInvalidComparison()
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:516
static ::ExceptionBase & ExcDereferenceInvalidObject(Accessor arg1)
static ::ExceptionBase & ExcDereferenceInvalidCell(Accessor arg1)
@ past_the_end
Iterator reached end of container.
@ valid
Iterator points to a valid object.
@ invalid
Iterator is invalid, probably due to an error.
std::ostream & operator<<(std::ostream &out, const TriaRawIterator< Accessor > &i)