namespace SparseMatrixIterators
{
// forward declaration
- template <typename number, bool Constness> class Iterator;
-
+ template <typename number, bool Constness>
+ class Iterator;
/**
* General template for sparse matrix
* Value of this matrix entry.
*/
number value() const;
-
- private:
+
/**
- * Pointer to the matrix we use.
+ * Return a reference to the matrix
+ * into which this accessor
+ * points. Note that in the present
+ * case, this is a constant
+ * reference.
*/
- const MatrixType *matrix;
+ MatrixType & get_matrix () const;
+ private:
/**
- * Make iterator class a
- * friend.
+ * Pointer to the matrix we use.
*/
- template <typename, bool>
- friend class internals::SparseMatrixIterators::Iterator;
+ MatrixType *matrix;
};
template <typename number>
class Accessor<number,false> : public SparsityPatternIterators::Accessor
{
+ private:
+ /**
+ * Reference class. This is what the
+ * accessor class returns when you
+ * call the value() function. The
+ * reference acts just as if it were
+ * a reference to the actual value of
+ * a matrix entry, i.e. you can read
+ * and write it, you can add and
+ * multiply to it, etc, but since the
+ * matrix does not give away the
+ * address of this matrix entry, we
+ * have to go through functions to do
+ * all this.
+ */
class Reference
{
- private:
+ public:
/**
- * Constructor. Made private so
- * as to only allow friend
- * classes access to it.
+ * Constructor.
*/
Reference (const Accessor *accessor);
- public:
-
/**
* Conversion operator to the
* data type of the matrix.
* presently point to.
*/
const Accessor *accessor;
-
- /**
- * Make the accessor class a
- * friend so as to allow it to
- * generate objects of this
- * type. To avoid trouble with
- * some compilers simply mark all
- * accessor classes as friends.
- *
- * We fully state the namespace
- * of the accessor class to work
- * around a bug in gcc2.95.
- */
- template <typename, bool>
- friend class internals::SparseMatrixIterators::Accessor;
};
-
+
public:
/**
* Typedef for the type (including
*/
Reference value() const;
- private:
/**
- * Pointer to the matrix we use.
+ * Return a reference to the matrix
+ * into which this accessor
+ * points. Note that in the present
+ * case, this is a non-constant
+ * reference.
*/
- MatrixType *matrix;
+ MatrixType & get_matrix () const;
+ private:
/**
- * Make all other accessor classes
- * friends.
+ * Pointer to the matrix we use.
*/
- template <typename, bool>
- friend class internals::SparseMatrixIterators::Accessor;
+ MatrixType *matrix;
/**
- * Make iterator class a
- * friend.
+ * Make the inner reference class a
+ * friend if the compiler has a bug
+ * and requires this.
*/
- template <typename, bool>
- friend class internals::SparseMatrixIterators::Iterator;
-
#ifdef DEAL_II_NESTED_CLASS_FRIEND_BUG
friend class Reference;
#endif
* accessor class.
*/
Accessor<number,Constness> accessor;
-
- /**
- * Make all other iterators friends.
- */
- template <typename, bool>
- friend class internals::SparseMatrixIterators::Iterator;
};
}
template <typename number>
inline
number
- Accessor<number, true>::value() const
+ Accessor<number, true>::value () const
{
return matrix->raw_entry(a_row, a_index);
}
+ template <typename number>
+ inline
+ typename Accessor<number, true>::MatrixType &
+ Accessor<number, true>::get_matrix () const
+ {
+ return *matrix;
+ }
+
+
+
template <typename number>
inline
Accessor<number, false>::Reference::
+ template <typename number>
+ inline
+ typename Accessor<number, false>::MatrixType &
+ Accessor<number, false>::get_matrix () const
+ {
+ return *matrix;
+ }
+
+
+
template <typename number, bool Constness>
inline
Iterator<number, Constness>::
Iterator<number, Constness> &
Iterator<number,Constness>::operator++ ()
{
- Assert (accessor.a_row < accessor.matrix->m(), ExcIteratorPastEnd());
-
- // move to next element
- ++accessor.a_index;
-
- // if at end of line: cycle until we
- // find a row with a nonzero number of
- // entries
- while (accessor.a_index >=
- accessor.matrix->get_sparsity_pattern().row_length(accessor.a_row))
- {
- accessor.a_index = 0;
- ++accessor.a_row;
-
- // if we happened to find the end
- // of the matrix, then stop here
- if (accessor.a_row == accessor.matrix->m())
- break;
- }
-
+ accessor.advance ();
return *this;
}
Iterator<number,Constness>
Iterator<number,Constness>::operator++ (int)
{
- Assert (accessor.a_row < accessor.matrix->m(), ExcIteratorPastEnd());
-
- const Iterator iter=*this;
-
- ++accessor.a_index;
-
- // if at end of line: cycle until we
- // find a row with a nonzero number of
- // entries
- while (accessor.a_index >=
- accessor.matrix->get_sparsity_pattern().row_length(accessor.a_row))
- {
- accessor.a_index = 0;
- ++accessor.a_row;
-
- // if we happened to find the end
- // of the matrix, then stop here
- if (accessor.a_row == accessor.matrix->m())
- break;
- }
-
+ const Iterator iter = *this;
+ accessor.advance ();
return iter;
}
Iterator<number,Constness>::
operator == (const Iterator& other) const
{
- return (accessor.matrix == other.accessor.matrix &&
+ return (&accessor.get_matrix() == &other.accessor.get_matrix() &&
accessor.row() == other.accessor.row() &&
accessor.index() == other.accessor.index());
}
* certain elements of the matrix.
*/
unsigned int column() const;
+
+ /**
+ * Move the accessor to the next
+ * nonzero entry in the matrix. This
+ * function should actually only be
+ * called from iterator classes, but
+ * due to various problems with
+ * friends and templates in gcc 2.95,
+ * we can't make it protected. Don't
+ * use it in your own programs.
+ */
+ void advance ();
protected:
/**
+ inline
+ void
+ Accessor::advance ()
+ {
+ Assert (a_row < sparsity_pattern->n_rows(), ExcIteratorPastEnd());
+
+ ++a_index;
+
+ // if at end of line: cycle until we
+ // find a row with a nonzero number of
+ // entries
+ while (a_index >= sparsity_pattern->row_length(a_row))
+ {
+ a_index = 0;
+ ++a_row;
+
+ // if we happened to find the end
+ // of the matrix, then stop here
+ if (a_row == sparsity_pattern->n_rows())
+ break;
+ }
+ }
+
+
+
inline
Iterator::Iterator (const SparsityPattern *sparsity_pattern,
const unsigned int r,
Iterator &
Iterator::operator++ ()
{
- Assert (accessor.a_row < accessor.sparsity_pattern->n_rows(),
- ExcIteratorPastEnd());
-
- ++accessor.a_index;
-
- // if at end of line: cycle until we
- // find a row with a nonzero number of
- // entries
- while (accessor.a_index >=
- accessor.sparsity_pattern->row_length(accessor.a_row))
- {
- accessor.a_index = 0;
- ++accessor.a_row;
-
- // if we happened to find the end
- // of the matrix, then stop here
- if (accessor.a_row == accessor.sparsity_pattern->n_rows())
- break;
- }
-
+ accessor.advance ();
return *this;
}
Iterator
Iterator::operator++ (int)
{
- Assert (accessor.a_row < accessor.sparsity_pattern->n_rows(),
- ExcIteratorPastEnd());
-
- const Iterator iter=*this;
-
- ++accessor.a_index;
-
- // if at end of line: cycle until we
- // find a row with a nonzero number of
- // entries
- while (accessor.a_index >=
- accessor.sparsity_pattern->row_length(accessor.a_row))
- {
- accessor.a_index = 0;
- ++accessor.a_row;
-
- // if we happened to find the end
- // of the matrix, then stop here
- if (accessor.a_row == accessor.sparsity_pattern->n_rows())
- break;
- }
-
+ const Iterator iter = *this;
+ accessor.advance ();
return iter;
}