Rcpp Version 0.9.10
MatrixBase.h
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
00002 //
00003 // MatrixBase.h: Rcpp R/C++ interface class library -- 
00004 //
00005 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
00006 //
00007 // This file is part of Rcpp.
00008 //
00009 // Rcpp is free software: you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by
00011 // the Free Software Foundation, either version 2 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // Rcpp is distributed in the hope that it will be useful, but
00015 // WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
00021 
00022 #ifndef Rcpp__vector__MatrixBase_h
00023 #define Rcpp__vector__MatrixBase_h
00024 
00025 #include <Rcpp/sugar/matrix/tools.h>
00026 
00027 namespace Rcpp{
00028         
00030     template <int RTYPE, bool na, typename MATRIX>
00031     class MatrixBase : public traits::expands_to_logical__impl<RTYPE> {
00032     public:
00033         struct r_type : traits::integral_constant<int,RTYPE>{} ;
00034         struct r_matrix_interface {} ;
00035         struct can_have_na : traits::integral_constant<bool,na>{} ;
00036         typedef typename traits::storage_type<RTYPE>::type stored_type ;
00037         
00038         MATRIX& get_ref(){
00039             return static_cast<MATRIX&>(*this) ;
00040         }
00041 
00042         inline stored_type operator()( int i, int j) const {
00043             return static_cast<const MATRIX*>(this)->operator()(i, j) ;
00044         }
00045         
00046         inline int size() const { return static_cast<const MATRIX&>(*this).size() ; }
00047         inline int nrow() const { return static_cast<const MATRIX&>(*this).nrow() ; }
00048         inline int ncol() const { return static_cast<const MATRIX&>(*this).ncol() ; }
00049         
00050         class iterator {
00051         public:
00052             typedef stored_type reference ;
00053             typedef stored_type* pointer ;
00054             typedef int difference_type ;
00055             typedef stored_type value_type;
00056             typedef std::random_access_iterator_tag iterator_category ;
00057 
00058             iterator( const MatrixBase& object_, int index_ ) : 
00059                 object(object_), i(0), j(0), nr(object_.nrow()), nc(object_.ncol()) {
00060                         
00061                 update_index( index_) ; 
00062             }
00063                 
00064             iterator( const iterator& other) : 
00065                 object(other.object), i(other.i), j(other.j), nr(other.nr), nc(other.nc){}
00066                 
00067             inline iterator& operator++(){
00068                 i++ ;
00069                 if( i == nr ){
00070                     j++ ;
00071                     i=0 ;
00072                 }
00073                 return *this ;
00074             }
00075             inline iterator& operator++(int){
00076                 i++ ;
00077                 if( i == nr ){
00078                     j++ ;
00079                     i=0 ;
00080                 }
00081                 return *this ;
00082             }
00083                 
00084             inline iterator& operator--(){
00085                 i-- ;
00086                 if( i == -1 ){
00087                     j-- ;
00088                     i = nr - 1 ;
00089                 }
00090                 return *this ;
00091             }
00092             inline iterator& operator--(int){
00093                 i-- ;
00094                 if( i == -1 ){
00095                     j-- ;
00096                     i = nr - 1 ;
00097                 }
00098                 return *this ;
00099             }
00100                                     
00101             inline iterator operator+(difference_type n) const {
00102                 return iterator( object, i + (j*nr) + n ) ;
00103             }
00104             inline iterator operator-(difference_type n) const {
00105                 return iterator( object, i + (j*nr) - n ) ;
00106             }
00107                 
00108             inline iterator& operator+=(difference_type n) {
00109                 update_index( i + j*nr + n );
00110                 return *this ;
00111             }
00112             inline iterator& operator-=(difference_type n) {
00113                 update_index( i + j*nr - n );
00114                 return *this ;
00115             }
00116 
00117             inline reference operator*() {
00118                 //  TODO: it might be better to call object( i, j )
00119                 //        as in many cases the sugar expression 
00120                 //        is faster with two indexes
00121                 return object(i,j) ;
00122             }
00123             inline pointer operator->(){
00124                 return &object(i,j) ;
00125             }
00126                 
00127             inline bool operator==( const iterator& y) const {
00128                 return ( i == y.i && j == y.j ) ;
00129             }
00130             inline bool operator!=( const iterator& y) const {
00131                 return ( i != y.i || j != y.j ) ;
00132             }
00133             inline bool operator<( const iterator& other ) const {
00134                 return index() < other.index() ;
00135             }
00136             inline bool operator>( const iterator& other ) const {
00137                 return index() > other.index() ;
00138             }
00139             inline bool operator<=( const iterator& other ) const {
00140                 return index() <= other.index() ;
00141             }
00142             inline bool operator>=( const iterator& other ) const {
00143                 return index() >= other.index() ;
00144             }
00145                 
00146             inline difference_type operator-(const iterator& other) const {
00147                 return index() - other.index() ;
00148             }
00149         
00150                         
00151         private:
00152             const MatrixBase& object ;
00153             int i, j ;
00154             int nr, nc ;
00155                 
00156             inline void update_index( int index_ ){
00157                 i = internal::get_line( index_, nr );
00158                 j = internal::get_column( index_, nr, i ) ;
00159             }
00160                 
00161             inline int index() const {
00162                 return i + nr * j ;
00163             }
00164                 
00165         } ;
00166         
00167         inline iterator begin() const { return iterator(*this, 0) ; }
00168         inline iterator end() const { return iterator(*this, size() ) ; }
00169         
00170     } ;
00171 
00172 } // namespace Rcpp
00173 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines