-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathVector.h
More file actions
278 lines (221 loc) · 9.74 KB
/
Vector.h
File metadata and controls
278 lines (221 loc) · 9.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#ifndef Rcpp__vector__Vector_h
#define Rcpp__vector__Vector_h
namespace Rcpp{
template <
int RTYPE,
template <class> class StoragePolicy
>
class Vector :
public StoragePolicy<Vector<RTYPE,StoragePolicy>>,
public SlotProxyPolicy<Vector<RTYPE,StoragePolicy>>,
public AttributeProxyPolicy<Vector<RTYPE,StoragePolicy>>,
public VectorBase< RTYPE, true, Vector<RTYPE,StoragePolicy> >,
public internal::eval_methods<RTYPE, StoragePolicy >,
public NamesProxyPolicy<Vector<RTYPE, StoragePolicy>>,
public AttributesProxyPolicy<Vector<RTYPE, StoragePolicy>>,
public RObjectMethods<Vector<RTYPE, StoragePolicy>>
{
public:
typedef typename traits::r_vector_proxy<RTYPE>::type Proxy ;
typedef typename traits::r_vector_const_proxy<RTYPE>::type const_Proxy ;
typedef typename traits::r_vector_name_proxy<RTYPE>::type NameProxy ;
typedef typename traits::r_vector_const_name_proxy<RTYPE>::type const_NameProxy ;
typedef typename traits::r_vector_proxy<RTYPE>::type value_type ;
typedef typename traits::r_vector_iterator<RTYPE>::type iterator ;
typedef typename traits::r_vector_const_iterator<RTYPE>::type const_iterator ;
typedef typename traits::init_type<RTYPE>::type init_type ;
typedef typename traits::r_vector_element_converter<RTYPE>::type converter_type ;
typedef typename traits::storage_type<RTYPE>::type stored_type ;
RCPP_GENERATE_CTOR_ASSIGN(Vector)
Vector( SEXP x ) {
Storage::set__( r_cast<RTYPE>( x ) ) ;
}
Vector( int n ) : Vector(Rf_allocVector(RTYPE, n) ) {}
Vector() : Vector(0) {}
template <typename U>
Vector( int n, const U& u ) : Vector(n) {
fill( u ) ;
}
Vector( const std::string& st ) : Vector( internal::vector_from_string<RTYPE>(st) ) {}
Vector( const char* st ) : Vector(internal::vector_from_string<RTYPE>(st)){}
template <bool NA, typename VEC>
Vector( const VectorBase<RTYPE,NA,VEC>& other ) ;
Vector( std::initializer_list<init_type> list ) {
Storage::set__( r_cast<RTYPE>( wrap( list.begin(), list.end() ) ) );
}
template <typename T> Vector&
operator=( const T& x) ;
static inline stored_type get_na() { return traits::get_na<RTYPE>(); }
static inline bool is_na( stored_type x){ return traits::is_na<RTYPE>(x); }
/**
* the length of the vector, uses Rf_length
*/
inline R_len_t length() const { return ::Rf_length( Storage::get__() ) ; }
/**
* alias of length
*/
inline R_len_t size() const { return ::Rf_length( Storage::get__() ) ; }
/**
* one dimensional offset doing bounds checking to ensure
* it is valid
*/
size_t offset(const size_t& i) const {
if( static_cast<R_len_t>(i) >= size() ) throw index_out_of_bounds() ;
return i ;
}
R_len_t offset(const std::string& name) const {
SEXP names = RCPP_GET_NAMES( Storage::get__() ) ;
if( names == R_NilValue ) throw index_out_of_bounds();
int n = size() ;
SEXP* data = internal::r_vector_start<STRSXP>(names) ;
int index = std::find( data, data+n, Rf_mkChar(name.c_str()) ) - data ;
if( index == n ) throw index_out_of_bounds() ;
return index ;
}
template <typename U>
void fill( const U& u){
fill__dispatch( typename traits::is_trivial<RTYPE>::type(), u ) ;
}
inline iterator begin() { return get_iterator(0) ; }
inline iterator end() { return get_iterator(size()) ; }
inline const_iterator begin() const{ return get_const_iterator(0) ; }
inline const_iterator end() const{ return get_const_iterator(size()) ; }
inline Proxy operator[](int i){ return get_Proxy(i) ;}
inline const_Proxy operator[](int i) const { return get_constProxy(i); }
inline NameProxy operator[]( const std::string& name ){
return NameProxy( *this, name ) ;
}
inline const_NameProxy operator[]( const std::string& name ) const {
return const_NameProxy( *this, name ) ;
}
template <typename T>
void push_back( const T& object){
push_back__impl( converter_type::get(object),
typename std::is_same<stored_type,SEXP>()
) ;
}
template <typename T>
void push_back( const T& object, const std::string& name ){
push_back_name__impl( converter_type::get(object), name,
typename std::is_same<stored_type,SEXP>()
) ;
}
template <typename T>
void push_front( const T& object){
push_front__impl( converter_type::get(object),
typename std::is_same<stored_type,SEXP>() ) ;
}
template <typename T>
void push_front( const T& object, const std::string& name){
push_front_name__impl( converter_type::get(object), name,
typename std::is_same<stored_type,SEXP>() ) ;
}
public:
template <typename T>
iterator insert( iterator position, const T& object) ;
template <typename T>
iterator insert( int position, const T& object){
return insert(get_iterator(position),object);
}
iterator erase( int position){
return erase_single__impl( get_iterator(position) ) ;
}
iterator erase( iterator position){
return erase_single__impl( position ) ;
}
iterator erase( int first, int last){
return erase_range__impl( get_iterator(first), get_iterator(last) ) ;
}
iterator erase( iterator first, iterator last){
return erase_range__impl( first, last ) ;
}
template <typename EXPR_VEC>
Vector& operator+=( const VectorBase<RTYPE,true,EXPR_VEC>& rhs ) ;
template <typename EXPR_VEC>
Vector& operator+=( const VectorBase<RTYPE,false,EXPR_VEC>& rhs ) ;
private:
void push_back__impl(const stored_type& object, std::true_type ) ;
void push_back__impl(const stored_type& object, std::false_type ) ;
void push_back_name__impl(const stored_type& object, const std::string& name, std::true_type ) ;
void push_back_name__impl(const stored_type& object, const std::string& name, std::false_type ) ;
void push_front__impl(const stored_type& object, std::true_type ) ;
void push_front__impl(const stored_type& object, std::false_type ) ;
void push_front_name__impl(const stored_type& object, const std::string& name, std::true_type ) ;
void push_front_name__impl(const stored_type& object, const std::string& name, std::false_type ) ;
iterator erase_single__impl( iterator position ) ;
iterator erase_range__impl( iterator first, iterator last ) ;
template <bool NA, typename T> inline void assign_sugar_expression( const VectorBase<RTYPE,NA,T>& x ) ;
// sugar
template <typename T> inline void assign_object( const T& x, std::true_type ) ;
// anything else
template <typename T> inline void assign_object( const T& x, std::false_type ) ;
// we are importing a real sugar expression, i.e. not a vector
template <bool NA, typename VEC>
inline void import_sugar_expression( const Rcpp::VectorBase<RTYPE,NA,VEC>& other, std::false_type ) ;
// we are importing a sugar expression that actually is a vector
template <bool NA, typename VEC>
inline void import_sugar_expression( const Rcpp::VectorBase<RTYPE,NA,VEC>& other, std::true_type ) ;
template <typename T>
inline void import_expression( const T& other, int n ) ;
template <typename U>
void fill__dispatch( std::false_type, const U& u){
// when this is not trivial, this is SEXP
Shield<SEXP> elem = converter_type::get( u );
iterator it(begin());
for( int i=0; i<size() ; i++, ++it){
*it = ::Rf_duplicate( elem ) ;
}
}
template <typename U>
void fill__dispatch( std::true_type, const U& u){
std::fill( begin(), end(), converter_type::get( u ) ) ;
}
public:
template <typename... Args> static Vector create(Args... args) ;
private:
inline stored_type* data(){
return reinterpret_cast<stored_type*>( DATAPTR(Storage::get__()) );
}
inline const stored_type* data() const{
return reinterpret_cast<const stored_type*>( DATAPTR(Storage::get__()) );
}
// dispatch between simple vectors and proxy based vectors
inline Proxy get_Proxy(int i){
return get_Proxy__impl( i, typename std::is_reference<Proxy>::type() ) ;
}
inline Proxy get_Proxy__impl( int i, std::true_type ){
return *( data() + i ) ;
}
inline Proxy get_Proxy__impl( int i, std::false_type ){
return Proxy( *this, i ) ;
}
inline const_Proxy get_constProxy(int i) const {
return get_constProxy__impl( i, typename std::is_reference<const_Proxy>::type() ) ;
}
inline const_Proxy get_constProxy__impl( int i, std::true_type ) const {
return *( data() + i ) ;
}
inline const_Proxy get_constProxy__impl( int i, std::false_type ) const {
return const_Proxy( *this, i ) ;
}
inline iterator get_iterator(int i){
return get_iterator__impl(i, typename std::is_pointer<iterator>::type() );
}
inline iterator get_iterator__impl(int i, std::true_type ){
return data() + i ;
}
inline iterator get_iterator__impl(int i, std::false_type ){
return iterator( Proxy(*this, i) );
}
inline const_iterator get_const_iterator(int i) const {
return get_const_iterator__impl(i, typename std::is_pointer<const_iterator>::type() );
}
inline const_iterator get_const_iterator__impl(int i, std::true_type ) const {
return data() + i ;
}
inline const_iterator get_const_iterator__impl(int i, std::false_type ) const {
return const_iterator( const_Proxy(*this, i) );
}
} ; /* Vector */
}
#endif