1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 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_matrix_iterator_h
17 #define dealii_matrix_iterator_h
18
19
20 #include <deal.II/base/config.h>
21
22 #include <deal.II/base/exceptions.h>
23
24 DEAL_II_NAMESPACE_OPEN
25
26 /**
27 * Iterator for constant and non-constant matrices.
28 *
29 * This iterator is abstracted from the actual matrix type and can be used for
30 * any matrix having the required ACCESSOR type.
31 */
32 template <class ACCESSOR>
33 class MatrixIterator
34 {
35 public:
36 /**
37 * Declare type for container size.
38 */
39 using size_type = types::global_dof_index;
40
41 /**
42 * Typedef for the matrix type (including constness) we are to operate on.
43 */
44 using MatrixType = typename ACCESSOR::MatrixType;
45
46 /**
47 * Constructor. Create an iterator into the matrix <tt>matrix</tt> for the
48 * given <tt>row</tt> and the <tt>index</tt> within it.
49 */
50 MatrixIterator(MatrixType * matrix,
51 const size_type row = 0,
52 const size_type index = 0);
53
54 /**
55 * Copy from another matrix iterator. Mostly implemented to allow
56 * initialization of a constant iterator from a non constant, this function
57 * only requires that a conversion from the other iterator's accessor to
58 * this accessor object is possible.
59 */
60 template <class OtherAccessor>
61 MatrixIterator(const MatrixIterator<OtherAccessor> &other);
62
63 /**
64 * Prefix increment.
65 */
66 MatrixIterator &
67 operator++();
68
69 /**
70 * Postfix increment.
71 */
72 MatrixIterator
73 operator++(int);
74
75 /**
76 * Dereferencing operator.
77 */
78 const ACCESSOR &operator*() const;
79
80 /**
81 * Dereferencing operator.
82 */
83 const ACCESSOR *operator->() const;
84
85 /**
86 * Comparison. True, if both accessors are equal.
87 */
88 bool
89 operator==(const MatrixIterator &) const;
90
91 /**
92 * Inverse of <tt>==</tt>.
93 */
94 bool
95 operator!=(const MatrixIterator &) const;
96
97 /**
98 * Comparison operator. Result is true if either the first row number is
99 * smaller or if the row numbers are equal and the first index is smaller.
100 *
101 * This function is only valid if both iterators point into the same matrix.
102 */
103 bool
104 operator<(const MatrixIterator &) const;
105
106 /**
107 * Comparison operator. Works in the same way as above operator, just the
108 * other way round.
109 */
110 bool
111 operator>(const MatrixIterator &) const;
112
113 private:
114 /**
115 * Store an object of the accessor class.
116 */
117 ACCESSOR accessor;
118
119 // Allow other iterators access to private data.
120 template <class OtherAccessor>
121 friend class MatrixIterator;
122 };
123
124
125 //----------------------------------------------------------------------//
126
127 template <class ACCESSOR>
MatrixIterator(MatrixType * matrix,const size_type r,const size_type i)128 inline MatrixIterator<ACCESSOR>::MatrixIterator(MatrixType * matrix,
129 const size_type r,
130 const size_type i)
131 : accessor(matrix, r, i)
132 {}
133
134
135 template <class ACCESSOR>
136 template <class OtherAccessor>
MatrixIterator(const MatrixIterator<OtherAccessor> & other)137 inline MatrixIterator<ACCESSOR>::MatrixIterator(
138 const MatrixIterator<OtherAccessor> &other)
139 : accessor(other.accessor)
140 {}
141
142
143 template <class ACCESSOR>
144 inline MatrixIterator<ACCESSOR> &
145 MatrixIterator<ACCESSOR>::operator++()
146 {
147 accessor.advance();
148 return *this;
149 }
150
151
152 template <class ACCESSOR>
153 inline MatrixIterator<ACCESSOR>
154 MatrixIterator<ACCESSOR>::operator++(int)
155 {
156 const MatrixIterator iter = *this;
157 accessor.advance();
158 return iter;
159 }
160
161
162 template <class ACCESSOR>
163 inline const ACCESSOR &MatrixIterator<ACCESSOR>::operator*() const
164 {
165 return accessor;
166 }
167
168
169 template <class ACCESSOR>
170 inline const ACCESSOR *MatrixIterator<ACCESSOR>::operator->() const
171 {
172 return &accessor;
173 }
174
175
176 template <class ACCESSOR>
177 inline bool
178 MatrixIterator<ACCESSOR>::operator==(const MatrixIterator &other) const
179 {
180 return (accessor == other.accessor);
181 }
182
183
184 template <class ACCESSOR>
185 inline bool
186 MatrixIterator<ACCESSOR>::operator!=(const MatrixIterator &other) const
187 {
188 return !(*this == other);
189 }
190
191
192 template <class ACCESSOR>
193 inline bool
194 MatrixIterator<ACCESSOR>::operator<(const MatrixIterator &other) const
195 {
196 Assert(&accessor.get_matrix() == &other.accessor.get_matrix(),
197 ExcInternalError());
198
199 return (accessor < other.accessor);
200 }
201
202
203 template <class ACCESSOR>
204 inline bool
205 MatrixIterator<ACCESSOR>::operator>(const MatrixIterator &other) const
206 {
207 return (other < *this);
208 }
209
210 DEAL_II_NAMESPACE_CLOSE
211
212 #endif
213