Skip to content

Commit eda71fd

Browse files
committed
Merge pull request #405 from dcdillon/master
Added ConstMatrixRow and ConstMatrixColumn per #200
2 parents cae9a81 + 533b9e7 commit eda71fd

File tree

8 files changed

+267
-3
lines changed

8 files changed

+267
-3
lines changed

inst/include/Rcpp/String.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,14 @@ namespace Rcpp {
217217
setBuffer(); buffer += CHAR(proxy_sexp); valid = false;
218218
return *this;
219219
}
220+
inline String& operator+=(const const_StringProxy& proxy) {
221+
RCPP_STRING_DEBUG("String::operator+=(const StringProxy&)");
222+
if (is_na()) return *this;
223+
SEXP proxy_sexp = proxy;
224+
if (proxy_sexp == NA_STRING) { data = Rcpp_ReplaceObject(data, NA_STRING); valid = true; buffer_ready = false; return *this;}
225+
setBuffer(); buffer += CHAR(proxy_sexp); valid = false;
226+
return *this;
227+
}
220228
inline String& operator+=(SEXP x) {
221229
RCPP_STRING_DEBUG("String::operator+=(SEXP)");
222230
if (is_na()) return *this;

inst/include/Rcpp/Vector.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ namespace Rcpp{
3131
template <int RTYPE, bool NA, typename VECTOR> struct Extractor ;
3232
}
3333
template <int RTYPE> class MatrixRow ;
34+
template <int RTYPE> class ConstMatrixRow ;
3435
template <int RTYPE> class MatrixColumn ;
36+
template <int RTYPE> class ConstMatrixColumn ;
3537
template <int RTYPE> class SubMatrix ;
3638

3739
class Dimension ;

inst/include/Rcpp/internal/Proxy_Iterator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class Proxy_Iterator {
112112

113113
inline int index() const { return proxy.index ; }
114114

115-
inline PROXY operator[](R_xlen_t i){ return PROXY(*proxy.parent, proxy.index + i) ; }
115+
inline PROXY operator[](R_xlen_t i) const { return PROXY(*proxy.parent, proxy.index + i) ; }
116116

117117
private:
118118
PROXY proxy ;

inst/include/Rcpp/vector/Matrix.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, tru
3232
struct r_type : traits::integral_constant<int,RTYPE>{} ;
3333
struct can_have_na : traits::true_type{} ;
3434
typedef MatrixRow<RTYPE> Row ;
35+
typedef ConstMatrixRow<RTYPE> ConstRow ;
3536
typedef MatrixColumn<RTYPE> Column ;
37+
typedef ConstMatrixColumn<RTYPE> ConstColumn ;
3638
typedef SubMatrix<RTYPE> Sub ;
3739

3840
typedef StoragePolicy<Matrix> Storage ;
@@ -103,7 +105,9 @@ class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, tru
103105
}
104106

105107
inline Row row( int i ){ return Row( *this, i ) ; }
108+
inline ConstRow row( int i ) const{ return ConstRow( *this, i ) ; }
106109
inline Column column( int i ){ return Column(*this, i ) ; }
110+
inline ConstColumn column( int i ) const{ return ConstColumn( *this, i ) ; }
107111

108112
inline const_iterator begin() const{ return VECTOR::begin() ; }
109113
inline const_iterator end() const{ return VECTOR::end() ; }
@@ -145,11 +149,14 @@ class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, tru
145149
inline Row operator()( int i, internal::NamedPlaceHolder ) {
146150
return Row( *this, i ) ;
147151
}
152+
inline ConstRow operator()( int i, internal::NamedPlaceHolder ) const {
153+
return ConstRow( *this, i ) ;
154+
}
148155
inline Column operator()( internal::NamedPlaceHolder, int i ) {
149156
return Column( *this, i ) ;
150157
}
151-
inline Column operator()( internal::NamedPlaceHolder, int i ) const {
152-
return Column( *this, i ) ;
158+
inline ConstColumn operator()( internal::NamedPlaceHolder, int i ) const {
159+
return ConstColumn( *this, i ) ;
153160
}
154161
inline Sub operator()( const Range& row_range, const Range& col_range) {
155162
return Sub( const_cast<Matrix&>(*this), row_range, col_range ) ;

inst/include/Rcpp/vector/MatrixColumn.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,46 @@ class MatrixColumn : public VectorBase<RTYPE,true,MatrixColumn<RTYPE> > {
103103

104104
} ;
105105

106+
template <int RTYPE>
107+
class ConstMatrixColumn : public VectorBase<RTYPE,true,ConstMatrixColumn<RTYPE> > {
108+
public:
109+
typedef Matrix<RTYPE> MATRIX ;
110+
typedef typename MATRIX::const_Proxy const_Proxy ;
111+
typedef typename MATRIX::value_type value_type ;
112+
typedef typename MATRIX::const_iterator const_iterator ;
113+
114+
ConstMatrixColumn( const MATRIX& parent, int i ) :
115+
n(parent.nrow()),
116+
const_start(parent.begin() + i *n)
117+
{
118+
if( i < 0 || i >= parent.ncol() ) throw index_out_of_bounds() ;
119+
}
120+
121+
ConstMatrixColumn( const ConstMatrixColumn& other ) :
122+
n(other.n),
123+
const_start(other.const_start) {}
124+
125+
inline const_Proxy operator[]( int i ) const {
126+
return const_start[i] ;
127+
}
128+
129+
inline const_iterator begin() const {
130+
return const_start ;
131+
}
132+
133+
inline const_iterator end() const {
134+
return const_start + n ;
135+
}
136+
137+
inline int size() const {
138+
return n ;
139+
}
140+
141+
private:
142+
const int n ;
143+
const_iterator const_start ;
144+
145+
} ;
146+
106147
}
107148
#endif

inst/include/Rcpp/vector/MatrixRow.h

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,127 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow<RTYPE> > {
170170
return i * parent_nrow ;
171171
}
172172
} ;
173+
174+
template <int RTYPE>
175+
class ConstMatrixRow : public VectorBase< RTYPE, true, ConstMatrixRow<RTYPE> > {
176+
public:
177+
typedef Matrix<RTYPE> MATRIX ;
178+
typedef typename MATRIX::const_Proxy const_reference ;
179+
typedef typename MATRIX::value_type value_type ;
180+
181+
class const_iterator {
182+
public:
183+
typedef typename traits::r_vector_iterator<RTYPE>::type vector_iterator ;
184+
185+
typedef int difference_type ;
186+
typedef typename traits::r_vector_const_proxy<RTYPE>::type value_type ;
187+
typedef typename traits::r_vector_const_proxy<RTYPE>::type reference ;
188+
typedef typename std::iterator_traits<vector_iterator>::pointer pointer ;
189+
190+
typedef std::random_access_iterator_tag iterator_category ;
191+
192+
const_iterator( const const_iterator& other) : row(other.row), index(other.index){}
193+
const_iterator( const ConstMatrixRow& row_, int index_ ) : row(row_), index(index_){}
194+
195+
const_iterator& operator++(){
196+
index++;
197+
return *this ;
198+
}
199+
const_iterator operator++(int) {
200+
const_iterator orig(*this);
201+
index++ ;
202+
return orig ;
203+
}
204+
205+
const_iterator& operator--(){
206+
index-- ;
207+
return *this ;
208+
}
209+
const_iterator operator--(int){
210+
const_iterator orig(*this);
211+
index-- ;
212+
return orig ;
213+
}
214+
215+
const_iterator operator+(difference_type n) const { return iterator( row, index + n ) ; }
216+
const_iterator operator-(difference_type n) const { return iterator( row, index - n ) ; }
217+
difference_type operator-(const const_iterator& other) const { return index - other.index ; }
218+
219+
const_iterator& operator+=(difference_type n) { index += n ; return *this ;}
220+
const_iterator& operator-=(difference_type n) { index -= n ; return *this ;}
221+
222+
const reference operator*() {
223+
return row[index] ;
224+
}
225+
const pointer operator->(){
226+
return &row[index] ;
227+
}
228+
229+
bool operator==( const const_iterator& other) { return index == other.index ; }
230+
bool operator!=( const const_iterator& other) { return index != other.index ; }
231+
bool operator<( const const_iterator& other ) { return index < other.index ;}
232+
bool operator>( const const_iterator& other ) { return index > other.index ;}
233+
bool operator<=( const const_iterator& other ) { return index <= other.index ; }
234+
bool operator>=( const const_iterator& other ) { return index >= other.index ; }
235+
236+
inline const reference operator[]( int i) const {
237+
return row[ index + i ] ;
238+
}
239+
240+
difference_type operator-(const const_iterator& other) {
241+
return index - other.index ;
242+
}
243+
244+
private:
245+
const ConstMatrixRow& row ;
246+
int index ;
247+
} ;
248+
249+
typedef const_iterator iterator;
250+
251+
ConstMatrixRow( const MATRIX& object, int i ) :
252+
parent(object),
253+
start(parent.begin() + i),
254+
parent_nrow(parent.nrow()),
255+
row(i)
256+
{
257+
if( i < 0 || i >= parent.nrow() ) throw index_out_of_bounds() ;
258+
}
259+
260+
ConstMatrixRow( const ConstMatrixRow& other ) :
261+
parent(other.parent),
262+
start(other.start),
263+
parent_nrow(other.parent_nrow),
264+
row(other.row)
265+
{} ;
266+
267+
inline const_reference operator[]( int i ) const {
268+
return parent[ row + i * parent_nrow ] ;
269+
}
270+
271+
inline const_iterator begin() const {
272+
return const_iterator( *this, 0 ) ;
273+
}
274+
275+
inline const_iterator end() const {
276+
return const_iterator( *this, size() ) ;
277+
}
278+
279+
inline int size() const {
280+
return parent.ncol() ;
281+
}
282+
283+
private:
284+
const MATRIX& parent;
285+
typename MATRIX::const_iterator start ;
286+
int parent_nrow ;
287+
int row ;
288+
289+
inline int get_parent_index(int i) const {
290+
RCPP_DEBUG_4( "ConstMatrixRow<%d>::get_parent_index(int = %d), parent_nrow = %d >> %d\n", RTYPE, i, parent_nrow, i*parent_nrow )
291+
return i * parent_nrow ;
292+
}
293+
} ;
173294
}
174295

