@@ -37,29 +37,27 @@ class SubsetProxy {
3737
3838 SubsetProxy (LHS_t& lhs_, const RHS_t& rhs_):
3939 lhs (lhs_), rhs(rhs_), lhs_n(lhs.size()), rhs_n(rhs.size()) {
40-
41- indices.reserve (rhs_n);
4240 get_indices ( traits::identity< traits::int2type<RHS_RTYPE> >() );
43-
4441 }
4542
4643 SubsetProxy (const SubsetProxy& other):
4744 lhs (other.lhs),
4845 rhs (other.rhs),
4946 lhs_n (other.lhs_n),
5047 rhs_n (other.rhs_n),
51- indices (other.indices) {}
48+ indices (other.indices),
49+ indices_n (other.indices_n) {}
5250
5351 // Enable e.g. x[y] = z
5452 template <int OtherRTYPE, template <class > class OtherStoragePolicy >
5553 SubsetProxy& operator =(const Vector<OtherRTYPE, OtherStoragePolicy>& other) {
5654 int n = other.size ();
57- if (indices. size () != n) stop (" index error" );
55+ if (indices_n != n) stop (" index error" );
5856 if (n == 1 ) {
5957 for (int i=0 ; i < n; ++i) {
6058 lhs[ indices[i] ] = other[0 ];
6159 }
62- } else if (n == indices. size () ) {
60+ } else if (n == indices_n ) {
6361 for (int i=0 ; i < n; ++i) {
6462 lhs[ indices[i] ] = other[i];
6563 }
@@ -72,32 +70,28 @@ class SubsetProxy {
7270 // Enable e.g. x[y] = 1;
7371 // TODO: std::enable_if<primitive> with C++11
7472 SubsetProxy& operator =(double other) {
75- int n = indices.size ();
76- for (int i=0 ; i < n; ++i) {
73+ for (int i=0 ; i < indices_n; ++i) {
7774 lhs[ indices[i] ] = other;
7875 }
7976 return *this ;
8077 }
8178
8279 SubsetProxy& operator =(int other) {
83- int n = indices.size ();
84- for (int i=0 ; i < n; ++i) {
80+ for (int i=0 ; i < indices_n; ++i) {
8581 lhs[ indices[i] ] = other;
8682 }
8783 return *this ;
8884 }
8985
9086 SubsetProxy& operator =(const char * other) {
91- int n = indices.size ();
92- for (int i=0 ; i < n; ++i) {
87+ for (int i=0 ; i < indices_n; ++i) {
9388 lhs[ indices[i] ] = other;
9489 }
9590 return *this ;
9691 }
9792
9893 SubsetProxy& operator =(bool other) {
99- int n = indices.size ();
100- for (int i=0 ; i < n; ++i) {
94+ for (int i=0 ; i < indices_n; ++i) {
10195 lhs[ indices[i] ] = other;
10296 }
10397 return *this ;
@@ -126,29 +120,31 @@ class SubsetProxy {
126120 #endif
127121
128122 void get_indices ( traits::identity< traits::int2type<INTSXP> > t ) {
129- int * ptr = INTEGER ( rhs );
130- check_indices (ptr, rhs_n, lhs_n);
131- for (int i=0 ; i < rhs_n; ++i) {
132- indices.push_back ( ptr[i] );
133- }
123+ indices = INTEGER (rhs);
124+ indices_n = rhs_n;
125+ check_indices (indices, rhs_n, lhs_n);
134126 }
135127
136128 void get_indices ( traits::identity< traits::int2type<REALSXP> > t ) {
129+ indices.reserve (rhs_n);
137130 Vector<INTSXP, StoragePolicy> tmp =
138131 as< Vector<INTSXP, StoragePolicy> >(rhs);
139132 int * ptr = INTEGER (tmp);
140133 check_indices (ptr, rhs_n, lhs_n);
141134 for (int i=0 ; i < rhs_n; ++i) {
142135 indices.push_back ( tmp[i] );
143136 }
137+ indices_n = rhs_n;
144138 }
145139
146140 void get_indices ( traits::identity< traits::int2type<STRSXP> > t ) {
141+ indices.reserve (rhs_n);
147142 SEXP names = Rf_getAttrib (lhs, R_NamesSymbol);
148143 if (Rf_isNull (names)) stop (" names is null" );
149144 for (int i=0 ; i < rhs_n; ++i) {
150145 indices.push_back ( find (names, CHAR ( STRING_ELT (rhs, i) )) );
151146 }
147+ indices_n = indices.size ();
152148 }
153149
154150 int find (const RHS_t& names, const char * str) {
@@ -160,6 +156,7 @@ class SubsetProxy {
160156 }
161157
162158 void get_indices ( traits::identity< traits::int2type<LGLSXP> > t ) {
159+ indices.reserve (rhs_n);
163160 if (lhs_n != rhs_n) {
164161 stop (" logical subsetting requires vectors of identical size" );
165162 }
@@ -172,18 +169,18 @@ class SubsetProxy {
172169 indices.push_back (i);
173170 }
174171 }
172+ indices_n = indices.size ();
175173 }
176174
177175 Vector<RTYPE, StoragePolicy> get_vec () const {
178- int n = indices.size ();
179- Vector<RTYPE, StoragePolicy> output = no_init (n);
180- for (int i=0 ; i < n; ++i) {
176+ Vector<RTYPE, StoragePolicy> output = no_init (indices_n);
177+ for (int i=0 ; i < indices_n; ++i) {
181178 output[i] = lhs[ indices[i] ];
182179 }
183180 SEXP names = Rf_getAttrib (lhs, R_NamesSymbol);
184181 if (!Rf_isNull (names)) {
185- Shield<SEXP> out_names ( Rf_allocVector (STRSXP, n ) );
186- for (int i=0 ; i < n ; ++i) {
182+ Shield<SEXP> out_names ( Rf_allocVector (STRSXP, indices_n ) );
183+ for (int i=0 ; i < indices_n ; ++i) {
187184 SET_STRING_ELT (out_names, i, STRING_ELT (names, indices[i]));
188185 }
189186 Rf_setAttrib (output, R_NamesSymbol, out_names);
@@ -196,7 +193,17 @@ class SubsetProxy {
196193 const RHS_t& rhs;
197194 int lhs_n;
198195 int rhs_n;
199- std::vector<int > indices;
196+
197+ // we want to reuse the indices if an IntegerVector is passed in; otherwise,
198+ // we construct a std::vector<int> to hold the indices
199+ typename traits::if_<
200+ RHS_RTYPE == INTSXP,
201+ int *,
202+ std::vector<int >
203+ >::type indices;
204+
205+ // because of the above, we keep track of the size
206+ int indices_n;
200207
201208};
202209
0 commit comments