1 // 2 // Vector.h: Rcpp R/C++ interface class library -- vectors 3 // 4 // Copyright (C) 2010 - 2020 Dirk Eddelbuettel and Romain Francois 5 // 6 // This file is part of Rcpp. 7 // 8 // Rcpp is free software: you can redistribute it and/or modify it 9 // under the terms of the GNU General Public License as published by 10 // the Free Software Foundation, either version 2 of the License, or 11 // (at your option) any later version. 12 // 13 // Rcpp is distributed in the hope that it will be useful, but 14 // WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 // 18 // You should have received a copy of the GNU General Public License 19 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 20 21 #ifndef Rcpp__vector__Vector_h 22 #define Rcpp__vector__Vector_h 23 24 #include <Rcpp/vector/Subsetter.h> 25 26 namespace Rcpp{ 27 28 template <int RTYPE, template <class> class StoragePolicy = PreserveStorage > 29 class Vector : 30 public StoragePolicy< Vector<RTYPE,StoragePolicy> >, 31 public SlotProxyPolicy< Vector<RTYPE,StoragePolicy> >, 32 public AttributeProxyPolicy< Vector<RTYPE,StoragePolicy> >, 33 public NamesProxyPolicy< Vector<RTYPE, StoragePolicy> >, 34 public RObjectMethods< Vector<RTYPE, StoragePolicy> >, 35 public VectorBase< RTYPE, true, Vector<RTYPE,StoragePolicy> > 36 { 37 public: 38 39 typedef StoragePolicy<Vector> Storage ; 40 41 typename traits::r_vector_cache_type<RTYPE, StoragePolicy>::type cache ; 42 typedef typename traits::r_vector_proxy<RTYPE, StoragePolicy>::type Proxy ; 43 typedef typename traits::r_vector_const_proxy<RTYPE, StoragePolicy>::type const_Proxy ; 44 typedef typename traits::r_vector_name_proxy<RTYPE, StoragePolicy>::type NameProxy ; 45 typedef typename traits::r_vector_proxy<RTYPE, StoragePolicy>::type value_type ; 46 typedef typename traits::r_vector_iterator<RTYPE, StoragePolicy>::type iterator ; 47 typedef typename traits::r_vector_const_iterator<RTYPE, StoragePolicy>::type const_iterator ; 48 typedef typename traits::init_type<RTYPE>::type init_type ; 49 typedef typename traits::r_vector_element_converter<RTYPE>::type converter_type ; 50 typedef typename traits::storage_type<RTYPE>::type stored_type ; 51 52 /** 53 * Default constructor. Creates a vector of the appropriate type 54 * and 0 length 55 */ Vector()56 Vector() { 57 Storage::set__( Rf_allocVector(RTYPE, 0 ) ); 58 init() ; 59 } 60 61 /** 62 * copy constructor. shallow copy of the SEXP 63 */ Vector(const Vector & other)64 Vector( const Vector& other){ 65 Storage::copy__(other) ; 66 } 67 68 Vector& operator=(const Vector& rhs) { 69 return Storage::copy__(rhs) ; 70 } 71 Vector(SEXP x)72 Vector( SEXP x ) { 73 Rcpp::Shield<SEXP> safe(x); 74 Storage::set__( r_cast<RTYPE>(safe) ) ; 75 } 76 77 template <typename Proxy> Vector(const GenericProxy<Proxy> & proxy)78 Vector( const GenericProxy<Proxy>& proxy ){ 79 Rcpp::Shield<SEXP> safe(proxy.get()); 80 Storage::set__( r_cast<RTYPE>(safe) ) ; 81 } 82 Vector(const no_init_vector & obj)83 explicit Vector( const no_init_vector& obj) { 84 Storage::set__( Rf_allocVector( RTYPE, obj.get() ) ) ; 85 } 86 87 template<typename T> 88 Vector( const T& size, const stored_type& u, 89 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 90 RCPP_DEBUG_2( "Vector<%d>( const T& size = %d, const stored_type& u )", RTYPE, size) 91 Storage::set__( Rf_allocVector( RTYPE, size) ) ; 92 fill( u ) ; 93 } 94 Vector(const int & size,const stored_type & u)95 Vector( const int& size, const stored_type& u) { 96 RCPP_DEBUG_2( "Vector<%d>( const int& size = %d, const stored_type& u )", RTYPE, size) 97 Storage::set__( Rf_allocVector( RTYPE, size) ) ; 98 fill( u ) ; 99 } 100 101 // constructor for CharacterVector() Vector(const std::string & st)102 Vector( const std::string& st ){ 103 RCPP_DEBUG_2( "Vector<%d>( const std::string& = %s )", RTYPE, st.c_str() ) 104 Storage::set__( internal::vector_from_string<RTYPE>(st) ) ; 105 } 106 107 // constructor for CharacterVector() Vector(const char * st)108 Vector( const char* st ) { 109 RCPP_DEBUG_2( "Vector<%d>( const char* = %s )", RTYPE, st ) 110 Storage::set__(internal::vector_from_string<RTYPE>(st) ) ; 111 } 112 113 template<typename T> 114 Vector( const T& siz, stored_type (*gen)(void), 115 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 116 RCPP_DEBUG_2( "Vector<%d>( const int& siz = %s, stored_type (*gen)(void) )", RTYPE, siz ) 117 Storage::set__( Rf_allocVector( RTYPE, siz) ) ; 118 std::generate( begin(), end(), gen ); 119 } 120 121 // Add template class T and then restict T to arithmetic. 122 template <typename T> 123 Vector(T size, 124 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 125 Storage::set__( Rf_allocVector( RTYPE, size) ) ; 126 init() ; 127 } 128 Vector(const int & size)129 Vector( const int& size ) { 130 Storage::set__( Rf_allocVector( RTYPE, size) ) ; 131 init() ; 132 } 133 Vector(const Dimension & dims)134 Vector( const Dimension& dims) { 135 Storage::set__( Rf_allocVector( RTYPE, dims.prod() ) ) ; 136 init() ; 137 if( dims.size() > 1 ){ 138 AttributeProxyPolicy<Vector>::attr( "dim" ) = dims; 139 } 140 } 141 142 // Enable construction from bool for LogicalVectors 143 // SFINAE only work for template. Add template class T and then restict T to 144 // bool. 145 template <typename T> 146 Vector(T value, 147 typename Rcpp::traits::enable_if<traits::is_bool<T>::value && RTYPE == LGLSXP, void>::type* = 0) { 148 Storage::set__(Rf_allocVector(RTYPE, 1)); 149 fill(value); 150 } 151 152 template <typename U> Vector(const Dimension & dims,const U & u)153 Vector( const Dimension& dims, const U& u) { 154 RCPP_DEBUG_2( "Vector<%d>( const Dimension& (%d), const U& )", RTYPE, dims.size() ) 155 Storage::set__( Rf_allocVector( RTYPE, dims.prod() ) ) ; 156 fill(u) ; 157 if( dims.size() > 1 ){ 158 AttributeProxyPolicy<Vector>::attr( "dim" ) = dims; 159 } 160 } 161 162 template <bool NA, typename VEC> Vector(const VectorBase<RTYPE,NA,VEC> & other)163 Vector( const VectorBase<RTYPE,NA,VEC>& other ) { 164 RCPP_DEBUG_2( "Vector<%d>( const VectorBase<RTYPE,NA,VEC>& ) [VEC = %s]", RTYPE, DEMANGLE(VEC) ) 165 import_sugar_expression( other, typename traits::same_type<Vector,VEC>::type() ) ; 166 } 167 168 template <typename T, typename U> 169 Vector( const T& size, const U& u, 170 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 171 RCPP_DEBUG_2( "Vector<%d>( const T& size, const U& u )", RTYPE, size ) 172 Storage::set__( Rf_allocVector( RTYPE, size) ) ; 173 fill_or_generate( u ) ; 174 } 175 176 template <bool NA, typename T> Vector(const sugar::SingleLogicalResult<NA,T> & obj)177 Vector( const sugar::SingleLogicalResult<NA,T>& obj ) { 178 Rcpp::Shield<SEXP> safe(const_cast<sugar::SingleLogicalResult<NA,T>&>(obj).get_sexp() ); 179 Storage::set__( r_cast<RTYPE>(safe) ) ; 180 RCPP_DEBUG_2( "Vector<%d>( const sugar::SingleLogicalResult<NA,T>& ) [T = %s]", RTYPE, DEMANGLE(T) ) 181 } 182 183 template <typename T, typename U1> 184 Vector( const T& siz, stored_type (*gen)(U1), const U1& u1, 185 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 186 Storage::set__( Rf_allocVector( RTYPE, siz) ) ; 187 RCPP_DEBUG_2( "const T& siz, stored_type (*gen)(U1), const U1& u1 )", RTYPE, siz ) 188 iterator first = begin(), last = end() ; 189 while( first != last ) *first++ = gen(u1) ; 190 } 191 192 template <typename T, typename U1, typename U2> 193 Vector( const T& siz, stored_type (*gen)(U1,U2), const U1& u1, const U2& u2, 194 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 195 Storage::set__( Rf_allocVector( RTYPE, siz) ) ; 196 RCPP_DEBUG_2( "const T& siz, stored_type (*gen)(U1,U2), const U1& u1, const U2& u2)", RTYPE, siz ) 197 iterator first = begin(), last = end() ; 198 while( first != last ) *first++ = gen(u1,u2) ; 199 } 200 201 template <typename T, typename U1, typename U2, typename U3> 202 Vector( const T& siz, stored_type (*gen)(U1,U2,U3), const U1& u1, const U2& u2, const U3& u3, 203 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 204 Storage::set__( Rf_allocVector( RTYPE, siz) ) ; 205 RCPP_DEBUG_2( "const T& siz, stored_type (*gen)(U1,U2,U3), const U1& u1, const U2& u2, const U3& u3)", RTYPE, siz ) 206 iterator first = begin(), last = end() ; 207 while( first != last ) *first++ = gen(u1,u2,u3) ; 208 } 209 210 template <typename InputIterator> Vector(InputIterator first,InputIterator last)211 Vector( InputIterator first, InputIterator last){ 212 RCPP_DEBUG_1( "Vector<%d>( InputIterator first, InputIterator last", RTYPE ) 213 Storage::set__( Rf_allocVector(RTYPE, std::distance(first, last) ) ) ; 214 std::copy( first, last, begin() ) ; 215 } 216 217 template <typename InputIterator, typename T> 218 Vector( InputIterator first, InputIterator last, T n, 219 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) { 220 Storage::set__(Rf_allocVector(RTYPE, n)) ; 221 RCPP_DEBUG_2( "Vector<%d>( InputIterator first, InputIterator last, T n = %d)", RTYPE, n ) 222 std::copy( first, last, begin() ) ; 223 } 224 225 template <typename InputIterator, typename Func> Vector(InputIterator first,InputIterator last,Func func)226 Vector( InputIterator first, InputIterator last, Func func) { 227 Storage::set__( Rf_allocVector( RTYPE, std::distance(first,last) ) ); 228 RCPP_DEBUG_1( "Vector<%d>( InputIterator, InputIterator, Func )", RTYPE ) 229 std::transform( first, last, begin(), func) ; 230 } 231 232 template <typename InputIterator, typename Func, typename T> 233 Vector( InputIterator first, InputIterator last, Func func, T n, 234 typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0){ 235 Storage::set__( Rf_allocVector( RTYPE, n ) ); 236 RCPP_DEBUG_2( "Vector<%d>( InputIterator, InputIterator, Func, T n = %d )", RTYPE, n ) 237 std::transform( first, last, begin(), func) ; 238 } 239 240 #ifdef HAS_CXX0X_INITIALIZER_LIST Vector(std::initializer_list<init_type> list)241 Vector( std::initializer_list<init_type> list ) { 242 assign( list.begin() , list.end() ) ; 243 } 244 #endif 245 246 template <typename T> 247 Vector& operator=( const T& x) { 248 assign_object( x, typename traits::is_sugar_expression<T>::type() ) ; 249 return *this ; 250 } 251 get_na()252 static inline stored_type get_na() { 253 return traits::get_na<RTYPE>(); 254 } is_na(stored_type x)255 static inline bool is_na( stored_type x){ 256 return traits::is_na<RTYPE>(x); 257 } 258 259 #ifdef RCPP_COMMA_INITIALIZATION 260 internal::ListInitialization<iterator,init_type> operator=( init_type x){ 261 iterator start = begin() ; *start = x; 262 return internal::ListInitialization<iterator,init_type>( start + 1 ) ; ; 263 } 264 #endif 265 266 /** 267 * the length of the vector, uses Rf_xlength 268 */ length()269 inline R_xlen_t length() const { 270 return ::Rf_xlength( Storage::get__() ) ; 271 } 272 273 /** 274 * alias of length 275 */ size()276 inline R_xlen_t size() const { 277 return ::Rf_xlength( Storage::get__() ) ; 278 } 279 280 /** 281 * offset based on the dimensions of this vector 282 */ offset(const int & i,const int & j)283 R_xlen_t offset(const int& i, const int& j) const { 284 if( !::Rf_isMatrix(Storage::get__()) ) throw not_a_matrix() ; 285 286 /* we need to extract the dimensions */ 287 const int* dim = dims() ; 288 const int nrow = dim[0] ; 289 const int ncol = dim[1] ; 290 if(i < 0|| i >= nrow || j < 0 || j >= ncol ) { 291 const char* fmt = "Location index is out of bounds: " 292 "[row index=%i; row extent=%i; " 293 "column index=%i; column extent=%i]."; 294 throw index_out_of_bounds(fmt, i, nrow, j, ncol); 295 } 296 return i + static_cast<R_xlen_t>(nrow)*j ; 297 } 298 299 /** 300 * one dimensional offset doing bounds checking to ensure 301 * it is valid 302 */ offset(const R_xlen_t & i)303 R_xlen_t offset(const R_xlen_t& i) const { // #nocov start 304 if(i < 0 || i >= ::Rf_xlength(Storage::get__()) ) { 305 const char* fmt = "Index out of bounds: [index=%i; extent=%i]."; 306 throw index_out_of_bounds(fmt, i, ::Rf_xlength(Storage::get__()) ) ; 307 } 308 return i ; // #nocov end 309 } 310 offset(const std::string & name)311 R_xlen_t offset(const std::string& name) const { 312 SEXP names = RCPP_GET_NAMES( Storage::get__() ) ; 313 if( Rf_isNull(names) ) { 314 throw index_out_of_bounds("Object was created without names."); 315 } 316 317 R_xlen_t n=size() ; 318 for( R_xlen_t i=0; i<n; ++i){ 319 if( ! name.compare( CHAR(STRING_ELT(names, i)) ) ){ 320 return i ; 321 } 322 } 323 324 const char* fmt = "Index out of bounds: [index='%s']."; 325 throw index_out_of_bounds(fmt, name); 326 return -1 ; /* -Wall */ 327 } 328 329 template <typename U> fill(const U & u)330 void fill( const U& u){ 331 fill__dispatch( typename traits::is_trivial<RTYPE>::type(), u ) ; 332 } 333 begin()334 inline iterator begin() { return cache.get() ; } end()335 inline iterator end() { return cache.get() + size() ; } begin()336 inline const_iterator begin() const{ return cache.get_const() ; } end()337 inline const_iterator end() const{ return cache.get_const() + size() ; } cbegin()338 inline const_iterator cbegin() const{ return cache.get_const() ; } cend()339 inline const_iterator cend() const{ return cache.get_const() + size() ; } 340 341 inline Proxy operator[]( R_xlen_t i ){ return cache.ref(i) ; } 342 inline const_Proxy operator[]( R_xlen_t i ) const { return cache.ref(i) ; } 343 operator()344 inline Proxy operator()( const size_t& i) { 345 return cache.ref( offset(i) ) ; 346 } operator()347 inline const_Proxy operator()( const size_t& i) const { 348 return cache.ref( offset(i) ) ; 349 } 350 at(const size_t & i)351 inline Proxy at( const size_t& i) { 352 return cache.ref( offset(i) ) ; 353 } at(const size_t & i)354 inline const_Proxy at( const size_t& i) const { // #nocov start 355 return cache.ref( offset(i) ) ; 356 } // #nocov end 357 operator()358 inline Proxy operator()( const size_t& i, const size_t& j) { 359 return cache.ref( offset(i,j) ) ; 360 } operator()361 inline const_Proxy operator()( const size_t& i, const size_t& j) const { 362 return cache.ref( offset(i,j) ) ; 363 } 364 365 inline NameProxy operator[]( const std::string& name ){ 366 return NameProxy( *this, name ) ; 367 } operator()368 inline NameProxy operator()( const std::string& name ){ 369 return NameProxy( *this, name ) ; 370 } 371 372 inline NameProxy operator[]( const std::string& name ) const { 373 return NameProxy( const_cast<Vector&>(*this), name ) ; 374 } operator()375 inline NameProxy operator()( const std::string& name ) const { 376 return NameProxy( const_cast<Vector&>(*this), name ) ; 377 } 378 RObject()379 inline operator RObject() const { 380 return RObject( Storage::get__() ); 381 } 382 383 // sugar subsetting requires dispatch on VectorBase 384 template <int RHS_RTYPE, bool RHS_NA, typename RHS_T> 385 SubsetProxy<RTYPE, StoragePolicy, RHS_RTYPE, RHS_NA, RHS_T> 386 operator[](const VectorBase<RHS_RTYPE, RHS_NA, RHS_T>& rhs) { 387 return SubsetProxy<RTYPE, StoragePolicy, RHS_RTYPE, RHS_NA, RHS_T>( 388 *this, 389 rhs 390 ); 391 } 392 393 template <int RHS_RTYPE, bool RHS_NA, typename RHS_T> 394 const SubsetProxy<RTYPE, StoragePolicy, RHS_RTYPE, RHS_NA, RHS_T> 395 operator[](const VectorBase<RHS_RTYPE, RHS_NA, RHS_T>& rhs) const { 396 return SubsetProxy<RTYPE, StoragePolicy, RHS_RTYPE, RHS_NA, RHS_T>( 397 const_cast< Vector<RTYPE, StoragePolicy>& >(*this), 398 rhs 399 ); 400 } 401 402 Vector& sort(bool decreasing = false) { 403 // sort() does not apply to List, RawVector or ExpressionVector. 404 // 405 // The function below does nothing for qualified Vector types, 406 // and is undefined for other types. Hence there will be a 407 // compiler error when sorting List, RawVector or ExpressionVector. 408 internal::Sort_is_not_allowed_for_this_type<RTYPE>::do_nothing(); 409 410 typename traits::storage_type<RTYPE>::type* start = internal::r_vector_start<RTYPE>( Storage::get__() ); 411 412 if (!decreasing) { 413 std::sort( 414 start, 415 start + size(), 416 internal::NAComparator<typename traits::storage_type<RTYPE>::type>() 417 ); 418 } else { 419 std::sort( 420 start, 421 start + size(), 422 internal::NAComparatorGreater<typename traits::storage_type<RTYPE>::type>() 423 ); 424 } 425 426 return *this; 427 } 428 429 template <typename InputIterator> assign(InputIterator first,InputIterator last)430 void assign( InputIterator first, InputIterator last){ 431 /* FIXME: we can do better than this r_cast to avoid 432 allocating an unnecessary temporary object 433 */ 434 Shield<SEXP> wrapped(wrap(first, last)); 435 Shield<SEXP> casted(r_cast<RTYPE>(wrapped)); 436 Storage::set__(casted) ; 437 } 438 439 template <typename InputIterator> import(InputIterator first,InputIterator last)440 static Vector import( InputIterator first, InputIterator last){ 441 Vector v ; 442 v.assign( first , last ) ; 443 return v ; 444 } 445 446 template <typename InputIterator, typename F> import_transform(InputIterator first,InputIterator last,F f)447 static Vector import_transform( InputIterator first, InputIterator last, F f){ 448 return Vector( first, last, f) ; 449 } 450 451 template <typename T> push_back(const T & object)452 void push_back( const T& object){ 453 push_back__impl( converter_type::get(object), 454 typename traits::same_type<stored_type,SEXP>() 455 ) ; 456 } 457 458 template <typename T> push_back(const T & object,const std::string & name)459 void push_back( const T& object, const std::string& name ){ 460 push_back_name__impl( converter_type::get(object), name, 461 typename traits::same_type<stored_type,SEXP>() 462 ) ; 463 } 464 465 template <typename T> push_front(const T & object)466 void push_front( const T& object){ 467 push_front__impl( converter_type::get(object), 468 typename traits::same_type<stored_type,SEXP>() ) ; 469 } 470 471 template <typename T> push_front(const T & object,const std::string & name)472 void push_front( const T& object, const std::string& name){ 473 push_front_name__impl( converter_type::get(object), name, 474 typename traits::same_type<stored_type,SEXP>() ) ; 475 } 476 477 478 template <typename T> insert(iterator position,const T & object)479 iterator insert( iterator position, const T& object){ 480 return insert__impl( position, converter_type::get(object), 481 typename traits::same_type<stored_type,SEXP>() 482 ) ; 483 } 484 485 template <typename T> insert(int position,const T & object)486 iterator insert( int position, const T& object){ 487 return insert__impl( cache.get() + position, converter_type::get(object), 488 typename traits::same_type<stored_type,SEXP>() 489 ); 490 } 491 erase(int position)492 iterator erase( int position){ 493 return erase_single__impl( cache.get() + position) ; 494 } 495 erase(iterator position)496 iterator erase( iterator position){ 497 return erase_single__impl( position ) ; 498 } 499 erase(int first,int last)500 iterator erase( int first, int last){ 501 iterator start = cache.get() ; 502 return erase_range__impl( start + first, start + last ) ; 503 } 504 erase(iterator first,iterator last)505 iterator erase( iterator first, iterator last){ 506 return erase_range__impl( first, last ) ; 507 } 508 update(SEXP)509 void update(SEXP){ 510 cache.update(*this) ; 511 } 512 513 template <typename U> replace_element(iterator it,SEXP names,R_xlen_t index,const U & u)514 static void replace_element( iterator it, SEXP names, R_xlen_t index, const U& u){ 515 replace_element__dispatch( typename traits::is_named<U>::type(), 516 it, names, index, u ) ; 517 } 518 519 template <typename U> replace_element__dispatch(traits::false_type,iterator it,SEXP names,R_xlen_t index,const U & u)520 static void replace_element__dispatch( traits::false_type, iterator it, SEXP names, R_xlen_t index, const U& u){ 521 *it = converter_type::get(u); 522 } 523 524 template <typename U> replace_element__dispatch(traits::true_type,iterator it,SEXP names,R_xlen_t index,const U & u)525 static void replace_element__dispatch( traits::true_type, iterator it, SEXP names, R_xlen_t index, const U& u){ 526 replace_element__dispatch__isArgument( typename traits::same_type<U,Argument>(), it, names, index, u ) ; 527 } 528 529 template <typename U> replace_element__dispatch__isArgument(traits::false_type,iterator it,SEXP names,R_xlen_t index,const U & u)530 static void replace_element__dispatch__isArgument( traits::false_type, iterator it, SEXP names, R_xlen_t index, const U& u){ 531 RCPP_DEBUG_2( " Vector::replace_element__dispatch<%s>(true, index= %d) ", DEMANGLE(U), index ) ; 532 533 *it = converter_type::get(u.object ) ; 534 SET_STRING_ELT( names, index, ::Rf_mkChar( u.name.c_str() ) ) ; 535 } 536 537 template <typename U> replace_element__dispatch__isArgument(traits::true_type,iterator it,SEXP names,R_xlen_t index,const U & u)538 static void replace_element__dispatch__isArgument( traits::true_type, iterator it, SEXP names, R_xlen_t index, const U& u){ 539 RCPP_DEBUG_2( " Vector::replace_element__dispatch<%s>(true, index= %d) ", DEMANGLE(U), index ) ; 540 541 *it = R_MissingArg ; 542 SET_STRING_ELT( names, index, ::Rf_mkChar( u.name.c_str() ) ) ; 543 } 544 545 typedef internal::RangeIndexer<RTYPE,true,Vector> Indexer ; 546 547 inline Indexer operator[]( const Range& range ){ 548 return Indexer( const_cast<Vector&>(*this), range ); 549 } 550 551 template <typename EXPR_VEC> 552 Vector& operator+=( const VectorBase<RTYPE,true,EXPR_VEC>& rhs ) { 553 const EXPR_VEC& ref = rhs.get_ref() ; 554 iterator start = begin() ; 555 R_xlen_t n = size() ; 556 // TODO: maybe unroll this 557 stored_type tmp ; 558 for( R_xlen_t i=0; i<n; i++){ 559 Proxy left = start[i] ; 560 if( ! traits::is_na<RTYPE>( left ) ){ 561 tmp = ref[i] ; 562 left = traits::is_na<RTYPE>( tmp ) ? tmp : ( left + tmp ) ; 563 } 564 } 565 return *this ; 566 } 567 568 template <typename EXPR_VEC> 569 Vector& operator+=( const VectorBase<RTYPE,false,EXPR_VEC>& rhs ) { 570 const EXPR_VEC& ref = rhs.get_ref() ; 571 iterator start = begin() ; 572 R_xlen_t n = size() ; 573 stored_type tmp ; 574 for( R_xlen_t i=0; i<n; i++){ 575 if( ! traits::is_na<RTYPE>(start[i]) ){ 576 start[i] += ref[i] ; 577 } 578 } 579 return *this ; 580 581 } 582 583 /** 584 * Does this vector have an element with the target name 585 */ containsElementNamed(const char * target)586 bool containsElementNamed( const char* target ) const { 587 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 588 if( Rf_isNull(names) ) return false ; 589 R_xlen_t n = Rf_xlength(names) ; 590 for( R_xlen_t i=0; i<n; i++){ 591 if( !strcmp( target, CHAR(STRING_ELT(names, i)) ) ) 592 return true ; 593 } 594 return false ; 595 } 596 findName(const std::string & name)597 int findName(const std::string& name) const { 598 SEXP names = RCPP_GET_NAMES(Storage::get__()); 599 if (Rf_isNull(names)) stop("'names' attribute is null"); 600 R_xlen_t n = Rf_xlength(names); 601 for (R_xlen_t i=0; i < n; ++i) { 602 if (strcmp(name.c_str(), CHAR(STRING_ELT(names, i))) == 0) { 603 return i; 604 } 605 } 606 std::stringstream ss; 607 ss << "no name '" << name << "' found"; 608 stop(ss.str()); 609 return -1; 610 } 611 612 protected: dims()613 inline int* dims() const { 614 if( !::Rf_isMatrix(Storage::get__()) ) throw not_a_matrix() ; 615 return INTEGER( ::Rf_getAttrib( Storage::get__(), R_DimSymbol ) ) ; 616 } init()617 void init(){ 618 RCPP_DEBUG_2( "VECTOR<%d>::init( SEXP = <%p> )", RTYPE, Storage::get__() ) 619 internal::r_init_vector<RTYPE>(Storage::get__()) ; 620 } 621 622 private: 623 push_back__impl(const stored_type & object,traits::true_type)624 void push_back__impl(const stored_type& object, traits::true_type ) { 625 Shield<SEXP> object_sexp( object ) ; 626 R_xlen_t n = size() ; 627 Vector target( n + 1 ) ; 628 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 629 iterator target_it( target.begin() ) ; 630 iterator it(begin()) ; 631 iterator this_end(end()); 632 if( Rf_isNull(names) ){ 633 for( ; it < this_end; ++it, ++target_it ){ 634 *target_it = *it ; // #nocov start 635 } 636 } else { 637 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n + 1) ) ; 638 int i = 0 ; 639 for( ; it < this_end; ++it, ++target_it, i++ ){ 640 *target_it = *it ; 641 SET_STRING_ELT( newnames, i, STRING_ELT(names, i ) ) ; 642 } 643 SET_STRING_ELT( newnames, i, Rf_mkChar("") ) ; 644 target.attr("names") = newnames ; // #nocov end 645 } 646 *target_it = object_sexp; 647 Storage::set__( target.get__() ) ; 648 } 649 push_back__impl(const stored_type & object,traits::false_type)650 void push_back__impl(const stored_type& object, traits::false_type ) { 651 R_xlen_t n = size() ; 652 Vector target( n + 1 ) ; 653 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 654 iterator target_it( target.begin() ) ; 655 iterator it(begin()) ; 656 iterator this_end(end()); 657 if( Rf_isNull(names) ){ 658 for( ; it < this_end; ++it, ++target_it ){ 659 *target_it = *it ; 660 } 661 } else { 662 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n + 1) ) ; 663 int i = 0 ; 664 for( ; it < this_end; ++it, ++target_it, i++ ){ 665 *target_it = *it ; 666 SET_STRING_ELT( newnames, i, STRING_ELT(names, i ) ) ; 667 } 668 SET_STRING_ELT( newnames, i, Rf_mkChar("") ) ; 669 target.attr("names") = newnames ; 670 } 671 *target_it = object; 672 Storage::set__( target.get__() ) ; 673 } 674 push_back_name__impl(const stored_type & object,const std::string & name,traits::true_type)675 void push_back_name__impl(const stored_type& object, const std::string& name, traits::true_type ) { 676 Shield<SEXP> object_sexp( object ) ; 677 R_xlen_t n = size() ; 678 Vector target( n + 1 ) ; 679 iterator target_it( target.begin() ) ; 680 iterator it(begin()) ; 681 iterator this_end(end()); 682 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 683 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n+1 ) ) ; 684 int i=0; 685 if( Rf_isNull(names) ){ 686 for( ; it < this_end; ++it, ++target_it,i++ ){ 687 *target_it = *it ; // #nocov 688 SET_STRING_ELT( newnames, i , R_BlankString ); // #nocov 689 } 690 } else { 691 for( ; it < this_end; ++it, ++target_it, i++ ){ 692 *target_it = *it ; 693 SET_STRING_ELT( newnames, i, STRING_ELT(names, i ) ) ; 694 } 695 } 696 SET_STRING_ELT( newnames, i, Rf_mkChar( name.c_str() ) ); 697 target.attr("names") = newnames ; 698 699 *target_it = object_sexp; 700 Storage::set__( target.get__() ) ; 701 } push_back_name__impl(const stored_type & object,const std::string & name,traits::false_type)702 void push_back_name__impl(const stored_type& object, const std::string& name, traits::false_type ) { 703 R_xlen_t n = size() ; 704 Vector target( n + 1 ) ; 705 iterator target_it( target.begin() ) ; 706 iterator it(begin()) ; 707 iterator this_end(end()); 708 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 709 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n+1 ) ) ; 710 int i=0; 711 if( Rf_isNull(names) ){ 712 Shield<SEXP> dummy( Rf_mkChar("") ); 713 for( ; it < this_end; ++it, ++target_it,i++ ){ 714 *target_it = *it ; 715 SET_STRING_ELT( newnames, i , dummy ); 716 } 717 } else { 718 for( ; it < this_end; ++it, ++target_it, i++ ){ 719 *target_it = *it ; 720 SET_STRING_ELT( newnames, i, STRING_ELT(names, i ) ) ; 721 } 722 } 723 SET_STRING_ELT( newnames, i, Rf_mkChar( name.c_str() ) ); 724 target.attr("names") = newnames ; 725 726 *target_it = object; 727 Storage::set__( target.get__() ) ; 728 } 729 push_front__impl(const stored_type & object,traits::true_type)730 void push_front__impl(const stored_type& object, traits::true_type ) { 731 Shield<SEXP> object_sexp( object ) ; 732 R_xlen_t n = size() ; 733 Vector target( n+1); 734 iterator target_it(target.begin()); 735 iterator it(begin()); 736 iterator this_end(end()); 737 *target_it = object_sexp ; 738 ++target_it ; 739 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 740 if( Rf_isNull(names) ){ 741 for( ; it<this_end; ++it, ++target_it){ 742 *target_it = *it ; 743 } 744 } else{ 745 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n + 1) ); 746 int i=1 ; 747 SET_STRING_ELT( newnames, 0, Rf_mkChar("") ) ; 748 for( ; it<this_end; ++it, ++target_it, i++){ 749 *target_it = *it ; 750 SET_STRING_ELT( newnames, i, STRING_ELT(names, i-1 ) ) ; 751 } 752 target.attr("names") = newnames ; 753 } 754 Storage::set__( target.get__() ) ; 755 756 } push_front__impl(const stored_type & object,traits::false_type)757 void push_front__impl(const stored_type& object, traits::false_type ) { 758 R_xlen_t n = size() ; 759 Vector target( n+1); 760 iterator target_it(target.begin()); 761 iterator it(begin()); 762 iterator this_end(end()); 763 *target_it = object ; 764 ++target_it ; 765 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 766 if( Rf_isNull(names) ){ 767 for( ; it<this_end; ++it, ++target_it){ 768 *target_it = *it ; 769 } 770 } else{ 771 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n + 1) ); 772 int i=1 ; 773 SET_STRING_ELT( newnames, 0, Rf_mkChar("") ) ; 774 for( ; it<this_end; ++it, ++target_it, i++){ 775 *target_it = *it ; 776 SET_STRING_ELT( newnames, i, STRING_ELT(names, i-1 ) ) ; 777 } 778 target.attr("names") = newnames ; 779 } 780 Storage::set__( target.get__() ) ; 781 782 } 783 push_front_name__impl(const stored_type & object,const std::string & name,traits::true_type)784 void push_front_name__impl(const stored_type& object, const std::string& name, traits::true_type ) { 785 Shield<SEXP> object_sexp(object) ; 786 R_xlen_t n = size() ; 787 Vector target( n + 1 ) ; 788 iterator target_it( target.begin() ) ; 789 iterator it(begin()) ; 790 iterator this_end(end()); 791 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 792 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n+1 ) ) ; 793 int i=1; 794 SET_STRING_ELT( newnames, 0, Rf_mkChar( name.c_str() ) ); 795 *target_it = object_sexp; 796 ++target_it ; 797 798 if( Rf_isNull(names) ){ 799 for( ; it < this_end; ++it, ++target_it,i++ ){ 800 *target_it = *it ; 801 SET_STRING_ELT( newnames, i , R_BlankString ); 802 } 803 } else { 804 for( ; it < this_end; ++it, ++target_it, i++ ){ 805 *target_it = *it ; 806 SET_STRING_ELT( newnames, i, STRING_ELT(names, i-1 ) ) ; 807 } 808 } 809 target.attr("names") = newnames ; 810 Storage::set__( target.get__() ) ; 811 812 } push_front_name__impl(const stored_type & object,const std::string & name,traits::false_type)813 void push_front_name__impl(const stored_type& object, const std::string& name, traits::false_type ) { 814 R_xlen_t n = size() ; 815 Vector target( n + 1 ) ; 816 iterator target_it( target.begin() ) ; 817 iterator it(begin()) ; 818 iterator this_end(end()); 819 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 820 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n+1 ) ) ; 821 int i=1; 822 SET_STRING_ELT( newnames, 0, Rf_mkChar( name.c_str() ) ); 823 *target_it = object; 824 ++target_it ; 825 826 if( Rf_isNull(names) ){ 827 for( ; it < this_end; ++it, ++target_it,i++ ){ 828 *target_it = *it ; 829 SET_STRING_ELT( newnames, i , R_BlankString ); 830 } 831 } else { 832 for( ; it < this_end; ++it, ++target_it, i++ ){ 833 *target_it = *it ; 834 SET_STRING_ELT( newnames, i, STRING_ELT(names, i-1 ) ) ; 835 } 836 } 837 target.attr("names") = newnames ; 838 839 Storage::set__( target.get__() ) ; 840 841 } 842 insert__impl(iterator position,const stored_type & object_,traits::true_type)843 iterator insert__impl( iterator position, const stored_type& object_, traits::true_type ) { 844 Shield<SEXP> object( object_ ) ; 845 R_xlen_t n = size() ; 846 Vector target( n+1 ) ; 847 iterator target_it = target.begin(); 848 iterator it = begin() ; 849 iterator this_end = end() ; 850 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 851 iterator result ; 852 if( Rf_isNull(names) ){ 853 for( ; it < position; ++it, ++target_it){ 854 *target_it = *it ; 855 } 856 result = target_it; 857 *target_it = object ; 858 ++target_it ; 859 for( ; it < this_end; ++it, ++target_it ){ 860 *target_it = *it ; 861 } 862 } else{ 863 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n + 1 ) ) ; 864 int i=0; 865 for( ; it < position; ++it, ++target_it, i++){ 866 *target_it = *it ; 867 SET_STRING_ELT( newnames, i, STRING_ELT(names, i ) ) ; 868 } 869 result = target_it; 870 *target_it = object ; 871 SET_STRING_ELT( newnames, i, ::Rf_mkChar("") ) ; 872 i++ ; 873 ++target_it ; 874 for( ; it < this_end; ++it, ++target_it, i++ ){ 875 *target_it = *it ; 876 SET_STRING_ELT( newnames, i, STRING_ELT(names, i - 1) ) ; 877 } 878 target.attr( "names" ) = newnames ; 879 } 880 Storage::set__( target.get__() ) ; 881 return result ; 882 } 883 insert__impl(iterator position,const stored_type & object,traits::false_type)884 iterator insert__impl( iterator position, const stored_type& object, traits::false_type ) { 885 R_xlen_t n = size() ; 886 Vector target( n+1 ) ; 887 iterator target_it = target.begin(); 888 iterator it = begin() ; 889 iterator this_end = end() ; 890 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 891 iterator result ; 892 if( Rf_isNull(names) ){ 893 for( ; it < position; ++it, ++target_it){ 894 *target_it = *it ; 895 } 896 result = target_it; 897 *target_it = object ; 898 ++target_it ; 899 for( ; it < this_end; ++it, ++target_it ){ 900 *target_it = *it ; 901 } 902 } else{ 903 Shield<SEXP> newnames( ::Rf_allocVector( STRSXP, n + 1 ) ) ; 904 int i=0; 905 for( ; it < position; ++it, ++target_it, i++){ 906 *target_it = *it ; 907 SET_STRING_ELT( newnames, i, STRING_ELT(names, i ) ) ; 908 } 909 result = target_it; 910 *target_it = object ; 911 SET_STRING_ELT( newnames, i, ::Rf_mkChar("") ) ; 912 i++ ; 913 ++target_it ; 914 for( ; it < this_end; ++it, ++target_it, i++ ){ 915 *target_it = *it ; 916 SET_STRING_ELT( newnames, i, STRING_ELT(names, i - 1) ) ; 917 } 918 target.attr( "names" ) = newnames ; 919 } 920 Storage::set__( target.get__() ) ; 921 return result ; 922 } 923 erase_single__impl(iterator position)924 iterator erase_single__impl( iterator position ) { 925 if( position < begin() || position > end() ) { 926 R_xlen_t requested_loc; 927 R_xlen_t available_locs = std::distance(begin(), end()); 928 929 if(position > end()){ 930 requested_loc = std::distance(position, begin()); 931 } else { 932 // This will be a negative number 933 requested_loc = std::distance(begin(), position); 934 } 935 const char* fmt = "Iterator index is out of bounds: " 936 "[iterator index=%i; iterator extent=%i]"; 937 throw index_out_of_bounds(fmt, requested_loc, available_locs ) ; 938 } 939 940 R_xlen_t n = size() ; 941 942 Vector target( n - 1 ) ; 943 iterator target_it(target.begin()) ; 944 iterator it(begin()) ; 945 iterator this_end(end()) ; 946 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 947 if( Rf_isNull(names) ){ 948 int i=0; 949 for( ; it < position; ++it, ++target_it, i++){ 950 *target_it = *it; 951 } 952 ++it ; 953 for( ; it < this_end ; ++it, ++target_it){ 954 *target_it = *it; 955 } 956 Storage::set__( target.get__() ) ; 957 return begin()+i ; 958 } else { 959 Shield<SEXP> newnames(::Rf_allocVector( STRSXP, n-1 )); 960 int i= 0 ; 961 for( ; it < position; ++it, ++target_it,i++){ 962 *target_it = *it; 963 SET_STRING_ELT( newnames, i , STRING_ELT(names,i) ) ; 964 } 965 int result=i ; 966 ++it ; 967 i++ ; 968 for( ; it < this_end ; ++it, ++target_it, i++){ 969 *target_it = *it; 970 SET_STRING_ELT( newnames, i-1, STRING_ELT(names,i) ) ; 971 } 972 target.attr( "names" ) = newnames ; 973 Storage::set__( target.get__() ) ; 974 return begin()+result ; 975 } 976 } 977 erase_range__impl(iterator first,iterator last)978 iterator erase_range__impl( iterator first, iterator last ) { 979 if( first > last ) throw std::range_error("invalid range") ; 980 if( last > end() || first < begin() ) { 981 R_xlen_t requested_loc; 982 R_xlen_t available_locs = std::distance(begin(), end()); 983 std::string iter_problem; 984 985 if(last > end()){ 986 requested_loc = std::distance(last, begin()); 987 iter_problem = "last"; 988 } else { 989 // This will be a negative number 990 requested_loc = std::distance(begin(), first); 991 iter_problem = "first"; 992 } 993 const char* fmt = "Iterator index is out of bounds: " 994 "[iterator=%s; index=%i; extent=%i]"; 995 throw index_out_of_bounds(fmt, iter_problem, 996 requested_loc, available_locs ) ; 997 } 998 999 iterator it = begin() ; 1000 iterator this_end = end() ; 1001 R_xlen_t nremoved = std::distance(first,last) ; 1002 R_xlen_t target_size = size() - nremoved ; 1003 Vector target( target_size ) ; 1004 iterator target_it = target.begin() ; 1005 1006 SEXP names = RCPP_GET_NAMES(Storage::get__()) ; 1007 int result = 0; 1008 if( Rf_isNull(names) ){ 1009 int i=0; 1010 for( ; it < first; ++it, ++target_it, i++ ){ 1011 *target_it = *it ; 1012 } 1013 result = i; 1014 for( it = last ; it < this_end; ++it, ++target_it ){ 1015 *target_it = *it ; 1016 } 1017 } else{ 1018 Shield<SEXP> newnames( ::Rf_allocVector(STRSXP, target_size) ) ; 1019 int i= 0 ; 1020 for( ; it < first; ++it, ++target_it, i++ ){ 1021 *target_it = *it ; 1022 SET_STRING_ELT( newnames, i, STRING_ELT(names, i ) ); 1023 } 1024 result = i; 1025 for( it = last ; it < this_end; ++it, ++target_it, i++ ){ 1026 *target_it = *it ; 1027 SET_STRING_ELT( newnames, i, STRING_ELT(names, i + nremoved ) ); 1028 } 1029 target.attr("names" ) = newnames ; 1030 } 1031 Storage::set__( target.get__() ) ; 1032 1033 return begin() + result; 1034 1035 } 1036 1037 template <typename T> assign_sugar_expression(const T & x)1038 inline void assign_sugar_expression( const T& x ) { 1039 R_xlen_t n = size() ; 1040 if( n == x.size() ){ 1041 // just copy the data 1042 import_expression<T>(x, n ) ; 1043 } else{ 1044 // different size, so we change the memory 1045 Shield<SEXP> wrapped(wrap(x)); 1046 Shield<SEXP> casted(r_cast<RTYPE>(wrapped)); 1047 Storage::set__(casted); 1048 } 1049 } 1050 1051 // sugar 1052 template <typename T> assign_object(const T & x,traits::true_type)1053 inline void assign_object( const T& x, traits::true_type ) { 1054 assign_sugar_expression( x.get_ref() ) ; 1055 } 1056 1057 // anything else 1058 template <typename T> assign_object(const T & x,traits::false_type)1059 inline void assign_object( const T& x, traits::false_type ) { 1060 Shield<SEXP> wrapped(wrap(x)); 1061 Shield<SEXP> casted(r_cast<RTYPE>(wrapped)); 1062 Storage::set__(casted); 1063 } 1064 1065 // we are importing a real sugar expression, i.e. not a vector 1066 template <bool NA, typename VEC> import_sugar_expression(const Rcpp::VectorBase<RTYPE,NA,VEC> & other,traits::false_type)1067 inline void import_sugar_expression( const Rcpp::VectorBase<RTYPE,NA,VEC>& other, traits::false_type ) { 1068 RCPP_DEBUG_4( "Vector<%d>::import_sugar_expression( VectorBase<%d,%d,%s>, false_type )", RTYPE, NA, RTYPE, DEMANGLE(VEC) ) ; 1069 R_xlen_t n = other.size() ; 1070 Storage::set__( Rf_allocVector( RTYPE, n ) ) ; 1071 import_expression<VEC>( other.get_ref() , n ) ; 1072 } 1073 1074 // we are importing a sugar expression that actually is a vector 1075 template <bool NA, typename VEC> import_sugar_expression(const Rcpp::VectorBase<RTYPE,NA,VEC> & other,traits::true_type)1076 inline void import_sugar_expression( const Rcpp::VectorBase<RTYPE,NA,VEC>& other, traits::true_type ) { 1077 RCPP_DEBUG_4( "Vector<%d>::import_sugar_expression( VectorBase<%d,%d,%s>, true_type )", RTYPE, NA, RTYPE, DEMANGLE(VEC) ) ; 1078 Storage::set__( other.get_ref() ) ; 1079 } 1080 1081 1082 template <typename T> import_expression(const T & other,R_xlen_t n)1083 inline void import_expression( const T& other, R_xlen_t n ) { 1084 iterator start = begin() ; 1085 RCPP_LOOP_UNROLL(start,other) 1086 } 1087 1088 template <typename T> fill_or_generate(const T & t)1089 inline void fill_or_generate( const T& t) { 1090 fill_or_generate__impl( t, typename traits::is_generator<T>::type() ) ; 1091 } 1092 1093 template <typename T> fill_or_generate__impl(const T & gen,traits::true_type)1094 inline void fill_or_generate__impl( const T& gen, traits::true_type) { 1095 iterator first = begin() ; 1096 iterator last = end() ; 1097 while( first != last ) *first++ = gen() ; 1098 } 1099 1100 template <typename T> fill_or_generate__impl(const T & t,traits::false_type)1101 inline void fill_or_generate__impl( const T& t, traits::false_type) { 1102 fill(t) ; 1103 } 1104 1105 template <typename U> fill__dispatch(traits::false_type,const U & u)1106 void fill__dispatch( traits::false_type, const U& u){ 1107 // when this is not trivial, this is SEXP 1108 Shield<SEXP> elem( converter_type::get( u ) ); 1109 iterator it(begin()); 1110 for( R_xlen_t i=0; i<size() ; i++, ++it){ 1111 *it = ::Rf_duplicate( elem ) ; 1112 } 1113 } 1114 1115 template <typename U> fill__dispatch(traits::true_type,const U & u)1116 void fill__dispatch( traits::true_type, const U& u){ 1117 std::fill( begin(), end(), converter_type::get( u ) ) ; 1118 } 1119 1120 public: 1121 create()1122 static Vector create(){ 1123 return Vector( 0 ) ; 1124 } 1125 1126 #include <Rcpp/generated/Vector__create.h> 1127 1128 public: 1129 eval()1130 inline SEXP eval() const { 1131 return Rcpp_fast_eval( Storage::get__(), R_GlobalEnv ) ; 1132 } 1133 eval(SEXP env)1134 inline SEXP eval(SEXP env) const { 1135 return Rcpp_fast_eval( Storage::get__(), env ); 1136 } 1137 1138 1139 } ; /* Vector */ 1140 1141 template <int RTYPE, template <class> class StoragePolicy > 1142 inline std::ostream &operator<<(std::ostream & s, const Vector<RTYPE, StoragePolicy> & rhs) { 1143 typedef Vector<RTYPE, StoragePolicy> VECTOR; 1144 1145 typename VECTOR::iterator i = const_cast<VECTOR &>(rhs).begin(); 1146 typename VECTOR::iterator iend = const_cast<VECTOR &>(rhs).end(); 1147 1148 if (i != iend) { 1149 s << (*i); 1150 ++i; 1151 1152 for ( ; i != iend; ++i) { 1153 s << " " << (*i); 1154 } 1155 } 1156 1157 return s; 1158 } 1159 1160 template<template <class> class StoragePolicy > 1161 inline std::ostream &operator<<(std::ostream & s, const Vector<STRSXP, StoragePolicy> & rhs) { 1162 typedef Vector<STRSXP, StoragePolicy> VECTOR; 1163 1164 typename VECTOR::iterator i = const_cast<VECTOR &>(rhs).begin(); 1165 typename VECTOR::iterator iend = const_cast<VECTOR &>(rhs).end(); 1166 1167 if (i != iend) { 1168 s << "\"" << (*i) << "\""; 1169 ++i; 1170 1171 for ( ; i != iend; ++i) { 1172 s << " \"" << (*i) << "\""; 1173 } 1174 } 1175 1176 return s; 1177 } 1178 1179 } 1180 1181 #endif 1182