|
Rcpp Version 0.9.10
|
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