Chris@49: // Copyright (C) 2011-2012 Ryan Curtin Chris@49: // Copyright (C) 2011 Matthew Amidon Chris@49: // Copyright (C) 2012 Conrad Sanderson Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: //! \addtogroup SpMat Chris@49: //! @{ Chris@49: Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: // SpMat::iterator_base implementation // Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: Chris@49: template Chris@49: inline Chris@49: SpMat::iterator_base::iterator_base(const SpMat& in_M) Chris@49: : M(in_M) Chris@49: , internal_col(0) Chris@49: , internal_pos(0) Chris@49: { Chris@49: // Technically this iterator is invalid (it may not point to a real element) Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpMat::iterator_base::iterator_base(const SpMat& in_M, const uword in_col, const uword in_pos) Chris@49: : M(in_M) Chris@49: , internal_col(in_col) Chris@49: , internal_pos(in_pos) Chris@49: { Chris@49: // Nothing to do. Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: eT Chris@49: SpMat::iterator_base::operator*() const Chris@49: { Chris@49: return M.values[internal_pos]; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: // SpMat::const_iterator implementation // Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: Chris@49: template Chris@49: inline Chris@49: SpMat::const_iterator::const_iterator(const SpMat& in_M, uword initial_pos) Chris@49: : iterator_base(in_M, 0, initial_pos) Chris@49: { Chris@49: // Corner case for empty matrices. Chris@49: if(in_M.n_nonzero == 0) Chris@49: { Chris@49: iterator_base::internal_col = in_M.n_cols; Chris@49: return; Chris@49: } Chris@49: Chris@49: // Determine which column we should be in. Chris@49: while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos) Chris@49: { Chris@49: iterator_base::internal_col++; Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpMat::const_iterator::const_iterator(const SpMat& in_M, uword in_row, uword in_col) Chris@49: : iterator_base(in_M, in_col, 0) Chris@49: { Chris@49: // So we have a position we want to be right after. Skip to the column. Chris@49: iterator_base::internal_pos = iterator_base::M.col_ptrs[iterator_base::internal_col]; Chris@49: Chris@49: // Now we have to make sure that is the right column. Chris@49: while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos) Chris@49: { Chris@49: iterator_base::internal_col++; Chris@49: } Chris@49: Chris@49: // Now we have to get to the right row. Chris@49: while((iterator_base::M.row_indices[iterator_base::internal_pos] < in_row) && (iterator_base::internal_col == in_col)) Chris@49: { Chris@49: ++(*this); // Increment iterator. Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpMat::const_iterator::const_iterator(const SpMat& in_M, const uword /* in_row */, const uword in_col, const uword in_pos) Chris@49: : iterator_base(in_M, in_col, in_pos) Chris@49: { Chris@49: // Nothing to do. Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpMat::const_iterator::const_iterator(const typename SpMat::const_iterator& other) Chris@49: : iterator_base(other.M, other.internal_col, other.internal_pos) Chris@49: { Chris@49: // Nothing to do. Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_iterator& Chris@49: SpMat::const_iterator::operator++() Chris@49: { Chris@49: ++iterator_base::internal_pos; Chris@49: Chris@49: if (iterator_base::internal_pos == iterator_base::M.n_nonzero) Chris@49: { Chris@49: iterator_base::internal_col = iterator_base::M.n_cols; Chris@49: return *this; Chris@49: } Chris@49: Chris@49: // Check to see if we moved a column. Chris@49: while (iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos) Chris@49: { Chris@49: ++iterator_base::internal_col; Chris@49: } Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_iterator Chris@49: SpMat::const_iterator::operator++(int) Chris@49: { Chris@49: typename SpMat::const_iterator tmp(*this); Chris@49: Chris@49: ++(*this); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_iterator& Chris@49: SpMat::const_iterator::operator--() Chris@49: { Chris@49: //iterator_base::M.print("M"); Chris@49: Chris@49: // printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, iterator_base::internal_col, iterator_base::row()); Chris@49: Chris@49: --iterator_base::internal_pos; Chris@49: Chris@49: // printf("now pos %d\n", iterator_base::internal_pos); Chris@49: Chris@49: // First, see if we moved back a column. Chris@49: while (iterator_base::internal_pos < iterator_base::M.col_ptrs[iterator_base::internal_col]) Chris@49: { Chris@49: // printf("colptr %d (col %d)\n", iterator_base::M.col_ptrs[iterator_base::internal_col], iterator_base::internal_col); Chris@49: Chris@49: --iterator_base::internal_col; Chris@49: } Chris@49: Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_iterator Chris@49: SpMat::const_iterator::operator--(int) Chris@49: { Chris@49: typename SpMat::const_iterator tmp(*this); Chris@49: Chris@49: --(*this); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator==(const const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator!=(const const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator==(const typename SpSubview::const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator!=(const typename SpSubview::const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator==(const const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator!=(const const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator==(const typename SpSubview::const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_iterator::operator!=(const typename SpSubview::const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: // SpMat::iterator implementation // Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: SpValProxy > Chris@49: SpMat::iterator::operator*() Chris@49: { Chris@49: return SpValProxy >( Chris@49: iterator_base::M.row_indices[iterator_base::internal_pos], Chris@49: iterator_base::internal_col, Chris@49: access::rw(iterator_base::M), Chris@49: &access::rw(iterator_base::M.values[iterator_base::internal_pos])); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::iterator& Chris@49: SpMat::iterator::operator++() Chris@49: { Chris@49: const_iterator::operator++(); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::iterator Chris@49: SpMat::iterator::operator++(int) Chris@49: { Chris@49: typename SpMat::iterator tmp(*this); Chris@49: Chris@49: const_iterator::operator++(); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::iterator& Chris@49: SpMat::iterator::operator--() Chris@49: { Chris@49: const_iterator::operator--(); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::iterator Chris@49: SpMat::iterator::operator--(int) Chris@49: { Chris@49: typename SpMat::iterator tmp(*this); Chris@49: Chris@49: const_iterator::operator--(); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: // SpMat::const_row_iterator implementation // Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: Chris@49: /** Chris@49: * Initialize the const_row_iterator. Chris@49: */ Chris@49: template Chris@49: inline Chris@49: SpMat::const_row_iterator::const_row_iterator(const SpMat& in_M, uword initial_pos) Chris@49: : iterator_base(in_M, 0, initial_pos) Chris@49: , internal_row(0) Chris@49: , actual_pos(0) Chris@49: { Chris@49: // Corner case for empty matrix. Chris@49: if(in_M.n_nonzero == 0) Chris@49: { Chris@49: iterator_base::internal_col = 0; Chris@49: internal_row = in_M.n_rows; Chris@49: return; Chris@49: } Chris@49: Chris@49: // We don't count zeroes in our position count, so we have to find the nonzero Chris@49: // value corresponding to the given initial position. We assume initial_pos Chris@49: // is valid. Chris@49: Chris@49: // This is irritating because we don't know where the elements are in each Chris@49: // row. What we will do is loop across all columns looking for elements in Chris@49: // row 0 (and add to our sum), then in row 1, and so forth, until we get to Chris@49: // the desired position. Chris@49: uword cur_pos = -1; Chris@49: uword cur_row = 0; Chris@49: uword cur_col = 0; Chris@49: Chris@49: while(true) // This loop is terminated from the inside. Chris@49: { Chris@49: // Is there anything in the column we are looking at? Chris@49: for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++) Chris@49: { Chris@49: // There is something in this column. Is it in the row we are looking at? Chris@49: const uword row_index = iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind]; Chris@49: if (row_index == cur_row) Chris@49: { Chris@49: // Yes, it is what we are looking for. Increment our current position. Chris@49: if (++cur_pos == iterator_base::internal_pos) Chris@49: { Chris@49: actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; Chris@49: internal_row = cur_row; Chris@49: iterator_base::internal_col = cur_col; Chris@49: Chris@49: return; Chris@49: } Chris@49: Chris@49: // We are done with this column. Break to the column incrementing code (directly below). Chris@49: break; Chris@49: } Chris@49: else if(row_index > cur_row) Chris@49: { Chris@49: break; // Can't be in this column. Chris@49: } Chris@49: } Chris@49: Chris@49: cur_col++; // Done with the column. Move on. Chris@49: if (cur_col == iterator_base::M.n_cols) Chris@49: { Chris@49: // We are out of columns. Loop back to the beginning and look on the Chris@49: // next row. Chris@49: cur_col = 0; Chris@49: cur_row++; Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpMat::const_row_iterator::const_row_iterator(const SpMat& in_M, uword in_row, uword in_col) Chris@49: : iterator_base(in_M, in_col, 0) Chris@49: , internal_row(0) Chris@49: , actual_pos(0) Chris@49: { Chris@49: // This is slow. It needs to be rewritten. Chris@49: // So we have a destination we want to be just after, but don't know what position that is. Make another iterator to find out... Chris@49: const_row_iterator it(in_M, 0); Chris@49: while((it.row() < in_row) || ((it.row() == in_row) && (it.col() < in_col))) Chris@49: { Chris@49: it++; Chris@49: } Chris@49: Chris@49: // Now that it is at the right place, take its position. Chris@49: iterator_base::internal_col = it.internal_col; Chris@49: iterator_base::internal_pos = it.internal_pos; Chris@49: internal_row = it.internal_row; Chris@49: actual_pos = it.actual_pos; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /** Chris@49: * Initialize the const_row_iterator from another const_row_iterator. Chris@49: */ Chris@49: template Chris@49: inline Chris@49: SpMat::const_row_iterator::const_row_iterator(const typename SpMat::const_row_iterator& other) Chris@49: : iterator_base(other.M, other.internal_col, other.internal_pos) Chris@49: , internal_row(other.internal_row) Chris@49: , actual_pos(other.actual_pos) Chris@49: { Chris@49: // Nothing to do. Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /** Chris@49: * Increment the row_iterator. Chris@49: */ Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_row_iterator& Chris@49: SpMat::const_row_iterator::operator++() Chris@49: { Chris@49: // We just need to find the next nonzero element. Chris@49: iterator_base::internal_pos++; Chris@49: Chris@49: if(iterator_base::internal_pos == iterator_base::M.n_nonzero) Chris@49: { Chris@49: internal_row = iterator_base::M.n_rows; Chris@49: iterator_base::internal_col = 0; Chris@49: actual_pos = iterator_base::M.n_nonzero; Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: // Otherwise, we need to search. Chris@49: uword cur_col = iterator_base::internal_col; Chris@49: uword cur_row = internal_row; Chris@49: Chris@49: while (true) // This loop is terminated from the inside. Chris@49: { Chris@49: // Increment the current column and see if we are now on a new row. Chris@49: if (++cur_col == iterator_base::M.n_cols) Chris@49: { Chris@49: cur_col = 0; Chris@49: cur_row++; Chris@49: } Chris@49: Chris@49: // Is there anything in this new column? Chris@49: for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++) Chris@49: { Chris@49: if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row) Chris@49: { Chris@49: // We have successfully incremented. Chris@49: internal_row = cur_row; Chris@49: iterator_base::internal_col = cur_col; Chris@49: actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; Chris@49: Chris@49: return *this; // Now we are done. Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /** Chris@49: * Increment the row_iterator (but do not return anything. Chris@49: */ Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_row_iterator Chris@49: SpMat::const_row_iterator::operator++(int) Chris@49: { Chris@49: typename SpMat::const_row_iterator tmp(*this); Chris@49: Chris@49: ++(*this); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /** Chris@49: * Decrement the row_iterator. Chris@49: */ Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_row_iterator& Chris@49: SpMat::const_row_iterator::operator--() Chris@49: { Chris@49: iterator_base::internal_pos--; Chris@49: Chris@49: // We have to search backwards. Chris@49: uword cur_col = iterator_base::internal_col; Chris@49: uword cur_row = internal_row; Chris@49: Chris@49: while (true) // This loop is terminated from the inside. Chris@49: { Chris@49: // Decrement the current column and see if we are now on a new row. This is a uword so a negativity check won't work. Chris@49: if (--cur_col > iterator_base::M.n_cols /* this means it underflew */) Chris@49: { Chris@49: cur_col = iterator_base::M.n_cols - 1; Chris@49: cur_row--; Chris@49: } Chris@49: Chris@49: // Is there anything in this new column? Chris@49: for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++) Chris@49: { Chris@49: if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row) Chris@49: { Chris@49: // We have successfully decremented. Chris@49: iterator_base::internal_col = cur_col; Chris@49: internal_row = cur_row; Chris@49: actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; Chris@49: Chris@49: return *this; // Now we are done. Chris@49: } Chris@49: } Chris@49: } Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /** Chris@49: * Decrement the row_iterator. Chris@49: */ Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::const_row_iterator Chris@49: SpMat::const_row_iterator::operator--(int) Chris@49: { Chris@49: typename SpMat::const_row_iterator tmp(*this); Chris@49: Chris@49: --(*this); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator==(const const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator!=(const const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator==(const typename SpSubview::const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator!=(const typename SpSubview::const_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator==(const const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator!=(const const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator==(const typename SpSubview::const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: bool Chris@49: SpMat::const_row_iterator::operator!=(const typename SpSubview::const_row_iterator& rhs) const Chris@49: { Chris@49: return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: // SpMat::row_iterator implementation // Chris@49: /////////////////////////////////////////////////////////////////////////////// Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: SpValProxy > Chris@49: SpMat::row_iterator::operator*() Chris@49: { Chris@49: return SpValProxy >( Chris@49: const_row_iterator::internal_row, Chris@49: iterator_base::internal_col, Chris@49: access::rw(iterator_base::M), Chris@49: &access::rw(iterator_base::M.values[const_row_iterator::actual_pos])); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::row_iterator& Chris@49: SpMat::row_iterator::operator++() Chris@49: { Chris@49: const_row_iterator::operator++(); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::row_iterator Chris@49: SpMat::row_iterator::operator++(int) Chris@49: { Chris@49: typename SpMat::row_iterator tmp(*this); Chris@49: Chris@49: const_row_iterator::operator++(); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::row_iterator& Chris@49: SpMat::row_iterator::operator--() Chris@49: { Chris@49: const_row_iterator::operator--(); Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: arma_hot Chris@49: typename SpMat::row_iterator Chris@49: SpMat::row_iterator::operator--(int) Chris@49: { Chris@49: typename SpMat::row_iterator tmp(*this); Chris@49: Chris@49: const_row_iterator::operator--(); Chris@49: Chris@49: return tmp; Chris@49: } Chris@49: Chris@49: //! @}