22
22
#ifndef Rcpp_vector_Subsetter_h_
23
23
#define Rcpp_vector_Subsetter_h_
24
24
25
+ #include < limits>
26
+
25
27
namespace Rcpp {
26
28
27
29
template <
@@ -51,14 +53,14 @@ class SubsetProxy {
51
53
// Enable e.g. x[y] = z
52
54
template <int OtherRTYPE, template <class > class OtherStoragePolicy >
53
55
SubsetProxy& operator =(const Vector<OtherRTYPE, OtherStoragePolicy>& other) {
54
- int n = other.size ();
56
+ R_xlen_t n = other.size ();
55
57
56
58
if (n == 1 ) {
57
- for (int i=0 ; i < indices_n; ++i) {
59
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
58
60
lhs[ indices[i] ] = other[0 ];
59
61
}
60
62
} else if (n == indices_n) {
61
- for (int i=0 ; i < n; ++i) {
63
+ for (R_xlen_t i=0 ; i < n; ++i) {
62
64
lhs[ indices[i] ] = other[i];
63
65
}
64
66
} else {
@@ -70,28 +72,28 @@ class SubsetProxy {
70
72
// Enable e.g. x[y] = 1;
71
73
// TODO: std::enable_if<primitive> with C++11
72
74
SubsetProxy& operator =(double other) {
73
- for (int i=0 ; i < indices_n; ++i) {
75
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
74
76
lhs[ indices[i] ] = other;
75
77
}
76
78
return *this ;
77
79
}
78
80
79
81
SubsetProxy& operator =(int other) {
80
- for (int i=0 ; i < indices_n; ++i) {
82
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
81
83
lhs[ indices[i] ] = other;
82
84
}
83
85
return *this ;
84
86
}
85
87
86
88
SubsetProxy& operator =(const char * other) {
87
- for (int i=0 ; i < indices_n; ++i) {
89
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
88
90
lhs[ indices[i] ] = other;
89
91
}
90
92
return *this ;
91
93
}
92
94
93
95
SubsetProxy& operator =(bool other) {
94
- for (int i=0 ; i < indices_n; ++i) {
96
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
95
97
lhs[ indices[i] ] = other;
96
98
}
97
99
return *this ;
@@ -107,12 +109,12 @@ class SubsetProxy {
107
109
108
110
SubsetProxy& operator =(const SubsetProxy& other) {
109
111
if (other.indices_n == 1 ) {
110
- for (int i=0 ; i < indices_n; ++i) {
112
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
111
113
lhs[ indices[i] ] = other.lhs [other.indices [0 ]];
112
114
}
113
115
}
114
116
else if (indices_n == other.indices_n ) {
115
- for (int i=0 ; i < indices_n; ++i)
117
+ for (R_xlen_t i=0 ; i < indices_n; ++i)
116
118
lhs[ indices[i] ] = other.lhs [other.indices [i]];
117
119
}
118
120
else {
@@ -132,34 +134,40 @@ class SubsetProxy {
132
134
private:
133
135
134
136
#ifndef RCPP_NO_BOUNDS_CHECK
135
- void check_indices (int * x, int n, int size) {
136
- for (int i=0 ; i < n; ++i) {
137
+ template <typename IDX>
138
+ void check_indices (IDX* x, R_xlen_t n, R_xlen_t size) {
139
+ for (IDX i=0 ; i < n; ++i) {
137
140
if (x[i] < 0 or x[i] >= size) {
141
+ if (std::numeric_limits<IDX>::is_integer && size > std::numeric_limits<IDX>::max ()) {
142
+ stop (" use NumericVector to index an object of this size" );
143
+ }
138
144
stop (" index error" );
139
145
}
140
146
}
141
147
}
142
148
#else
143
- void check_indices (int * x, int n, int size) {}
149
+ template <typename IDX>
150
+ void check_indices (IDX* x, IDX n, IDX size) {}
144
151
#endif
145
152
146
153
void get_indices ( traits::identity< traits::int2type<INTSXP> > t ) {
147
154
indices.reserve (rhs_n);
148
- int * ptr = INTEGER (rhs);
155
+ int * ptr = INTEGER (rhs); // ok to use int * here, we'll catch any problems inside check_indices
149
156
check_indices (ptr, rhs_n, lhs_n);
150
- for (int i=0 ; i < rhs_n; ++i) {
157
+ for (R_xlen_t i=0 ; i < rhs_n; ++i) {
151
158
indices.push_back ( rhs[i] );
152
159
}
153
160
indices_n = rhs_n;
154
161
}
155
162
156
163
void get_indices ( traits::identity< traits::int2type<REALSXP> > t ) {
157
164
indices.reserve (rhs_n);
158
- Vector<INTSXP, StoragePolicy> tmp =
159
- as< Vector<INTSXP, StoragePolicy> >(rhs);
160
- int * ptr = INTEGER (tmp);
161
- check_indices (ptr, rhs_n, lhs_n);
162
- for (int i=0 ; i < rhs_n; ++i) {
165
+ std::vector<R_xlen_t> tmp (rhs.size ()); // create temp R_xlen_t type indices from reals
166
+ for (size_t i = 0 ; i < tmp.size () ; ++i) {
167
+ tmp[i] = rhs[i];
168
+ }
169
+ check_indices (&tmp[0 ], rhs_n, lhs_n);
170
+ for (R_xlen_t i=0 ; i < rhs_n; ++i) {
163
171
indices.push_back ( tmp[i] );
164
172
}
165
173
indices_n = rhs_n;
@@ -171,7 +179,7 @@ class SubsetProxy {
171
179
if (Rf_isNull (names)) stop (" names is null" );
172
180
SEXP* namesPtr = STRING_PTR (names);
173
181
SEXP* rhsPtr = STRING_PTR (rhs);
174
- for (int i = 0 ; i < rhs_n; ++i) {
182
+ for (R_xlen_t i = 0 ; i < rhs_n; ++i) {
175
183
SEXP* match = std::find (namesPtr, namesPtr + lhs_n, *(rhsPtr + i));
176
184
if (match == namesPtr + lhs_n)
177
185
stop (" not found" );
@@ -186,7 +194,7 @@ class SubsetProxy {
186
194
stop (" logical subsetting requires vectors of identical size" );
187
195
}
188
196
int * ptr = LOGICAL (rhs);
189
- for (int i=0 ; i < rhs_n; ++i) {
197
+ for (R_xlen_t i=0 ; i < rhs_n; ++i) {
190
198
if (ptr[i] == NA_INTEGER) {
191
199
stop (" can't subset using a logical vector with NAs" );
192
200
}
@@ -199,13 +207,13 @@ class SubsetProxy {
199
207
200
208
Vector<RTYPE, StoragePolicy> get_vec () const {
201
209
Vector<RTYPE, StoragePolicy> output = no_init (indices_n);
202
- for (int i=0 ; i < indices_n; ++i) {
210
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
203
211
output[i] = lhs[ indices[i] ];
204
212
}
205
213
SEXP names = Rf_getAttrib (lhs, R_NamesSymbol);
206
214
if (!Rf_isNull (names)) {
207
215
Shield<SEXP> out_names ( Rf_allocVector (STRSXP, indices_n) );
208
- for (int i=0 ; i < indices_n; ++i) {
216
+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
209
217
SET_STRING_ELT (out_names, i, STRING_ELT (names, indices[i]));
210
218
}
211
219
Rf_setAttrib (output, R_NamesSymbol, out_names);
@@ -216,13 +224,13 @@ class SubsetProxy {
216
224
217
225
LHS_t& lhs;
218
226
const RHS_t& rhs;
219
- int lhs_n;
220
- int rhs_n;
227
+ R_xlen_t lhs_n;
228
+ R_xlen_t rhs_n;
221
229
222
- std::vector<int > indices;
230
+ std::vector<R_xlen_t > indices;
223
231
224
232
// because of the above, we keep track of the size
225
- int indices_n;
233
+ R_xlen_t indices_n;
226
234
227
235
public:
228
236
@@ -234,10 +242,10 @@ class SubsetProxy {
234
242
RHS_NA_OTHER, RHS_T_OTHER>& other) { \
235
243
Vector<RTYPE, StoragePolicy> result (indices_n); \
236
244
if (other.indices_n == 1 ) { \
237
- for (int i = 0 ; i < indices_n; ++i) \
245
+ for (R_xlen_t i = 0 ; i < indices_n; ++i) \
238
246
result[i] = lhs[indices[i]] __OPERATOR__ other.lhs [other.indices [0 ]]; \
239
247
} else if (indices_n == other.indices_n ) { \
240
- for (int i = 0 ; i < indices_n; ++i) \
248
+ for (R_xlen_t i = 0 ; i < indices_n; ++i) \
241
249
result[i] = lhs[indices[i]] __OPERATOR__ other.lhs [other.indices [i]]; \
242
250
} else { \
243
251
stop (" index error" ); \
0 commit comments