Skip to content

Commit 48b37f6

Browse files
dcdilloneddelbuettel
authored andcommitted
Adding cbegin()/cend() to MatrixRow (#750)
* Adding cbegin()/cend() to MatrixRow. * Fixed returns of cbegin/cend and friends
1 parent 97e11da commit 48b37f6

File tree

3 files changed

+77
-30
lines changed

3 files changed

+77
-30
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
* vignettes/Rcpp-extending.Rmd: Idem
4747
* vignettes/Rcpp-attributes.Rmd: Idem
4848

49+
2017-09-18 Daniel C. Dillon <[email protected]>
50+
* inst/include/Rcpp/vector/MatrixRow.h: Added cbegin() and cend() to
51+
the class along with a framework for proper const-correctness in the
52+
future.
53+
4954
2017-09-03 Dirk Eddelbuettel <[email protected]>
5055

5156
* DESCRIPTION (Version, Date): Roll minor version

inst/include/Rcpp/vector/MatrixRow.h

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,46 +33,72 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow<RTYPE> > {
3333
typedef typename MATRIX::const_Proxy const_reference ;
3434
typedef typename MATRIX::value_type value_type ;
3535

36-
class iterator {
36+
// We now have the structure to correct const-correctness, but without
37+
// major changes to the proxy mechanism, we cannot do it correctly. As
38+
// a result, it turns out that both MatrixRow iterators are effectively
39+
// const, but this has always been the way it is so we won't break any
40+
// compatibility. TODO: Fix proxies and make this const correct.
41+
struct iter_traits
42+
{
43+
typedef typename traits::r_vector_iterator<RTYPE>::type vector_iterator;
44+
45+
typedef int difference_type;
46+
typedef typename traits::r_vector_proxy<RTYPE>::type value_type;
47+
typedef value_type reference;
48+
typedef typename std::iterator_traits<vector_iterator>::pointer pointer;
49+
};
50+
51+
struct const_iter_traits
52+
{
53+
typedef typename traits::r_vector_const_iterator<RTYPE>::type vector_iterator;
54+
55+
typedef int difference_type;
56+
typedef typename traits::r_vector_proxy<RTYPE>::type value_type;
57+
typedef value_type reference;
58+
typedef typename std::iterator_traits<vector_iterator>::pointer pointer;
59+
};
60+
61+
template< typename TRAITS >
62+
class iter_base {
3763
public:
38-
typedef typename traits::r_vector_iterator<RTYPE>::type vector_iterator ;
64+
typedef typename TRAITS::vector_iterator vector_iterator;
3965

40-
typedef int difference_type ;
41-
typedef typename traits::r_vector_proxy<RTYPE>::type value_type ;
42-
typedef typename traits::r_vector_proxy<RTYPE>::type reference ;
43-
typedef typename std::iterator_traits<vector_iterator>::pointer pointer ;
66+
typedef typename TRAITS::difference_type difference_type ;
67+
typedef typename TRAITS::value_type value_type ;
68+
typedef typename TRAITS::reference reference ;
69+
typedef typename TRAITS::pointer pointer ;
4470

4571
typedef std::random_access_iterator_tag iterator_category ;
4672

47-
iterator( const iterator& other) : row(other.row), index(other.index){}
48-
iterator( MatrixRow& row_, int index_ ) : row(row_), index(index_){}
73+
iter_base( const iter_base& other) : row(other.row), index(other.index){}
74+
iter_base( MatrixRow& row_, int index_ ) : row(row_), index(index_){}
4975

50-
iterator& operator++(){
76+
iter_base& operator++(){
5177
index++;
5278
return *this ;
5379
}
54-
iterator operator++(int) {
80+
iter_base operator++(int) {
5581
iterator orig(*this);
5682
index++ ;
5783
return orig ;
5884
}
5985

60-
iterator& operator--(){
86+
iter_base& operator--(){
6187
index-- ;
6288
return *this ;
6389
}
64-
iterator operator--(int){
65-
iterator orig(*this);
90+
iter_base operator--(int){
91+
iter_base orig(*this);
6692
index-- ;
6793
return orig ;
6894
}
6995

70-
iterator operator+(difference_type n) const { return iterator( row, index + n ) ; }
71-
iterator operator-(difference_type n) const { return iterator( row, index - n ) ; }
72-
difference_type operator-(const iterator& other) const { return index - other.index ; }
96+
iter_base operator+(difference_type n) const { return iter_base( row, index + n ) ; }
97+
iter_base operator-(difference_type n) const { return iter_base( row, index - n ) ; }
98+
difference_type operator-(const iter_base& other) const { return index - other.index ; }
7399

74-
iterator& operator+=(difference_type n) { index += n ; return *this ;}
75-
iterator& operator-=(difference_type n) { index -= n ; return *this ;}
100+
iter_base& operator+=(difference_type n) { index += n ; return *this ;}
101+
iter_base& operator-=(difference_type n) { index -= n ; return *this ;}
76102

77103
reference operator*() {
78104
return row[index] ;
@@ -81,25 +107,28 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow<RTYPE> > {
81107
return &row[index] ;
82108
}
83109

84-
bool operator==( const iterator& other) { return index == other.index ; }
85-
bool operator!=( const iterator& other) { return index != other.index ; }
86-
bool operator<( const iterator& other ) { return index < other.index ;}
87-
bool operator>( const iterator& other ) { return index > other.index ;}
88-
bool operator<=( const iterator& other ) { return index <= other.index ; }
89-
bool operator>=( const iterator& other ) { return index >= other.index ; }
110+
bool operator==( const iter_base& other) { return index == other.index ; }
111+
bool operator!=( const iter_base& other) { return index != other.index ; }
112+
bool operator<( const iter_base& other ) { return index < other.index ;}
113+
bool operator>( const iter_base& other ) { return index > other.index ;}
114+
bool operator<=( const iter_base& other ) { return index <= other.index ; }
115+
bool operator>=( const iter_base& other ) { return index >= other.index ; }
90116

91117
inline reference operator[]( int i) const {
92118
return row[ index + i ] ;
93119
}
94120

95-
difference_type operator-(const iterator& other) {
121+
difference_type operator-(const iter_base& other) {
96122
return index - other.index ;
97123
}
98124

99125
private:
100126
MatrixRow& row ;
101127
int index ;
102-
} ;
128+
};
129+
130+
typedef iter_base< iter_traits > iterator;
131+
typedef iter_base< const_iter_traits > const_iterator;
103132

104133
MatrixRow( MATRIX& object, int i ) :
105134
parent(object),
@@ -151,12 +180,20 @@ class MatrixRow : public VectorBase< RTYPE, true, MatrixRow<RTYPE> > {
151180
return iterator( *this, size() ) ;
152181
}
153182

154-
inline iterator begin() const {
155-
return iterator( const_cast<MatrixRow&>(*this), 0 ) ;
183+
inline const_iterator begin() const {
184+
return const_iterator( const_cast<MatrixRow&>(*this), 0 ) ;
185+
}
186+
187+
inline const_iterator end() const {
188+
return const_iterator( const_cast<MatrixRow&>(*this), size() ) ;
189+
}
190+
191+
inline const_iterator cbegin() const {
192+
return const_iterator( const_cast<MatrixRow&>(*this), 0 ) ;
156193
}
157194

158-
inline iterator end() const {
159-
return iterator( const_cast<MatrixRow&>(*this), size() ) ;
195+
inline const_iterator cend() const {
196+
return const_iterator( const_cast<MatrixRow&>(*this), size() ) ;
160197
}
161198

162199
inline int size() const {

inst/include/Rcpp/vector/VectorBase.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ class VectorBase : public traits::expands_to_logical__impl<RTYPE> {
4848

4949
inline R_xlen_t size() const { return static_cast<const VECTOR*>(this)->size() ; }
5050

51+
// We now have the structure to correct const-correctness, but without
52+
// major changes to the proxy mechanism, we cannot do it correctly. As
53+
// a result, it turns out that both Vector iterators are effectively
54+
// const, but this has always been the way it is so we won't break any
55+
// compatibility. TODO: Fix proxies and make this const correct.
5156
struct iter_traits
5257
{
5358
typedef stored_type & reference ;

0 commit comments

Comments
 (0)