1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2019 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 /*---------------------------- tria-iterator.h ---------------------------*/
21
22
23 # include <deal.II/base/config.h>
24
25 # include <deal.II/base/exceptions.h>
26 # include <deal.II/base/point.h>
27
28 # include <deal.II/grid/tria_iterator_base.h>
29
30 # include <iterator>
31 # include <ostream>
32
33 DEAL_II_NAMESPACE_OPEN
34
35 // Forward declarations
36 # ifndef DOXYGEN
37 template <int dim, int spacedim>
38 class Triangulation;
39 template <int, int, int>
40 class TriaAccessorBase;
41
42 template <typename>
43 class TriaIterator;
44 template <typename>
45 class TriaActiveIterator;
46 # endif
47
48
49
50 // note: in non-debug mode, i.e. with optimizations, the file
51 // tria_iterator.templates.h is included at the end of this file.
52 // this includes a lot of templates and thus makes compilation
53 // slower, but at the same time allows for more aggressive
54 // inlining and thus faster code.
55
56
57 /**
58 * This class implements an iterator, analogous to those used in the standard
59 * library. It fulfills the requirements of a bidirectional iterator. See the
60 * C++ documentation for further details of iterator specification and usage.
61 *
62 *
63 * In addition to the standard interface, an iterator of this class provides a
64 * <tt>-@></tt> operator, i.e. you can write statements like
65 * @code
66 * cell->set_refine_flag ();
67 * @endcode
68 *
69 * Iterators are used whenever a loop over all lines, quads, cells etc. is to
70 * be performed. These loops can then be coded like this:
71 * @code
72 * cell_iterator cell = tria.begin();
73 * cell_iterator end = tria.end();
74 * for (; cell!=end; ++cell)
75 * if (cell->at_boundary())
76 * cell->set_refine_flag();
77 * @endcode
78 *
79 * Note the usage of <tt>++cell</tt> instead of <tt>cell++</tt> since this does
80 * not involve temporaries and copying. It is recommended to use a fixed value
81 * <tt>end</tt> inside the loop instead of <tt>tria.end()</tt>, since the
82 * creation and copying of these iterators is rather expensive compared to
83 * normal pointers.
84 *
85 * The objects pointed to are accessors, derived from TriaAccessorBase. Which
86 * kind of accessor is determined by the template argument <em>Accessor</em>.
87 * These accessors are not so much data structures as they are a collection of
88 * functions providing access to the data stored in Triangulation or
89 * DoFHandler objects. Using these accessors, the structure of these classes
90 * is hidden from the application program.
91 *
92 * <h3>Which iterator to use when</h3>
93 *
94 * @attention Application programs will rarely use TriaRawIterator, but rather
95 * one of the derived classes TriaIterator or TriaActiveIterator.
96 *
97 * <ul>
98 * <li> TriaRawIterator objects point to lines, cells, etc in the lists
99 * whether they are used or not (in the vectors, also <i>dead</i> objects are
100 * stored, since deletion in vectors is expensive and we also do not want to
101 * destroy the ordering induced by the numbering in the vectors). Therefore
102 * not all raw iterators point to valid objects.
103 *
104 * <li> The derived class TriaIterator selects the valid cells, that is, cells
105 * used somewhere in the triangulation hierarchy.
106 *
107 * <li> TriaActiveIterator objects which only loop over active cells.
108 * </ul>
109 *
110 * <h3>Purpose</h3>
111 *
112 * Iterators are not much slower than operating directly on the data
113 * structures, since they perform the loops that you had to handcode yourself
114 * anyway. Most iterator and accessor functions are inlined.
115 *
116 * The main functionality of iterators, resides in the <tt>++</tt> and
117 * <tt>\--</tt> operators. These move the iterator forward or backward just as
118 * if it were a pointer into an array. Here, this operation is not so easy,
119 * since it may include skipping some elements and the transition between the
120 * triangulation levels. This is completely hidden from the user, though you
121 * can still create an iterator pointing to an arbitrary element. Actually,
122 * the operation of moving iterators back and forth is not done in the
123 * iterator classes, but rather in the accessor classes. Since these are
124 * passed as template arguments, you can write your own versions here to add
125 * more functionality.
126 *
127 * Furthermore, the iterators described here satisfy the requirement of input
128 * and bidirectional iterators as stated by the C++ standard. It is therefore
129 * possible to use the functions from the algorithm section of the C++
130 * standard, e.g., <em>count_if</em> (see the documentation for Triangulation
131 * for an example) and several others.
132 *
133 * <h3>Implementation</h3>
134 *
135 * The iterator class itself does not have much functionality. It only becomes
136 * useful when assigned an Accessor (the second template parameter), which
137 * really does the access to data. An Accessor has to fulfill some
138 * requirements:
139 *
140 * <ul>
141 * <li> It must have two members named <tt>present_level</tt> and
142 * <tt>present_index</tt> storing the address of the element in the
143 * triangulation presently pointed to. These data have to be accessible by all
144 * triangulation iterators listed above.
145 *
146 * <li> It must have a constructor which takes a Triangulation* and two
147 * unsigned integers, denoting the initial level and index, as well as a data
148 * object depending on its type.
149 *
150 * <li> For the TriaIterator and the TriaActiveIterator class, it must have a
151 * member function <tt>bool used()</tt>, for the latter a member function
152 * <tt>bool active()</tt>.
153 *
154 * <li> It must have void operators <tt>++</tt> and <tt>\--</tt>.
155 *
156 * <li> It must declare a local alias <tt>AccessorData</tt> which states the
157 * data type the accessor expects to get passed as fourth constructor
158 * argument. By declaring a local data type, the respective iterator class may
159 * type-safely enforce that data type to be one of its own constructor
160 * argument types. If an accessor class does not need additional data, this
161 * type shall be <tt>void</tt>.
162 * </ul>
163 *
164 * Then the iterator is able to do what it is supposed to. All of the
165 * necessary functions are implemented in the <tt>Accessor</tt> base class,
166 * but you may write your own version (non-virtual, since we use templates) to
167 * add functionality.
168 *
169 * The accessors provided by the library consist of two groups, determined by
170 * whether they access the data of Triangulation objects or
171 * DoFHandler/hp::DoFHandler objects. They are derived from TriaAccessor and
172 * DoFAccessor, respectively. Each group also has specialized accessors for
173 * cells (as opposed to faces and lines) that offer more functionality such as
174 * accessing neighbors.
175 *
176 * @attention It seems impossible to preserve constness of a triangulation
177 * through iterator usage. Thus, if you declare pointers to a <tt>const</tt>
178 * triangulation object, you should be well aware that you might involuntarily
179 * alter the data stored in the triangulation.
180 *
181 * @note More information on valid and invalid iterators can be found in the
182 * documentation of TriaAccessorBase, where the iterator states are checked
183 * and implemented.
184 *
185 *
186 * <h3>Past-the-end iterators</h3>
187 *
188 * There is a representation of past-the-end-pointers, denoted by special
189 * values of the member variables @p present_level and @p present_index: If
190 * <tt>present_level>=0</tt> and <tt>present_index>=0</tt>, then the object is
191 * valid (there is no check whether the triangulation really has that many
192 * levels or that many cells on the present level when we investigate the
193 * state of an iterator; however, in many places where an iterator is
194 * dereferenced we make this check); if <tt>present_level==-1</tt> and
195 * <tt>present_index==-1</tt>, then the iterator points past the end; in all
196 * other cases, the iterator is considered invalid. You can check this by
197 * calling the <tt>state()</tt> function.
198 *
199 * An iterator is also invalid, if the pointer pointing to the Triangulation
200 * object is invalid or zero.
201 *
202 * Finally, an iterator is invalid, if the element pointed to by @p
203 * present_level and @p present_index is not used, i.e. if the @p used flag is
204 * set to false.
205 *
206 * The last two checks are not made in <tt>state()</tt> since both cases
207 * should only occur upon uninitialized construction through @p memcpy and the
208 * like (the parent triangulation can only be set upon construction). If an
209 * iterator is constructed empty through the empty constructor,
210 * <tt>present_level==-2</tt> and <tt>present_index==-2</tt>. Thus, the
211 * iterator is invalid anyway, regardless of the state of the triangulation
212 * pointer and the state of the element pointed to.
213 *
214 * Past-the-end iterators may also be used to compare an iterator with the
215 * <i>before-the-start</i> value, when running backwards. There is no
216 * distinction between the iterators pointing past the two ends of a vector.
217 *
218 * By defining only one value to be past-the-end and making all other values
219 * invalid provides a second track of security: if we should have forgotten a
220 * check in the library when an iterator is incremented or decremented, we
221 * automatically convert the iterator from the allowed state "past-the-end" to
222 * the disallowed state "invalid" which increases the chance that some time
223 * earlier than for past-the-end iterators an exception is raised.
224 *
225 * @ref Triangulation
226 * @ingroup grid
227 * @ingroup Iterators
228 */
229 template <typename Accessor>
230 class TriaRawIterator
231 {
232 public:
233 /**
234 * Declare the type of the Accessor for use in the outside world. This way
235 * other functions can use the Accessor's type without knowledge of how the
236 * exact implementation actually is.
237 */
238 using AccessorType = Accessor;
239
240 /**
241 * Default constructor. This constructor creates an iterator pointing
242 * to an invalid object. The iterator is consequently not usable.
243 */
244 TriaRawIterator();
245
246 /**
247 * Copy constructor.
248 */
249 TriaRawIterator(const TriaRawIterator &);
250
251 /**
252 * Construct an iterator from the given accessor; the given accessor needs
253 * not be of the same type as the accessor of this class is, but it needs to
254 * be convertible.
255 *
256 * Through this constructor, it is also possible to construct objects for
257 * derived iterators:
258 * @code
259 * DoFCellAccessor dof_accessor;
260 * Triangulation::active_cell_iterator cell = dof_accessor;
261 * @endcode
262 */
263 explicit TriaRawIterator(const Accessor &a);
264
265 /**
266 * Constructor. Assumes that the other accessor type is convertible to the
267 * current one.
268 */
269 template <typename OtherAccessor>
270 explicit TriaRawIterator(const OtherAccessor &a);
271
272 /**
273 * Proper constructor, initialized with the triangulation, the level and
274 * index of the object pointed to. The last parameter is of a type declared
275 * by the accessor class.
276 */
277 TriaRawIterator(
278 const Triangulation<Accessor::dimension, Accessor::space_dimension> *parent,
279 const int level,
280 const int index,
281 const typename AccessorType::AccessorData *local_data = nullptr);
282
283 /**
284 * This is a conversion operator (constructor) which takes another iterator
285 * type and copies the data; this conversion works, if there is a conversion
286 * path from the @p OtherAccessor class to the @p Accessor class of this
287 * object. One such path would be derived class to base class, which for
288 * example may be used to get a Triangulation::raw_cell_iterator from a
289 * DoFHandler::raw_cell_iterator, since the DoFAccessor class is derived
290 * from the TriaAccessorBase class.
291 */
292 template <typename OtherAccessor>
293 TriaRawIterator(const TriaRawIterator<OtherAccessor> &i);
294
295 /**
296 * Another conversion operator, where we use the pointers to the
297 * Triangulation from a TriaAccessorBase object, while the additional data
298 * is used according to the actual type of Accessor.
299 */
300 TriaRawIterator(
301 const TriaAccessorBase<Accessor::structure_dimension,
302 Accessor::dimension,
303 Accessor::space_dimension> &tria_accessor,
304 const typename Accessor::AccessorData * local_data);
305
306 /**
307 * Conversion constructor. Same as above with the difference that it
308 * converts from TriaIterator classes (not TriaRawIterator).
309 */
310 template <typename OtherAccessor>
311 TriaRawIterator(const TriaIterator<OtherAccessor> &i);
312
313 /**
314 * Conversion constructor. Same as above with the difference that it
315 * converts from TriaActiveIterator classes (not TriaRawIterator).
316 */
317 template <typename OtherAccessor>
318 TriaRawIterator(const TriaActiveIterator<OtherAccessor> &i);
319
320 /**
321 * @name Dereferencing
322 */
323 /*@{*/
324 /**
325 * Dereferencing operator, returns a reference to an accessor. Usage is thus
326 * like <tt>(*i).index ();</tt>
327 *
328 * This function has to be specialized explicitly for the different @p
329 * Pointees, to allow an
330 * <tt>iterator<1,TriangulationLevel<1>::LinesData></tt> to point to
331 * <tt>tria->lines.cells[index]</tt> while for one dimension higher it has
332 * to point to <tt>tria->quads.cells[index]</tt>.
333 *
334 * You must not dereference invalid or past the end iterators.
335 */
336 const Accessor &operator*() const;
337
338 /**
339 * Dereferencing operator, non-@p const version.
340 */
341 Accessor &operator*();
342
343 /**
344 * Dereferencing operator, returns a reference of the cell pointed to. Usage
345 * is thus like <tt>i->index ();</tt>
346 *
347 * There is a @p const and a non-@p const version.
348 */
349 const Accessor *operator->() const;
350
351 /**
352 * Dereferencing operator, non-@p const version.
353 */
354 Accessor *operator->();
355
356
357 /**
358 * In order be able to assign end-iterators for different accessors to each
359 * other, we need an access function which returns the accessor regardless
360 * of its state.
361 *
362 * @warning This function should not be used in application programs. It is
363 * only intended for limited purposes inside the library and it makes
364 * debugging much harder.
365 */
366 const Accessor &
367 access_any() const;
368
369 /*@}*/
370
371 /**
372 * Assignment operator.
373 */
374 TriaRawIterator &
375 operator=(const TriaRawIterator &);
376
377 /**
378 * Compare for equality.
379 */
380 template <typename OtherAccessor = Accessor>
381 typename std::enable_if<std::is_convertible<OtherAccessor, Accessor>::value,
382 bool>::type
383 operator==(const TriaRawIterator<OtherAccessor> &) const;
384
385 /**
386 * Compare for inequality.
387 */
388 bool
389 operator!=(const TriaRawIterator &) const;
390
391 /**
392 * Ordering relation for iterators.
393 *
394 * This relation attempts a total ordering of cells.
395 *
396 * The relation is defined as follows:
397 *
398 * For objects of <tt>Accessor::structure_dimension <
399 * Accessor::dimension</tt>, we simply compare the index of such an object.
400 * The ordering is lexicographic according to the following hierarchy (in
401 * the sense, that the next test is only applied if the previous was
402 * inconclusive):
403 *
404 * <ol>
405 * <li> The past-the-end iterator is always ordered last. Two past-the-end
406 * iterators rank the same, thus false is returned in that case.</li>
407 *
408 * <li> The level of the cell.</li>
409 * <li> The index of a cell inside the level.</li>
410 * </ol>
411 *
412 * @note The ordering is not consistent between different processor in a
413 * parallel::distributed::Triangulation because we rely on index(), which is
414 * likely not the same.
415 */
416 bool
417 operator<(const TriaRawIterator &) const;
418
419 /**
420 * Another comparison operator, implementing with the same ordering as
421 * #operator<.
422 */
423 bool
424 operator>(const TriaRawIterator &) const;
425
426 /**
427 * @name Advancement of iterators
428 */
429 /*@{*/
430 /**
431 * Prefix <tt>++</tt> operator: <tt>++iterator</tt>. This operator advances
432 * the iterator to the next element and returns a reference to
433 * <tt>*this</tt>.
434 */
435 TriaRawIterator &
436 operator++();
437
438 /**
439 * Postfix <tt>++</tt> operator: <tt>iterator++</tt>. This operator advances
440 * the iterator to the next element, but returns an iterator to the element
441 * previously pointed to.
442 *
443 * Since this operation involves a temporary and a copy operation and since
444 * an @p iterator is quite a large object for a pointer, use the prefix
445 * operator <tt>++iterator</tt> whenever possible, especially in the header
446 * of for loops (<tt>for (; iterator!=end; ++iterator)</tt>) since there you
447 * normally never need the returned value.
448 */
449 TriaRawIterator
450 operator++(int);
451
452 /**
453 * Prefix @p \-- operator: @p \--iterator. This operator moves the iterator to
454 * the previous element and returns a reference to <tt>*this</tt>.
455 */
456 TriaRawIterator &
457 operator--();
458
459 /**
460 * Postfix @p \-- operator: @p iterator\--. This operator moves the iterator
461 * to the previous element, but returns an iterator to the element
462 * previously pointed to.
463 *
464 * The same applies as for the postfix operator++: If possible, avoid it by
465 * using the prefix operator form to avoid the use of a temporary variable.
466 */
467 TriaRawIterator
468 operator--(int);
469 /*@}*/
470
471 /**
472 * Return the state of the iterator.
473 */
474 IteratorState::IteratorStates
475 state() const;
476
477 /**
478 * Print the iterator to a stream <code>out</code>. The format is
479 * <tt>level.index</tt>.
480 */
481 template <class StreamType>
482 void
483 print(StreamType &out) const;
484
485
486 /**
487 * Determine an estimate for the memory consumption (in bytes) of this
488 * object.
489 */
490 std::size_t
491 memory_consumption() const;
492
493 /**
494 * Mark the class as bidirectional iterator and declare some alias which
495 * are standard for iterators and are used by algorithms to enquire about the
496 * specifics of the iterators they work on.
497 */
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
504 /**
505 * @name Exceptions
506 */
507 /*@{*/
508 /**
509 * Exception for TriaObjects with level, i.e. cells.
510 */
511 DeclException1(ExcDereferenceInvalidCell,
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
523 /**
524 * Exception.
525 */
526 DeclException1(ExcDereferenceInvalidObject,
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
537 /**
538 * Exception
539 */
540 DeclException0(ExcAdvanceInvalidObject);
541 /**
542 * Exception
543 */
544 DeclException0(ExcInvalidComparison);
545
546 /*@}*/
547 protected:
548 /**
549 * Object holding the real data.
550 */
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
570 /**
571 * This specialization of TriaRawIterator provides access only to the
572 * <em>used</em> lines, quads, cells, etc.
573 *
574 * @ingroup grid
575 * @ingroup Iterators
576 */
577 template <typename Accessor>
578 class TriaIterator : public TriaRawIterator<Accessor>
579 {
580 public:
581 /**
582 * Default constructor. This constructor creates an iterator pointing
583 * to an invalid object. The iterator is consequently not usable.
584 */
585 TriaIterator();
586
587 /**
588 * Copy constructor.
589 */
590 TriaIterator(const TriaIterator<Accessor> &);
591
592 /**
593 * Conversion constructor from iterators potentially pointing to non-active
594 * objects (i.e., for objects for which we can't tell that the object is
595 * used just by looking at its type).
596 *
597 * @pre The argument passed to this constructor must either be
598 * (i) a past-the-end iterator; or (ii) it must point to
599 * a used object. All other cases will result in an exception.
600 */
601 TriaIterator(const TriaRawIterator<Accessor> &);
602
603 /**
604 * Constructor, initialized with the triangulation, the level and
605 * index of the object pointed to. The last parameter is of a type declared
606 * by the accessor class.
607 *
608 * @pre The argument passed to this constructor must either be
609 * (i) a past-the-end iterator; or (ii) it must point to
610 * a used object. All other cases will result in an exception.
611 */
612 TriaIterator(
613 const Triangulation<Accessor::dimension, Accessor::space_dimension> *parent,
614 const int level,
615 const int index,
616 const typename Accessor::AccessorData *local_data = nullptr);
617
618 /**
619 * Construct from an accessor of type OtherAccessor that is convertible to
620 * the type Accessor.
621 */
622 template <typename OtherAccessor>
623 explicit TriaIterator(const OtherAccessor &a);
624
625 /**
626 * This is a conversion operator (constructor) which takes another iterator
627 * type and copies the data; this conversion works, if there is a conversion
628 * path from the @p OtherAccessor class to the @p Accessor class of this
629 * object. One such path would be derived class to base class, which for
630 * example may be used to get a Triangulation::cell_iterator from a
631 * DoFHandler::cell_iterator, since the DoFAccessor class is derived from
632 * the TriaAccessorBase class.
633 */
634 template <typename OtherAccessor>
635 TriaIterator(const TriaIterator<OtherAccessor> &i);
636
637 /**
638 * Another conversion operator, where we use the pointers to the
639 * Triangulation from a TriaAccessorBase object, while the additional data
640 * is used according to the actual type of Accessor.
641 */
642 TriaIterator(const TriaAccessorBase<Accessor::structure_dimension,
643 Accessor::dimension,
644 Accessor::space_dimension> &tria_accessor,
645 const typename Accessor::AccessorData * local_data);
646
647 /**
648 * Similar conversion operator to the above one, but does a check whether
649 * the iterator points to a used element, which is necessary for raw
650 * iterators.
651 */
652 template <typename OtherAccessor>
653 TriaIterator(const TriaRawIterator<OtherAccessor> &i);
654
655 /**
656 * Similar conversion operator to the above one, but for conversion from
657 * active iterators.
658 */
659 template <typename OtherAccessor>
660 TriaIterator(const TriaActiveIterator<OtherAccessor> &i);
661
662 /**
663 * Assignment operator.
664 */
665 TriaIterator<Accessor> &
666 operator=(const TriaIterator<Accessor> &);
667
668 /**
669 * Cross assignment operator. This assignment is only valid if the given
670 * iterator points to a used element.
671 */
672 TriaIterator<Accessor> &
673 operator=(const TriaRawIterator<Accessor> &);
674
675 /**
676 * Assignment operator. Requires, that Accessor can be copied from
677 * OtherAccessor.
678 */
679 template <class OtherAccessor>
680 TriaIterator<Accessor> &
681 operator=(const TriaIterator<OtherAccessor> &);
682
683 /**
684 * Cross assignment operator. This assignment is only valid if the given
685 * iterator points to a used element. Requires, that Accessor can be copied
686 * from OtherAccessor.
687 */
688 template <class OtherAccessor>
689 TriaIterator<Accessor> &
690 operator=(const TriaRawIterator<OtherAccessor> &);
691
692 /**
693 * @name Advancement of iterators
694 */
695 /*@{*/
696 /**
697 * Prefix <tt>++</tt> operator: <tt>++i</tt>. This operator advances the
698 * iterator to the next used element and returns a reference to
699 * <tt>*this</tt>.
700 */
701 TriaIterator<Accessor> &
702 operator++();
703
704 /**
705 * Postfix <tt>++</tt> operator: <tt>i++</tt>. This operator advances the
706 * iterator to the next used element, but returns an iterator to the element
707 * previously pointed to. Since this involves a temporary and a copy
708 * operation and since an @p active_iterator is quite a large object for a
709 * pointer, use the prefix operator <tt>++i</tt> whenever possible,
710 * especially in the head of for loops (<tt>for (; i!=end; ++i)</tt>) since
711 * there you normally never need the returned value.
712 */
713 TriaIterator<Accessor>
714 operator++(int);
715
716 /**
717 * Prefix @p \-- operator: @p \--i. This operator advances the iterator to the
718 * previous used element and returns a reference to <tt>*this</tt>.
719 */
720 TriaIterator<Accessor> &
721 operator--();
722
723 /**
724 * Postfix @p \-- operator: @p i\--.
725 */
726 TriaIterator<Accessor>
727 operator--(int);
728 /*@}*/
729
730 /**
731 * Declare some aliases which are standard for iterators and are used
732 * by algorithms to enquire about the specifics of the iterators they
733 * work on.
734 */
735 using iterator_category =
736 typename TriaRawIterator<Accessor>::iterator_category;
737 using value_type = typename TriaRawIterator<Accessor>::value_type;
738 using pointer = typename TriaRawIterator<Accessor>::pointer;
739 using reference = typename TriaRawIterator<Accessor>::reference;
740 using difference_type = typename TriaRawIterator<Accessor>::difference_type;
741
742 /**
743 * Exception
744 */
745 DeclException0(ExcAssignmentOfUnusedObject);
746 };
747
748
749 /**
750 * This specialization of TriaIterator provides access only to the
751 * <em>active</em> lines, quads, cells, etc. An active cell is a cell which is
752 * not refined and thus a cell on which calculations on the finest level are
753 * done.
754 *
755 * @ingroup grid
756 * @ingroup Iterators
757 */
758 template <typename Accessor>
759 class TriaActiveIterator : public TriaIterator<Accessor>
760 {
761 public:
762 /**
763 * Default constructor. This constructor creates an iterator pointing
764 * to an invalid object. The iterator is consequently not usable.
765 */
766 TriaActiveIterator();
767
768 /**
769 * Copy constructor.
770 */
771 TriaActiveIterator(const TriaActiveIterator<Accessor> &);
772
773 /**
774 * Conversion constructor creating an active iterator from an iterators
775 * pointing to a potentially non-active object (or at least from which
776 * it is not apparent from the type alone that it is active).
777 *
778 * @pre The argument passed to this constructor must either be
779 * (i) a past-the-end iterator; or (ii) it must point to
780 * an active object. All other cases will result in an exception.
781 */
782 TriaActiveIterator(const TriaRawIterator<Accessor> &);
783
784 /**
785 * Conversion constructor creating an active iterator from an iterators
786 * pointing to a potentially non-active object (or at least from which
787 * it is not apparent from the type alone that it is active).
788 *
789 * @pre The argument passed to this constructor must either be
790 * (i) a past-the-end iterator; or (ii) it must point to
791 * an active object. All other cases will result in an exception.
792 */
793 TriaActiveIterator(const TriaIterator<Accessor> &);
794
795 /**
796 * Constructor, initialized with the triangulation, the level and
797 * index of the object pointed to. The last parameter is of a type declared
798 * by the accessor class used by the current iterator.
799 *
800 * @pre The argument passed to this constructor must either be
801 * (i) a past-the-end iterator; or (ii) it must point to
802 * an active object. All other cases will result in an exception.
803 */
804 TriaActiveIterator(
805 const Triangulation<Accessor::dimension, Accessor::space_dimension> *parent,
806 const int level,
807 const int index,
808 const typename Accessor::AccessorData *local_data = 0);
809
810 /**
811 * This is a conversion operator (constructor) which takes another iterator
812 * type and copies the data; this conversion works, if there is a conversion
813 * path from the @p OtherAccessor class to the @p Accessor class of this
814 * object. One such path would be derived class to base class, which for
815 * example may be used to get a Triangulation::active_cell_iterator from a
816 * DoFHandler::active_cell_iterator, since the DoFAccessor class is derived
817 * from the TriaAccessorBase class.
818 */
819 template <typename OtherAccessor>
820 TriaActiveIterator(const TriaActiveIterator<OtherAccessor> &i);
821
822 /**
823 * Another conversion operator, where we use the pointers to the
824 * Triangulation from a TriaAccessorBase object, while the additional data
825 * is used according to the actual type of Accessor.
826 */
827 TriaActiveIterator(
828 const TriaAccessorBase<Accessor::structure_dimension,
829 Accessor::dimension,
830 Accessor::space_dimension> &tria_accessor,
831 const typename Accessor::AccessorData * local_data);
832
833 /**
834 * Similar conversion operator to the above one, but does a check whether
835 * the iterator points to a used element, and is active, which is necessary
836 * for raw iterators. Since usual iterators are also raw iterators, this
837 * constructor works also for parameters of type
838 * <tt>TriaIterator<OtherAccessor></tt>.
839 *
840 * @pre The argument passed to this constructor must either be
841 * (i) a past-the-end iterator; or (ii) it must point to
842 * an active object. All other cases will result in an exception.
843 */
844 template <typename OtherAccessor>
845 TriaActiveIterator(const TriaRawIterator<OtherAccessor> &i);
846
847 /**
848 * Assignment operator.
849 */
850 TriaActiveIterator<Accessor> &
851 operator=(const TriaActiveIterator<Accessor> &);
852
853 /**
854 * Cross assignment operator. This assignment is only valid if the given
855 * iterator points to an active element.
856 */
857 TriaActiveIterator<Accessor> &
858 operator=(const TriaIterator<Accessor> &);
859
860 /**
861 * Cross assignment operator. This assignment is only valid if the given
862 * iterator points to an active element or past the end.
863 */
864 TriaActiveIterator<Accessor> &
865 operator=(const TriaRawIterator<Accessor> &);
866
867 /**
868 * Assignment operator. Requires, that Accessor can be copied from
869 * OtherAccessor.
870 */
871 template <class OtherAccessor>
872 TriaActiveIterator<Accessor> &
873 operator=(const TriaActiveIterator<OtherAccessor> &);
874
875 /**
876 * Cross assignment operator. This assignment is only valid if the given
877 * iterator points to an active element or past the end. Requires, that
878 * Accessor can be copied from OtherAccessor.
879 */
880 template <class OtherAccessor>
881 TriaActiveIterator<Accessor> &
882 operator=(const TriaRawIterator<OtherAccessor> &);
883
884 /**
885 * Cross assignment operator. This assignment is only valid if the given
886 * iterator points to an active element. Requires, that Accessor can be
887 * copied from OtherAccessor.
888 */
889 template <class OtherAccessor>
890 TriaActiveIterator<Accessor> &
891 operator=(const TriaIterator<OtherAccessor> &);
892
893 /**
894 * Prefix <tt>++</tt> operator: <tt>++i</tt>. This operator advances the
895 * iterator to the next active element and returns a reference to
896 * <tt>*this</tt>.
897 */
898 TriaActiveIterator<Accessor> &
899 operator++();
900
901 /**
902 * @name Advancement of iterators
903 */
904 /*@{*/
905 /**
906 * Postfix <tt>++</tt> operator: <tt>i++</tt>. This operator advances the
907 * iterator to the next active element, but returns an iterator to the
908 * element previously pointed to. Since this involves a temporary and a copy
909 * operation and since an @p active_iterator is quite a large object for a
910 * pointer, use the prefix operator <tt>++i</tt> whenever possible,
911 * especially in the head of for loops (<tt>for (; i!=end; ++i)</tt>) since
912 * there you normally never need the returned value.
913 */
914 TriaActiveIterator<Accessor>
915 operator++(int);
916
917 /**
918 * Prefix @p \-- operator: @p \--i. This operator advances the iterator to the
919 * previous active element and returns a reference to <tt>*this</tt>.
920 */
921 TriaActiveIterator<Accessor> &
922 operator--();
923
924 /**
925 * Postfix @p \-- operator: @p i\--.
926 */
927 TriaActiveIterator<Accessor>
928 operator--(int);
929 /*@}*/
930
931 /**
932 * Declare some alias which are standard for iterators and are used
933 * by algorithms to enquire about the specifics of the iterators they
934 * work on.
935 */
936 using iterator_category = typename TriaIterator<Accessor>::iterator_category;
937 using value_type = typename TriaIterator<Accessor>::value_type;
938 using pointer = typename TriaIterator<Accessor>::pointer;
939 using reference = typename TriaIterator<Accessor>::reference;
940 using difference_type = typename TriaIterator<Accessor>::difference_type;
941
942 /**
943 * Exception
944 */
945 DeclException0(ExcAssignmentOfInactiveObject);
946 };
947
948
949 /*----------------------- Inline functions -------------------*/
950
951
952 template <typename Accessor>
TriaRawIterator(const Accessor & a)953 inline TriaRawIterator<Accessor>::TriaRawIterator(const Accessor &a)
954 : accessor(a)
955 {}
956
957
958
959 template <typename Accessor>
960 template <typename OtherAccessor>
TriaRawIterator(const OtherAccessor & a)961 inline TriaRawIterator<Accessor>::TriaRawIterator(const OtherAccessor &a)
962 : accessor(a)
963 {}
964
965
966
967 template <typename Accessor>
968 template <typename OtherAccessor>
TriaRawIterator(const TriaRawIterator<OtherAccessor> & i)969 inline TriaRawIterator<Accessor>::TriaRawIterator(
970 const TriaRawIterator<OtherAccessor> &i)
971 : accessor(i.accessor)
972 {}
973
974
975
976 template <typename Accessor>
977 template <typename OtherAccessor>
TriaRawIterator(const TriaIterator<OtherAccessor> & i)978 inline TriaRawIterator<Accessor>::TriaRawIterator(
979 const TriaIterator<OtherAccessor> &i)
980 : accessor(i.accessor)
981 {}
982
983
984
985 template <typename Accessor>
986 template <typename OtherAccessor>
TriaRawIterator(const TriaActiveIterator<OtherAccessor> & i)987 inline TriaRawIterator<Accessor>::TriaRawIterator(
988 const TriaActiveIterator<OtherAccessor> &i)
989 : accessor(i.accessor)
990 {}
991
992
993
994 template <typename Accessor>
995 inline const Accessor &TriaRawIterator<Accessor>::operator*() const
996 {
997 Assert(Accessor::structure_dimension != Accessor::dimension ||
998 state() == IteratorState::valid,
999 ExcDereferenceInvalidCell(accessor));
1000 Assert(Accessor::structure_dimension == Accessor::dimension ||
1001 state() == IteratorState::valid,
1002 ExcDereferenceInvalidObject(accessor));
1003
1004 return accessor;
1005 }
1006
1007
1008
1009 template <typename Accessor>
1010 inline Accessor &TriaRawIterator<Accessor>::operator*()
1011 {
1012 Assert(Accessor::structure_dimension != Accessor::dimension ||
1013 state() == IteratorState::valid,
1014 ExcDereferenceInvalidCell(accessor));
1015 Assert(Accessor::structure_dimension == Accessor::dimension ||
1016 state() == IteratorState::valid,
1017 ExcDereferenceInvalidObject(accessor));
1018
1019 return accessor;
1020 }
1021
1022
1023
1024 template <typename Accessor>
1025 inline const Accessor &
access_any()1026 TriaRawIterator<Accessor>::access_any() const
1027 {
1028 return accessor;
1029 }
1030
1031
1032
1033 template <typename Accessor>
1034 inline const Accessor *TriaRawIterator<Accessor>::operator->() const
1035 {
1036 return &(this->operator*());
1037 }
1038
1039
1040
1041 template <typename Accessor>
1042 inline Accessor *TriaRawIterator<Accessor>::operator->()
1043 {
1044 return &(this->operator*());
1045 }
1046
1047
1048
1049 template <typename Accessor>
1050 inline IteratorState::IteratorStates
state()1051 TriaRawIterator<Accessor>::state() const
1052 {
1053 return accessor.state();
1054 }
1055
1056
1057
1058 template <typename Accessor>
1059 inline bool
1060 TriaRawIterator<Accessor>::
1061 operator<(const TriaRawIterator<Accessor> &other) const
1062 {
1063 Assert(state() != IteratorState::invalid,
1064 ExcDereferenceInvalidObject(accessor));
1065 Assert(other.state() != IteratorState::invalid,
1066 ExcDereferenceInvalidObject(other.accessor));
1067
1068 Assert(&accessor.get_triangulation() == &other.accessor.get_triangulation(),
1069 ExcInvalidComparison());
1070
1071 // Deal with iterators past end
1072 if (state() == IteratorState::past_the_end)
1073 return false;
1074 if (other.state() == IteratorState::past_the_end)
1075 return true;
1076
1077 return ((**this) < (*other));
1078 }
1079
1080
1081
1082 template <typename Accessor>
1083 inline bool
1084 TriaRawIterator<Accessor>::
1085 operator>(const TriaRawIterator<Accessor> &other) const
1086 {
1087 return (other < *this);
1088 }
1089
1090
1091
1092 template <typename Accessor>
1093 inline TriaRawIterator<Accessor> &
1094 TriaRawIterator<Accessor>::operator++()
1095 {
1096 Assert(state() == IteratorState::valid, ExcAdvanceInvalidObject());
1097
1098 ++accessor;
1099 return *this;
1100 }
1101
1102
1103
1104 template <typename Accessor>
1105 inline TriaRawIterator<Accessor> &
1106 TriaRawIterator<Accessor>::operator--()
1107 {
1108 Assert(state() == IteratorState::valid, ExcAdvanceInvalidObject());
1109
1110 --accessor;
1111 return *this;
1112 }
1113
1114
1115
1116 template <typename Accessor>
1117 template <class StreamType>
1118 inline void
print(StreamType & out)1119 TriaRawIterator<Accessor>::print(StreamType &out) const
1120 {
1121 if (Accessor::structure_dimension == Accessor::dimension)
1122 out << accessor.level() << "." << accessor.index();
1123 else
1124 out << accessor.index();
1125 }
1126
1127
1128
1129 template <typename Accessor>
1130 inline std::size_t
memory_consumption()1131 TriaRawIterator<Accessor>::memory_consumption() const
1132 {
1133 return sizeof(TriaRawIterator<Accessor>);
1134 }
1135
1136
1137
1138 template <typename Accessor>
1139 template <typename OtherAccessor>
TriaIterator(const TriaIterator<OtherAccessor> & i)1140 inline TriaIterator<Accessor>::TriaIterator(
1141 const TriaIterator<OtherAccessor> &i)
1142 : TriaRawIterator<Accessor>(i.accessor)
1143 {}
1144
1145
1146
1147 template <typename Accessor>
1148 template <typename OtherAccessor>
TriaIterator(const TriaActiveIterator<OtherAccessor> & i)1149 inline TriaIterator<Accessor>::TriaIterator(
1150 const TriaActiveIterator<OtherAccessor> &i)
1151 : TriaRawIterator<Accessor>(i.accessor)
1152 {}
1153
1154
1155
1156 template <typename Accessor>
1157 template <typename OtherAccessor>
TriaIterator(const TriaRawIterator<OtherAccessor> & i)1158 inline TriaIterator<Accessor>::TriaIterator(
1159 const TriaRawIterator<OtherAccessor> &i)
1160 : TriaRawIterator<Accessor>(i.accessor)
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)
1170 Assert(this->accessor.used(), ExcAssignmentOfUnusedObject());
1171 # endif
1172 }
1173
1174 template <typename Accessor>
1175 template <typename OtherAccessor>
TriaIterator(const OtherAccessor & a)1176 TriaIterator<Accessor>::TriaIterator(const OtherAccessor &a)
1177 : TriaRawIterator<Accessor>(a)
1178 {
1179 # ifdef DEBUG
1180 // do this like this, because:
1181 // if we write
1182 // "Assert (IteratorState::past_the_end || used)"
1183 // used() is called anyway, even if
1184 // state==IteratorState::past_the_end, and will then
1185 // throw the exception!
1186 if (this->state() != IteratorState::past_the_end)
1187 Assert(this->accessor.used(), ExcAssignmentOfUnusedObject());
1188 # endif
1189 }
1190
1191 template <typename Accessor>
1192 template <typename OtherAccessor>
TriaActiveIterator(const TriaActiveIterator<OtherAccessor> & i)1193 inline TriaActiveIterator<Accessor>::TriaActiveIterator(
1194 const TriaActiveIterator<OtherAccessor> &i)
1195 : TriaIterator<Accessor>(i.accessor)
1196 {}
1197
1198
1199
1200 template <typename Accessor>
1201 template <typename OtherAccessor>
TriaActiveIterator(const TriaRawIterator<OtherAccessor> & i)1202 inline TriaActiveIterator<Accessor>::TriaActiveIterator(
1203 const TriaRawIterator<OtherAccessor> &i)
1204 : TriaIterator<Accessor>(i)
1205 {
1206 # ifdef DEBUG
1207 // do this like this, because:
1208 // if we write
1209 // "Assert (IteratorState::past_the_end || !has_children())"
1210 // has_children() is called anyway, even if
1211 // state==IteratorState::past_the_end, and will then
1212 // throw the exception!
1213 if (this->state() != IteratorState::past_the_end)
1214 Assert(this->accessor.has_children() == false,
1215 ExcAssignmentOfInactiveObject());
1216 # endif
1217 }
1218
1219
1220
1221 /**
1222 * Print the address to which this iterator points to @p out. The address is
1223 * given by the pair <tt>(level,index)</tt>, where @p index is an index
1224 * relative to the level in which the object is that is pointed to.
1225 */
1226 template <typename Accessor>
1227 inline std::ostream &
1228 operator<<(std::ostream &out, const TriaRawIterator<Accessor> &i)
1229 {
1230 i.print(out);
1231 return out;
1232 }
1233
1234
1235
1236 /**
1237 * Print the address to which this iterator points to @p out. The address is
1238 * given by the pair <tt>(level,index)</tt>, where @p index is an index
1239 * relative to the level in which the object is that is pointed to.
1240 */
1241 template <typename Accessor>
1242 inline std::ostream &
1243 operator<<(std::ostream &out, const TriaIterator<Accessor> &i)
1244 {
1245 i.print(out);
1246 return out;
1247 }
1248
1249
1250
1251 /**
1252 * Print the address to which this iterator points to @p out. The address is
1253 * given by the pair <tt>(level,index)</tt>, where @p index is an index
1254 * relative to the level in which the object is that is pointed to.
1255 */
1256 template <typename Accessor>
1257 inline std::ostream &
1258 operator<<(std::ostream &out, const TriaActiveIterator<Accessor> &i)
1259 {
1260 i.print(out);
1261 return out;
1262 }
1263
1264
1265 DEAL_II_NAMESPACE_CLOSE
1266
1267
1268 // if in optimized mode: include more templates
1269 # ifndef DEBUG
1270 # include "tria_iterator.templates.h"
1271 # endif
1272
1273
1274 /*---------------------------- tria-iterator.h ---------------------------*/
1275 #endif
1276 /*---------------------------- tria-iterator.h ---------------------------*/
1277