@@ -37,29 +37,27 @@ class SubsetProxy {
37
37
38
38
SubsetProxy (LHS_t& lhs_, const RHS_t& rhs_):
39
39
lhs (lhs_), rhs(rhs_), lhs_n(lhs.size()), rhs_n(rhs.size()) {
40
-
41
- indices.reserve (rhs_n);
42
40
get_indices ( traits::identity< traits::int2type<RHS_RTYPE> >() );
43
-
44
41
}
45
42
46
43
SubsetProxy (const SubsetProxy& other):
47
44
lhs (other.lhs),
48
45
rhs (other.rhs),
49
46
lhs_n (other.lhs_n),
50
47
rhs_n (other.rhs_n),
51
- indices (other.indices) {}
48
+ indices (other.indices),
49
+ indices_n (other.indices_n) {}
52
50
53
51
// Enable e.g. x[y] = z
54
52
template <int OtherRTYPE, template <class > class OtherStoragePolicy >
55
53
SubsetProxy& operator =(const Vector<OtherRTYPE, OtherStoragePolicy>& other) {
56
54
int n = other.size ();
57
- if (indices. size () != n) stop (" index error" );
55
+ if (indices_n != n) stop (" index error" );
58
56
if (n == 1 ) {
59
57
for (int i=0 ; i < n; ++i) {
60
58
lhs[ indices[i] ] = other[0 ];
61
59
}
62
- } else if (n == indices. size () ) {
60
+ } else if (n == indices_n ) {
63
61
for (int i=0 ; i < n; ++i) {
64
62
lhs[ indices[i] ] = other[i];
65
63
}
@@ -72,32 +70,28 @@ class SubsetProxy {
72
70
// Enable e.g. x[y] = 1;
73
71
// TODO: std::enable_if<primitive> with C++11
74
72
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) {
77
74
lhs[ indices[i] ] = other;
78
75
}
79
76
return *this ;
80
77
}
81
78
82
79
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) {
85
81
lhs[ indices[i] ] = other;
86
82
}
87
83
return *this ;
88
84
}
89
85
90
86
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) {
93
88
lhs[ indices[i] ] = other;
94
89
}
95
90
return *this ;
96
91
}
97
92
98
93
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) {
101
95
lhs[ indices[i] ] = other;
102
96
}
103
97
return *this ;
@@ -126,29 +120,31 @@ class SubsetProxy {
126
120
#endif
127
121
128
122
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);
134
126
}
135
127
136
128
void get_indices ( traits::identity< traits::int2type<REALSXP> > t ) {
129
+ indices.reserve (rhs_n);
137
130
Vector<INTSXP, StoragePolicy> tmp =
138
131
as< Vector<INTSXP, StoragePolicy> >(rhs);
139
132
int * ptr = INTEGER (tmp);
140
133
check_indices (ptr, rhs_n, lhs_n);
141
134
for (int i=0 ; i < rhs_n; ++i) {
142
135
indices.push_back ( tmp[i] );
143
136
}
137
+ indices_n = rhs_n;
144
138
}
145
139
146
140
void get_indices ( traits::identity< traits::int2type<STRSXP> > t ) {
141
+ indices.reserve (rhs_n);
147
142
SEXP names = Rf_getAttrib (lhs, R_NamesSymbol);
148
143
if (Rf_isNull (names)) stop (" names is null" );
149
144
for (int i=0 ; i < rhs_n; ++i) {
150
145
indices.push_back ( find (names, CHAR ( STRING_ELT (rhs, i) )) );
151
146
}
147
+ indices_n = indices.size ();
152
148
}
153
149
154
150
int find (const RHS_t& names, const char * str) {
@@ -160,6 +156,7 @@ class SubsetProxy {
160
156
}
161
157
162
158
void get_indices ( traits::identity< traits::int2type<LGLSXP> > t ) {
159
+ indices.reserve (rhs_n);
163
160
if (lhs_n != rhs_n) {
164
161
stop (" logical subsetting requires vectors of identical size" );
165
162
}
@@ -172,18 +169,18 @@ class SubsetProxy {
172
169
indices.push_back (i);
173
170
}
174
171
}
172
+ indices_n = indices.size ();
175
173
}
176
174
177
175
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) {
181
178
output[i] = lhs[ indices[i] ];
182
179
}
183
180
SEXP names = Rf_getAttrib (lhs, R_NamesSymbol);
184
181
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) {
187
184
SET_STRING_ELT (out_names, i, STRING_ELT (names, indices[i]));
188
185
}
189
186
Rf_setAttrib (output, R_NamesSymbol, out_names);
@@ -196,7 +193,17 @@ class SubsetProxy {
196
193
const RHS_t& rhs;
197
194
int lhs_n;
198
195
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;
200
207
201
208
};
202
209
0 commit comments