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