Rcpp Version 0.10.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
Vector.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // Vector.h: Rcpp R/C++ interface class library -- vectors
4 //
5 // Copyright (C) 2010 - 2012 Dirk Eddelbuettel and Romain Francois
6 //
7 // This file is part of Rcpp.
8 //
9 // Rcpp is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Rcpp is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21 
22 #ifndef Rcpp__vector__Vector_h
23 #define Rcpp__vector__Vector_h
24 
25 // forward declarations
26 class Dimension ;
27 
28 template <bool NA,typename T> class SingleLogicalResult ;
29 
30 template <int RTYPE>
31 class Vector :
32  public RObject,
33  public VectorBase< RTYPE, true, Vector<RTYPE> >,
34  public internal::eval_methods<RTYPE>
35 {
37 
38 public:
45  typedef typename traits::init_type<RTYPE>::type init_type ;
47  typedef typename traits::storage_type<RTYPE>::type stored_type ;
48 
53  Vector() ;
54 
58  ~Vector() ;
59 
63  Vector( const Vector& other) ;
64 
65 
66  // we can't define these 3 in meat for some reason
67  // maybe because of the typedef in instantiation.h
68  Vector( SEXP x ) : RObject( r_cast<RTYPE>( x ) ) {
69  RCPP_DEBUG_2( "Vector<%d>( SEXP = <%p> )", RTYPE, x)
70  update_vector() ;
71  }
72  Vector( const RObject::SlotProxy& proxy ) : RObject( r_cast<RTYPE>( (SEXP)proxy ) ) {
73  RCPP_DEBUG_2( "Vector<%d>( const RObject::SlotProxy& proxy = <%p> )", RTYPE, m_sexp)
74  update_vector() ;
75  }
76 
77  Vector( const RObject::AttributeProxy& proxy ) : RObject( r_cast<RTYPE>( (SEXP)proxy ) ) {
78  RCPP_DEBUG_2( "Vector<%d>( const RObject::AttributeProxy& proxy = <%p> )", RTYPE, m_sexp)
79  update_vector() ;
80  }
81  Vector( const int& size, const stored_type& u ) : RObject( Rf_allocVector( RTYPE, size) ) {
82  RCPP_DEBUG_2( "Vector<%d>( const int& size = %d, const stored_type& u )", RTYPE, size)
83  update_vector() ;
84  fill( u ) ;
85  }
86  Vector( const std::string& st ) : RObject( internal::vector_from_string<RTYPE>(st) ){
87  RCPP_DEBUG_2( "Vector<%d>( const std::string& = %s )", RTYPE, st.c_str() )
88  update_vector();
89  }
90  Vector( const int& siz, stored_type (*gen)(void) ) : RObject(Rf_allocVector( RTYPE, siz)) {
91  RCPP_DEBUG_2( "Vector<%d>( const int& siz = %s, stored_type (*gen)(void) )", RTYPE, siz )
92  update_vector() ;
93  iterator first = begin(), last = end() ;
94  while( first != last ) *first++ = gen() ;
95  }
96 
97  Vector( const int& size ) ;
98  Vector( const Dimension& dims) ;
99  template <typename U> Vector( const Dimension& dims, const U& u) ;
100  template <bool NA, typename VEC> Vector( const VectorBase<RTYPE,NA,VEC>& other ) ;
101  template <typename U> Vector( const int& size, const U& u) ;
102  template <bool NA, typename T> Vector( const sugar::SingleLogicalResult<NA,T>& obj ) ;
103 
104  template <typename U1>
105  Vector( const int& siz, stored_type (*gen)(U1), const U1& u1) ;
106 
107  template <typename U1, typename U2>
108  Vector( const int& siz, stored_type (*gen)(U1,U2), const U1& u1, const U2& u2) ;
109 
110  template <typename U1, typename U2, typename U3>
111  Vector( const int& siz, stored_type (*gen)(U1,U2,U3), const U1& u1, const U2& u2, const U3& u3) ;
112 
113  template <typename InputIterator>
114  Vector( InputIterator first, InputIterator last) ;
115 
116  template <typename InputIterator>
117  Vector( InputIterator first, InputIterator last, int n) ;
118 
119  template <typename InputIterator, typename Func>
120  Vector( InputIterator first, InputIterator last, Func func) ;
121 
122  template <typename InputIterator, typename Func>
123  Vector( InputIterator first, InputIterator last, Func func, int n) ;
124 
125 #ifdef HAS_CXX0X_INITIALIZER_LIST
126  Vector( std::initializer_list<init_type> list ) : RObject(){
127  assign( list.begin() , list.end() ) ;
128  }
129 #endif
130 
131 
135  Vector& operator=( const Vector& other ) ;
136  template <typename T> Vector& operator=( const T& x) ;
137 
138 
139  static inline stored_type get_na() { return traits::get_na<RTYPE>(); }
140  static inline bool is_na( stored_type x){ return traits::is_na<RTYPE>(x); }
141 
142  internal::ListInitialization<iterator,init_type> operator=( init_type x){
143  iterator start = begin() ; *start = x;
144  return internal::ListInitialization<iterator,init_type>( start + 1 ) ; ;
145  }
146 
147 
151  inline R_len_t length() const { return ::Rf_length( RObject::m_sexp ) ; }
152 
156  inline R_len_t size() const { return ::Rf_length( RObject::m_sexp ) ; }
157 
161  size_t offset(const size_t& i, const size_t& j) const {
162  if( !::Rf_isMatrix(RObject::m_sexp) ) throw not_a_matrix() ;
163  /* we need to extract the dimensions */
164  int *dim = dims() ;
165  size_t nrow = static_cast<size_t>(dim[0]) ;
166  size_t ncol = static_cast<size_t>(dim[1]) ;
167  if( i >= nrow || j >= ncol ) throw index_out_of_bounds() ;
168  return i + nrow*j ;
169  }
170 
175  size_t offset(const size_t& i) const {
176  if( static_cast<R_len_t>(i) >= ::Rf_length(RObject::m_sexp) ) throw index_out_of_bounds() ;
177  return i ;
178  }
179 
180  R_len_t offset(const std::string& name) const {
181  SEXP names = RCPP_GET_NAMES( RObject::m_sexp ) ;
182  if( names == R_NilValue ) throw index_out_of_bounds();
183  R_len_t n=size() ;
184  for( R_len_t i=0; i<n; ++i){
185  if( ! name.compare( CHAR(STRING_ELT(names, i)) ) ){
186  return i ;
187  }
188  }
189  throw index_out_of_bounds() ;
190  return -1 ; /* -Wall */
191  }
192 
193  template <typename U>
194  void fill( const U& u){
195  fill__dispatch( typename traits::is_trivial<RTYPE>::type(), u ) ;
196  }
197 
198 
199  /* TODO: 3 dimensions, ... n dimensions through variadic templates */
200 
201  class NamesProxy {
202  public:
203  NamesProxy( const Vector& v) : parent(v){} ;
204 
205  /* lvalue uses */
207  set( rhs.get() ) ;
208  return *this ;
209  }
210 
211  template <typename T>
212  NamesProxy& operator=(const T& rhs){
213  set( wrap(rhs) ) ;
214  return *this ;
215  }
216 
217  template <typename T> operator T() const {
218  return Rcpp::as<T>(get()) ;
219  }
220 
221  private:
222  const Vector& parent;
223 
224  SEXP get() const {
225  return RCPP_GET_NAMES(parent) ;
226  }
227 
228  void set(SEXP x) const {
229 
230  /* check if we can use a fast version */
231  if( TYPEOF(x) == STRSXP && parent.size() == Rf_length(x) ){
232  SEXP y = const_cast<Vector&>(parent).asSexp() ;
233  Rf_setAttrib( y, R_NamesSymbol, x ) ;
234  } else {
235  /* use the slower and more flexible version (callback to R) */
236  SEXP namesSym = Rf_install( "names<-" );
237  SEXP new_vec = PROTECT( internal::try_catch(Rf_lang3( namesSym, parent, x ))) ;
238  /* names<- makes a new vector, so we have to change
239  the SEXP of the parent of this proxy */
240  const_cast<Vector&>(parent).set_sexp( new_vec ) ;
241  UNPROTECT(1) ; /* new_vec */
242  }
243 
244  }
245 
246  } ;
247 
248  NamesProxy names() const {
249  return NamesProxy(*this) ;
250  }
251 
252  inline iterator begin() { return cache.get() ; }
253  inline iterator end() { return cache.get() + size() ; }
254  inline const_iterator begin() const{ return cache.get_const() ; }
255  inline const_iterator end() const{ return cache.get_const() + size() ; }
256 
257  inline Proxy operator[]( int i ){ return cache.ref(i) ; }
258  inline const_Proxy operator[]( int i ) const { return cache.ref(i) ; }
259 
260  inline Proxy operator()( const size_t& i) {
261  return cache.ref( offset(i) ) ;
262  }
263  inline const_Proxy operator()( const size_t& i) const {
264  return cache.ref( offset(i) ) ;
265  }
266 
267  inline Proxy operator()( const size_t& i, const size_t& j) {
268  return cache.ref( offset(i,j) ) ;
269  }
270  inline const_Proxy operator()( const size_t& i, const size_t& j) const {
271  return cache.ref( offset(i,j) ) ;
272  }
273 
274  inline NameProxy operator[]( const std::string& name ){
275  return NameProxy( *this, name ) ;
276  }
277  inline NameProxy operator()( const std::string& name ){
278  return NameProxy( *this, name ) ;
279  }
280 
281  inline NameProxy operator[]( const std::string& name ) const {
282  return NameProxy( const_cast<Vector&>(*this), name ) ;
283  }
284  inline NameProxy operator()( const std::string& name ) const {
285  return NameProxy( const_cast<Vector&>(*this), name ) ;
286  }
287 
289  std::sort(
290  internal::r_vector_start<RTYPE>(m_sexp),
291  internal::r_vector_start<RTYPE>(m_sexp) + size(),
292  typename traits::comparator_type<RTYPE>::type()
293  ) ;
294  return *this ;
295  }
296 
297  template <typename InputIterator>
298  void assign( InputIterator first, InputIterator last){
299  /* FIXME: we can do better than this r_cast to avoid
300  allocating an unnecessary temporary object
301  */
302  SEXP x = PROTECT( r_cast<RTYPE>( wrap( first, last ) ) );
303  RObject::setSEXP( x) ;
304  UNPROTECT(1) ;
305  }
306 
307  template <typename InputIterator>
308  static Vector import( InputIterator first, InputIterator last){
309  Vector v ;
310  v.assign( first , last ) ;
311  return v ;
312  }
313 
314  template <typename InputIterator, typename F>
315  static Vector import_transform( InputIterator first, InputIterator last, F f){
316  return Vector( first, last, f) ;
317  }
318 
319  template <typename T>
320  void push_back( const T& object){
321  push_back__impl( converter_type::get(object),
322  typename traits::same_type<stored_type,SEXP>()
323  ) ;
324  }
325 
326  template <typename T>
327  void push_back( const T& object, const std::string& name ){
328  push_back_name__impl( converter_type::get(object), name,
329  typename traits::same_type<stored_type,SEXP>()
330  ) ;
331  }
332 
333  template <typename T>
334  void push_front( const T& object){
335  push_front__impl( converter_type::get(object),
336  typename traits::same_type<stored_type,SEXP>() ) ;
337  }
338 
339  template <typename T>
340  void push_front( const T& object, const std::string& name){
341  push_front_name__impl( converter_type::get(object), name,
342  typename traits::same_type<stored_type,SEXP>() ) ;
343  }
344 
345 
346  template <typename T>
347  iterator insert( iterator position, const T& object){
348  return insert__impl( position, converter_type::get(object),
349  typename traits::same_type<stored_type,SEXP>()
350  ) ;
351  }
352 
353  template <typename T>
354  iterator insert( int position, const T& object){
355  return insert__impl( cache.get() + position, converter_type::get(object),
356  typename traits::same_type<stored_type,SEXP>()
357  );
358  }
359 
360  iterator erase( int position){
361  return erase_single__impl( cache.get() + position) ;
362  }
363 
364  iterator erase( iterator position){
365  return erase_single__impl( position ) ;
366  }
367 
368  iterator erase( int first, int last){
369  iterator start = cache.get() ;
370  return erase_range__impl( start + first, start + last ) ;
371  }
372 
374  return erase_range__impl( first, last ) ;
375  }
376 
378  RCPP_DEBUG_2( " update_vector( VECTOR = %s, SEXP = < %p > )", DEMANGLE(Vector), reinterpret_cast<void*>( RObject::asSexp() ) )
379  cache.update(*this) ;
380  }
381 
382  template <typename U>
383  static void replace_element( iterator it, SEXP names, int index, const U& u){
384  replace_element__dispatch( typename traits::is_named<U>::type(),
385  it, names, index, u ) ;
386  }
387 
388  template <typename U>
389  static void replace_element__dispatch( traits::false_type, iterator it, SEXP names, int index, const U& u){
390  *it = converter_type::get(u);
391  }
392 
393  template <typename U>
394  static void replace_element__dispatch( traits::true_type, iterator it, SEXP names, int index, const U& u){
395  replace_element__dispatch__isArgument( typename traits::same_type<U,Argument>(), it, names, index, u ) ;
396  }
397 
398  template <typename U>
399  static void replace_element__dispatch__isArgument( traits::false_type, iterator it, SEXP names, int index, const U& u){
400  RCPP_DEBUG_2( " Vector::replace_element__dispatch<%s>(true, index= %d) ", DEMANGLE(U), index ) ;
401 
402  *it = converter_type::get(u.object ) ;
403  SET_STRING_ELT( names, index, ::Rf_mkChar( u.name.c_str() ) ) ;
404  }
405 
406  template <typename U>
407  static void replace_element__dispatch__isArgument( traits::true_type, iterator it, SEXP names, int index, const U& u){
408  RCPP_DEBUG_2( " Vector::replace_element__dispatch<%s>(true, index= %d) ", DEMANGLE(U), index ) ;
409 
410  *it = R_MissingArg ;
411  SET_STRING_ELT( names, index, ::Rf_mkChar( u.name.c_str() ) ) ;
412  }
413 
414  void set_sexp(SEXP x){
415  RObject::setSEXP( x) ;
416  update_vector() ;
417  }
419 
420  inline Indexer operator[]( const Range& range ){
421  return Indexer( const_cast<Vector&>(*this), range );
422  }
423 
424  template <typename EXPR_VEC>
426 
427  template <typename EXPR_VEC>
429 
433  bool containsElementNamed( const char* target ) const ;
434 
435 
436 protected:
437  inline int* dims() const {
438  if( !::Rf_isMatrix(RObject::m_sexp) ) throw not_a_matrix() ;
439  return INTEGER( ::Rf_getAttrib( RObject::m_sexp, R_DimSymbol ) ) ;
440  }
441  void init(){
442  RCPP_DEBUG_2( "VECTOR<%d>::init( SEXP = <%p> )", RTYPE, RObject::m_sexp )
443  internal::r_init_vector<RTYPE>(RObject::m_sexp) ;
444  }
445 
446 private:
447 
448  void push_back__impl(const stored_type& object, traits::true_type ) ;
449  void push_back__impl(const stored_type& object, traits::false_type ) ;
450 
451  void push_back_name__impl(const stored_type& object, const std::string& name, traits::true_type ) ;
452  void push_back_name__impl(const stored_type& object, const std::string& name, traits::false_type ) ;
453 
454  void push_front__impl(const stored_type& object, traits::true_type ) ;
455  void push_front__impl(const stored_type& object, traits::false_type ) ;
456 
457  void push_front_name__impl(const stored_type& object, const std::string& name, traits::true_type ) ;
458  void push_front_name__impl(const stored_type& object, const std::string& name, traits::false_type ) ;
459 
460  iterator insert__impl( iterator position, const stored_type& object, traits::true_type ) ;
461  iterator insert__impl( iterator position, const stored_type& object, traits::false_type ) ;
462 
463  iterator erase_single__impl( iterator position ) ;
464 
466 
467  template <typename T> inline void assign_sugar_expression( const T& x ) ;
468 
469  // sugar
470  template <typename T> inline void assign_object( const T& x, traits::true_type ) ;
471 
472  // anything else
473  template <typename T> inline void assign_object( const T& x, traits::false_type ) ;
474 
475  // we are importing a real sugar expression, i.e. not a vector
476  template <bool NA, typename VEC>
478 
479  // we are importing a sugar expression that actually is a vector
480  template <bool NA, typename VEC>
482 
483 
484  template <typename T>
485  inline void import_expression( const T& other, int n ) ;
486 
487  template <typename T>
488  inline void fill_or_generate( const T& t) ;
489 
490  template <typename T>
491  inline void fill_or_generate__impl( const T& gen, traits::true_type) ;
492 
493  template <typename T>
494  inline void fill_or_generate__impl( const T& t, traits::false_type) ;
495 
496  template <typename U>
497  void fill_dispatch( traits::false_type, const U& u){
498  // when this is not trivial, this is SEXP
499  SEXP elem = PROTECT( converter_type::get( u ) );
500  iterator it(begin());
501  for( int i=0; i<size() ; i++, ++it){
502  *it = ::Rf_duplicate( elem ) ;
503  }
504  UNPROTECT(1) ; /* elem */
505  }
506 
507  template <typename U>
508  void fill__dispatch( traits::true_type, const U& u){
509  std::fill( begin(), end(), converter_type::get( u ) ) ;
510  }
511 
512 public:
513 
514  static Vector create(){
515  return Vector( 0 ) ;
516  }
517 
518  #include <Rcpp/generated/Vector__create.h>
519 
520 } ; /* Vector */
521 
522 #endif