175296
#endif

inst/unitTests/cpp/Matrix.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ double runit_NumericMatrix_row( NumericMatrix m){
9999
return std::accumulate( first_row.begin(), first_row.end(), 0.0 ) ;
100100
}
101101

102+
// [[Rcpp::export]]
103+
double runit_NumericMatrix_row_const( const NumericMatrix m){
104+
NumericMatrix::ConstRow first_row = m.row(0) ;
105+
return std::accumulate( first_row.begin(), first_row.end(), 0.0 ) ;
106+
}
107+
102108
// [[Rcpp::export]]
103109
std::string runit_CharacterMatrix_row( CharacterMatrix m ){
104110
CharacterMatrix::Row first_row = m.row(0) ;
@@ -108,6 +114,15 @@ std::string runit_CharacterMatrix_row( CharacterMatrix m ){
108114
return res ;
109115
}
110116

117+
// [[Rcpp::export]]
118+
std::string runit_CharacterMatrix_row_const( const CharacterMatrix m ){
119+
CharacterMatrix::ConstRow first_row = m.row(0) ;
120+
std::string res(
121+
std::accumulate(
122+
first_row.begin(), first_row.end(), std::string() ) ) ;
123+
return res ;
124+
}
125+
111126
// [[Rcpp::export]]
112127
IntegerVector runit_GenericMatrix_row( GenericMatrix m ){
113128
GenericMatrix::Row first_row = m.row(0) ;
@@ -119,12 +134,29 @@ IntegerVector runit_GenericMatrix_row( GenericMatrix m ){
119134
return out ;
120135
}
121136

137+
// [[Rcpp::export]]
138+
IntegerVector runit_GenericMatrix_row_const( const GenericMatrix m ){
139+
GenericMatrix::ConstRow first_row = m.row(0) ;
140+
IntegerVector out( first_row.size() ) ;
141+
std::transform(
142+
first_row.begin(), first_row.end(),
143+
out.begin(),
144+
unary_call<SEXP,int>( Function("length" ) ) ) ;
145+
return out ;
146+
}
147+
122148
// [[Rcpp::export]]
123149
double runit_NumericMatrix_column( NumericMatrix m ){
124150
NumericMatrix::Column col = m.column(0) ;
125151
return std::accumulate( col.begin(), col.end(), 0.0 ) ;
126152
}
127153

154+
// [[Rcpp::export]]
155+
double runit_NumericMatrix_column_const( const NumericMatrix m ){
156+
NumericMatrix::ConstColumn col = m.column(0) ;
157+
return std::accumulate( col.begin(), col.end(), 0.0 ) ;
158+
}
159+
128160
// [[Rcpp::export]]
129161
NumericMatrix runit_NumericMatrix_cumsum( NumericMatrix input ){
130162
int nr = input.nrow(), nc = input.ncol() ;
@@ -147,6 +179,15 @@ std::string runit_CharacterMatrix_column( CharacterMatrix m){
147179
return res ;
148180
}
149181

182+
// [[Rcpp::export]]
183+
std::string runit_CharacterMatrix_column_const( const CharacterMatrix m){
184+
CharacterMatrix::ConstColumn col = m.column(0) ;
185+
std::string res(
186+
std::accumulate( col.begin(), col.end(), std::string() )
187+
) ;
188+
return res ;
189+
}
190+
150191
// [[Rcpp::export]]
151192
IntegerVector runit_GenericMatrix_column( GenericMatrix m ){
152193
GenericMatrix::Column col = m.column(0) ;
@@ -159,6 +200,18 @@ IntegerVector runit_GenericMatrix_column( GenericMatrix m ){
159200
return wrap(out) ;
160201
}
161202

203+
// [[Rcpp::export]]
204+
IntegerVector runit_GenericMatrix_column_const( const GenericMatrix m ){
205+
GenericMatrix::ConstColumn col = m.column(0) ;
206+
IntegerVector out( col.size() ) ;
207+
std::transform(
208+
col.begin(), col.end(),
209+
out.begin(),
210+
unary_call<SEXP,int>( Function("length" ) )
211+
) ;
212+
return wrap(out) ;
213+
}
214+
162215
// [[Rcpp::export]]
163216
List runit_Row_Column_sugar( NumericMatrix x){
164217
NumericVector r0 = x.row(0) ;

0 commit comments

Comments
 (0)