EVOLUTION-MANAGER
Edit File: MatrixRow.h
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- // // MatrixRow.h: Rcpp R/C++ interface class library -- matrices row // // Copyright (C) 2010 - 2013 Dirk Eddelbuettel and Romain Francois // // This file is part of Rcpp. // // Rcpp is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // Rcpp is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. #ifndef Rcpp__vector__MatrixRow_h #define Rcpp__vector__MatrixRow_h namespace Rcpp{ template <int RTYPE> class MatrixRow : public VectorBase< RTYPE, true, MatrixRow<RTYPE> > { public: typedef Matrix<RTYPE> MATRIX ; typedef typename MATRIX::Proxy Proxy ; typedef typename MATRIX::Proxy reference ; typedef typename MATRIX::const_Proxy const_reference ; typedef typename MATRIX::value_type value_type ; // We now have the structure to correct const-correctness, but without // major changes to the proxy mechanism, we cannot do it correctly. As // a result, it turns out that both MatrixRow iterators are effectively // const, but this has always been the way it is so we won't break any // compatibility. TODO: Fix proxies and make this const correct. struct iter_traits { typedef typename traits::r_vector_iterator<RTYPE>::type vector_iterator; typedef int difference_type; typedef typename traits::r_vector_proxy<RTYPE>::type value_type; typedef value_type reference; typedef typename std::iterator_traits<vector_iterator>::pointer pointer; }; struct const_iter_traits { typedef typename traits::r_vector_const_iterator<RTYPE>::type vector_iterator; typedef int difference_type; typedef typename traits::r_vector_proxy<RTYPE>::type value_type; typedef value_type reference; typedef typename std::iterator_traits<vector_iterator>::pointer pointer; }; template< typename TRAITS > class iter_base { public: typedef typename TRAITS::vector_iterator vector_iterator; typedef typename TRAITS::difference_type difference_type ; typedef typename TRAITS::value_type value_type ; typedef typename TRAITS::reference reference ; typedef typename TRAITS::pointer pointer ; typedef std::random_access_iterator_tag iterator_category ; iter_base( const iter_base& other) : row(other.row), index(other.index){} iter_base( MatrixRow& row_, int index_ ) : row(row_), index(index_){} iter_base& operator++(){ index++; return *this ; } iter_base operator++(int) { iterator orig(*this); index++ ; return orig ; } iter_base& operator--(){ index-- ; return *this ; } iter_base operator--(int){ iter_base orig(*this); index-- ; return orig ; } iter_base operator+(difference_type n) const { return iter_base( row, index + n ) ; } iter_base operator-(difference_type n) const { return iter_base( row, index - n ) ; } difference_type operator-(const iter_base& other) const { return index - other.index ; } iter_base& operator+=(difference_type n) { index += n ; return *this ;} iter_base& operator-=(difference_type n) { index -= n ; return *this ;} reference operator*() { return row[index] ; } pointer operator->(){ return &row[index] ; } bool operator==( const iter_base& other) { return index == other.index ; } bool operator!=( const iter_base& other) { return index != other.index ; } bool operator<( const iter_base& other ) { return index < other.index ;} bool operator>( const iter_base& other ) { return index > other.index ;} bool operator<=( const iter_base& other ) { return index <= other.index ; } bool operator>=( const iter_base& other ) { return index >= other.index ; } inline reference operator[]( int i) const { return row[ index + i ] ; } difference_type operator-(const iter_base& other) { return index - other.index ; } private: MatrixRow& row ; int index ; }; typedef iter_base< iter_traits > iterator; typedef iter_base< const_iter_traits > const_iterator; MatrixRow( MATRIX& object, int i ) : parent(object), start(parent.begin() + i), parent_nrow(parent.nrow()), row(i) { if( i < 0 || i >= parent.nrow() ) { const char* fmt = "Row index is out of bounds: " "[index=%i; row extent=%i]."; throw index_out_of_bounds(fmt, i, parent.nrow()) ; } } MatrixRow( const MatrixRow& other ) : parent(other.parent), start(other.start), parent_nrow(other.parent_nrow), row(other.row) {} ; template <int RT, bool NA, typename T> MatrixRow& operator=( const Rcpp::VectorBase<RT,NA,T>& rhs ){ int n = size() ; const T& ref = rhs.get_ref() ; RCPP_LOOP_UNROLL_LHSFUN(start,get_parent_index,ref) return *this ; } MatrixRow& operator=( const MatrixRow& rhs ){ int n = size() ; RCPP_LOOP_UNROLL_LHSFUN(start,get_parent_index,rhs) return *this ; } inline reference operator[]( int i ){ return start[ get_parent_index(i) ] ; } inline reference operator[]( int i ) const { return parent[ row + i * parent_nrow ] ; } inline iterator begin(){ return iterator( *this, 0 ) ; } inline iterator end(){ return iterator( *this, size() ) ; } inline const_iterator begin() const { return const_iterator( const_cast<MatrixRow&>(*this), 0 ) ; } inline const_iterator end() const { return const_iterator( const_cast<MatrixRow&>(*this), size() ) ; } inline const_iterator cbegin() const { return const_iterator( const_cast<MatrixRow&>(*this), 0 ) ; } inline const_iterator cend() const { return const_iterator( const_cast<MatrixRow&>(*this), size() ) ; } inline int size() const { return parent.ncol() ; } private: MATRIX& parent; typename MATRIX::iterator start ; int parent_nrow ; int row ; inline int get_parent_index(int i) const { RCPP_DEBUG_4( "MatrixRow<%d>::get_parent_index(int = %d), parent_nrow = %d >> %d\n", RTYPE, i, parent_nrow, i*parent_nrow ) return i * parent_nrow ; } } ; template <int RTYPE> class ConstMatrixRow : public VectorBase< RTYPE, true, ConstMatrixRow<RTYPE> > { public: typedef Matrix<RTYPE> MATRIX ; typedef typename MATRIX::const_Proxy const_reference ; typedef typename MATRIX::value_type value_type ; class const_iterator { public: typedef typename traits::r_vector_iterator<RTYPE>::type vector_iterator ; typedef int difference_type ; typedef typename traits::r_vector_const_proxy<RTYPE>::type value_type ; typedef typename traits::r_vector_const_proxy<RTYPE>::type reference ; typedef typename std::iterator_traits<vector_iterator>::pointer pointer ; typedef std::random_access_iterator_tag iterator_category ; const_iterator( const const_iterator& other) : row(other.row), index(other.index){} const_iterator( const ConstMatrixRow& row_, int index_ ) : row(row_), index(index_){} const_iterator& operator++(){ index++; return *this ; } const_iterator operator++(int) { const_iterator orig(*this); index++ ; return orig ; } const_iterator& operator--(){ index-- ; return *this ; } const_iterator operator--(int){ const_iterator orig(*this); index-- ; return orig ; } const_iterator operator+(difference_type n) const { return iterator( row, index + n ) ; } const_iterator operator-(difference_type n) const { return iterator( row, index - n ) ; } difference_type operator-(const const_iterator& other) const { return index - other.index ; } const_iterator& operator+=(difference_type n) { index += n ; return *this ;} const_iterator& operator-=(difference_type n) { index -= n ; return *this ;} const reference operator*() { return row[index] ; } const pointer operator->(){ return &row[index] ; } bool operator==( const const_iterator& other) { return index == other.index ; } bool operator!=( const const_iterator& other) { return index != other.index ; } bool operator<( const const_iterator& other ) { return index < other.index ;} bool operator>( const const_iterator& other ) { return index > other.index ;} bool operator<=( const const_iterator& other ) { return index <= other.index ; } bool operator>=( const const_iterator& other ) { return index >= other.index ; } inline const reference operator[]( int i) const { return row[ index + i ] ; } difference_type operator-(const const_iterator& other) { return index - other.index ; } private: const ConstMatrixRow& row ; int index ; } ; typedef const_iterator iterator; ConstMatrixRow( const MATRIX& object, int i ) : parent(object), start(parent.begin() + i), parent_nrow(parent.nrow()), row(i) { if( i < 0 || i >= parent.nrow() ) { const char* fmt = "Row index is out of bounds: " "[index=%i; row extent=%i]."; throw index_out_of_bounds(fmt, i, parent.nrow()) ; } } ConstMatrixRow( const ConstMatrixRow& other ) : parent(other.parent), start(other.start), parent_nrow(other.parent_nrow), row(other.row) {} ; inline const_reference operator[]( int i ) const { return parent[ row + i * parent_nrow ] ; } inline const_iterator begin() const { return const_iterator( *this, 0 ) ; } inline const_iterator end() const { return const_iterator( *this, size() ) ; } inline int size() const { return parent.ncol() ; } private: const MATRIX& parent; typename MATRIX::const_iterator start ; int parent_nrow ; int row ; inline int get_parent_index(int i) const { RCPP_DEBUG_4( "ConstMatrixRow<%d>::get_parent_index(int = %d), parent_nrow = %d >> %d\n", RTYPE, i, parent_nrow, i*parent_nrow ) return i * parent_nrow ; } } ; } #endif