2222#ifndef Rcpp_vector_Subsetter_h_
2323#define Rcpp_vector_Subsetter_h_
2424
25+ #include < limits>
26+
2527namespace Rcpp {
2628
2729template <
@@ -51,14 +53,14 @@ class SubsetProxy {
5153 // Enable e.g. x[y] = z
5254 template <int OtherRTYPE, template <class > class OtherStoragePolicy >
5355 SubsetProxy& operator =(const Vector<OtherRTYPE, OtherStoragePolicy>& other) {
54- int n = other.size ();
56+ R_xlen_t n = other.size ();
5557
5658 if (n == 1 ) {
57- for (int i=0 ; i < indices_n; ++i) {
59+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
5860 lhs[ indices[i] ] = other[0 ];
5961 }
6062 } else if (n == indices_n) {
61- for (int i=0 ; i < n; ++i) {
63+ for (R_xlen_t i=0 ; i < n; ++i) {
6264 lhs[ indices[i] ] = other[i];
6365 }
6466 } else {
@@ -70,28 +72,28 @@ class SubsetProxy {
7072 // Enable e.g. x[y] = 1;
7173 // TODO: std::enable_if<primitive> with C++11
7274 SubsetProxy& operator =(double other) {
73- for (int i=0 ; i < indices_n; ++i) {
75+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
7476 lhs[ indices[i] ] = other;
7577 }
7678 return *this ;
7779 }
7880
7981 SubsetProxy& operator =(int other) {
80- for (int i=0 ; i < indices_n; ++i) {
82+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
8183 lhs[ indices[i] ] = other;
8284 }
8385 return *this ;
8486 }
8587
8688 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) {
8890 lhs[ indices[i] ] = other;
8991 }
9092 return *this ;
9193 }
9294
9395 SubsetProxy& operator =(bool other) {
94- for (int i=0 ; i < indices_n; ++i) {
96+ for (R_xlen_t i=0 ; i < indices_n; ++i) {
9597 lhs[ indices[i] ] = other;
9698 }
9799 return *this ;
@@ -107,12 +109,12 @@ class SubsetProxy {
107109
108110 SubsetProxy& operator =(const SubsetProxy& other) {
109111 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) {
111113 lhs[ indices[i] ] = other.lhs [other.indices [0 ]];
112114 }
113115 }
114116 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)
116118 lhs[ indices[i] ] = other.lhs [other.indices [i]];
117119 }
118120 else {
@@ -132,34 +134,40 @@ class SubsetProxy {
132134private:
133135
134136 #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) {
137140 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+ }
138144 stop (" index error" );
139145 }
140146 }
141147 }
142148 #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) {}
144151 #endif
145152
146153 void get_indices ( traits::identity< traits::int2type<INTSXP> > t ) {
147154 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
149156 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) {
151158 indices.push_back ( rhs[i] );
152159 }
153160 indices_n = rhs_n;
154161 }
155162
156163 void get_indices ( traits::identity< traits::int2type<REALSXP> > t ) {
157164 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) {
163171 indices.push_back ( tmp[i] );
164172 }
165173 indices_n = rhs_n;
@@ -171,7 +179,7 @@ class SubsetProxy {
171179 if (Rf_isNull (names)) stop (" names is null" );
172180 SEXP* namesPtr = STRING_PTR (names);
173181 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) {
175183 SEXP* match = std::find (namesPtr, namesPtr + lhs_n, *(rhsPtr + i));
176184 if (match == namesPtr + lhs_n)
177185 stop (" not found" );
@@ -186,7 +194,7 @@ class SubsetProxy {
186194 stop (" logical subsetting requires vectors of identical size" );
187195 }
188196 int * ptr = LOGICAL (rhs);
189- for (int i=0 ; i < rhs_n; ++i) {
197+ for (R_xlen_t i=0 ; i < rhs_n; ++i) {
190198 if (ptr[i] == NA_INTEGER) {
191199 stop (" can't subset using a logical vector with NAs" );
192200 }
@@ -199,13 +207,13 @@ class SubsetProxy {
199207
200208 Vector<RTYPE, StoragePolicy> get_vec () const {
201209 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) {
203211 output[i] = lhs[ indices[i] ];
204212 }
205213 SEXP names = Rf_getAttrib (lhs, R_NamesSymbol);
206214 if (!Rf_isNull (names)) {
207215 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) {
209217 SET_STRING_ELT (out_names, i, STRING_ELT (names, indices[i]));
210218 }
211219 Rf_setAttrib (output, R_NamesSymbol, out_names);
@@ -216,13 +224,13 @@ class SubsetProxy {
216224
217225 LHS_t& lhs;
218226 const RHS_t& rhs;
219- int lhs_n;
220- int rhs_n;
227+ R_xlen_t lhs_n;
228+ R_xlen_t rhs_n;
221229
222- std::vector<int > indices;
230+ std::vector<R_xlen_t > indices;
223231
224232 // because of the above, we keep track of the size
225- int indices_n;
233+ R_xlen_t indices_n;
226234
227235public:
228236
@@ -234,10 +242,10 @@ class SubsetProxy {
234242 RHS_NA_OTHER, RHS_T_OTHER>& other) { \
235243 Vector<RTYPE, StoragePolicy> result (indices_n); \
236244 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) \
238246 result[i] = lhs[indices[i]] __OPERATOR__ other.lhs [other.indices [0 ]]; \
239247 } 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) \
241249 result[i] = lhs[indices[i]] __OPERATOR__ other.lhs [other.indices [i]]; \
242250 } else { \
243251 stop (" index error" ); \
0 commit comments