From b9b39d8e0ac0b9d848f09babb0948eb7a6cc35c7 Mon Sep 17 00:00:00 2001 From: wolf Date: Wed, 31 Mar 2004 17:37:24 +0000 Subject: [PATCH] Make things compile with gcc2.95. This patch is mostly gross, and I don t like it since we have to make quite a number of functions public, rather than making the respective accessing classes friends, but gcc 2.95 has so many bugs with templates and friends that there does not seem to be a way to achieve what we want otherwise... :-( git-svn-id: https://svn.dealii.org/trunk@8929 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/lac/include/lac/sparse_matrix.h | 160 +++++++++------------ deal.II/lac/include/lac/sparsity_pattern.h | 82 ++++++----- 2 files changed, 107 insertions(+), 135 deletions(-) diff --git a/deal.II/lac/include/lac/sparse_matrix.h b/deal.II/lac/include/lac/sparse_matrix.h index c5da4eab92..3818814cb2 100644 --- a/deal.II/lac/include/lac/sparse_matrix.h +++ b/deal.II/lac/include/lac/sparse_matrix.h @@ -33,8 +33,8 @@ namespace internals namespace SparseMatrixIterators { // forward declaration - template class Iterator; - + template + class Iterator; /** * General template for sparse matrix @@ -103,19 +103,21 @@ namespace internals * 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 - friend class internals::SparseMatrixIterators::Iterator; + MatrixType *matrix; }; @@ -132,18 +134,29 @@ namespace internals template class Accessor : 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. @@ -190,23 +203,8 @@ namespace internals * 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 - friend class internals::SparseMatrixIterators::Accessor; }; - + public: /** * Typedef for the type (including @@ -229,26 +227,26 @@ namespace internals */ 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 - 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 - friend class internals::SparseMatrixIterators::Iterator; - #ifdef DEAL_II_NESTED_CLASS_FRIEND_BUG friend class Reference; #endif @@ -367,12 +365,6 @@ namespace internals * accessor class. */ Accessor accessor; - - /** - * Make all other iterators friends. - */ - template - friend class internals::SparseMatrixIterators::Iterator; }; } @@ -1847,13 +1839,23 @@ namespace internals template inline number - Accessor::value() const + Accessor::value () const { return matrix->raw_entry(a_row, a_index); } + template + inline + typename Accessor::MatrixType & + Accessor::get_matrix () const + { + return *matrix; + } + + + template inline Accessor::Reference:: @@ -1963,6 +1965,16 @@ namespace internals + template + inline + typename Accessor::MatrixType & + Accessor::get_matrix () const + { + return *matrix; + } + + + template inline Iterator:: @@ -1990,26 +2002,7 @@ namespace internals Iterator & Iterator::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; } @@ -2019,27 +2012,8 @@ namespace internals Iterator Iterator::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; } @@ -2068,7 +2042,7 @@ namespace internals Iterator:: 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()); } diff --git a/deal.II/lac/include/lac/sparsity_pattern.h b/deal.II/lac/include/lac/sparsity_pattern.h index 9e654433fc..05794b7788 100644 --- a/deal.II/lac/include/lac/sparsity_pattern.h +++ b/deal.II/lac/include/lac/sparsity_pattern.h @@ -90,6 +90,18 @@ namespace internals * 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: /** @@ -1540,6 +1552,31 @@ namespace internals + 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, @@ -1554,26 +1591,7 @@ namespace internals 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; } @@ -1583,28 +1601,8 @@ namespace internals 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; } -- 2.39.5