1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 4 -*- 2 // 3 // plus.h: Rcpp R/C++ interface class library -- operator+ 4 // 5 // Copyright (C) 2010 - 2011 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__sugar__plus_h 23 #define Rcpp__sugar__plus_h 24 25 namespace Rcpp{ 26 namespace sugar{ 27 28 template <int RTYPE, bool LHS_NA, typename LHS_T, bool RHS_NA, typename RHS_T > 29 class Plus_Vector_Vector : public Rcpp::VectorBase<RTYPE, true , Plus_Vector_Vector<RTYPE,LHS_NA,LHS_T,RHS_NA,RHS_T> > { 30 public: 31 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 32 typedef typename Rcpp::VectorBase<RTYPE,LHS_NA,LHS_T> LHS_TYPE ; 33 typedef typename Rcpp::VectorBase<RTYPE,RHS_NA,RHS_T> RHS_TYPE ; 34 35 typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; 36 typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; 37 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)38 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 39 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} 40 41 inline STORAGE operator[]( R_xlen_t i ) const { 42 STORAGE lhs_ = lhs[i] ; 43 if( traits::is_na<RTYPE>(lhs_) ) return lhs_ ; 44 STORAGE rhs_ = rhs[i] ; 45 return traits::is_na<RTYPE>(rhs_) ? rhs_ : (lhs_ + rhs_) ; 46 } 47 size()48 inline R_xlen_t size() const { return lhs.size() ; } 49 50 private: 51 const LHS_EXT& lhs ; 52 const RHS_EXT& rhs ; 53 } ; 54 // specialization of the above for REALSXP because : 55 // NA_REAL + NA_REAL = NA_REAL 56 // NA_REAL + x = NA_REAL 57 // x + NA_REAL = NA_REAL 58 template <bool LHS_NA, typename LHS_T, bool RHS_NA, typename RHS_T > 59 class Plus_Vector_Vector<REALSXP,LHS_NA,LHS_T,RHS_NA,RHS_T> : 60 public Rcpp::VectorBase<REALSXP, true , Plus_Vector_Vector<REALSXP,LHS_NA,LHS_T,RHS_NA,RHS_T> > { 61 public: 62 typedef typename Rcpp::VectorBase<REALSXP,LHS_NA,LHS_T> LHS_TYPE ; 63 typedef typename Rcpp::VectorBase<REALSXP,RHS_NA,RHS_T> RHS_TYPE ; 64 65 typedef typename Rcpp::traits::Extractor<REALSXP, LHS_NA, LHS_T>::type LHS_EXT ; 66 typedef typename Rcpp::traits::Extractor<REALSXP, RHS_NA, RHS_T>::type RHS_EXT ; 67 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)68 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 69 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()) {} 70 71 inline double operator[]( R_xlen_t i ) const { 72 return lhs[i] + rhs[i] ; 73 } 74 size()75 inline R_xlen_t size() const { return lhs.size() ; } 76 77 private: 78 const LHS_EXT& lhs ; 79 const RHS_EXT& rhs ; 80 } ; 81 82 83 84 85 // specialization LHS_NA = false 86 template <int RTYPE, typename LHS_T, bool RHS_NA, typename RHS_T > 87 class Plus_Vector_Vector<RTYPE,false,LHS_T,RHS_NA,RHS_T> : public Rcpp::VectorBase<RTYPE,true, Plus_Vector_Vector<RTYPE,false,LHS_T,RHS_NA,RHS_T> > { 88 public: 89 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 90 typedef typename Rcpp::VectorBase<RTYPE,false,LHS_T> LHS_TYPE ; 91 typedef typename Rcpp::VectorBase<RTYPE,RHS_NA,RHS_T> RHS_TYPE ; 92 93 typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; 94 typedef typename Rcpp::traits::Extractor< RTYPE, RHS_NA, RHS_T>::type RHS_EXT ; 95 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)96 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 97 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} 98 99 inline STORAGE operator[]( R_xlen_t i ) const { 100 STORAGE rhs_ = rhs[i] ; 101 if( traits::is_na<RTYPE>(rhs_) ) return rhs_ ; 102 return lhs[i] + rhs_ ; 103 } 104 size()105 inline R_xlen_t size() const { return lhs.size() ; } 106 107 private: 108 const LHS_EXT& lhs ; 109 const RHS_EXT& rhs ; 110 } ; 111 // LHS_NA = false & RTYPE = REALSXP 112 template <typename LHS_T, bool RHS_NA, typename RHS_T > 113 class Plus_Vector_Vector<REALSXP,false,LHS_T,RHS_NA,RHS_T> : 114 public Rcpp::VectorBase<REALSXP,true, Plus_Vector_Vector<REALSXP,false,LHS_T,RHS_NA,RHS_T> > { 115 public: 116 typedef typename Rcpp::VectorBase<REALSXP,false,LHS_T> LHS_TYPE ; 117 typedef typename Rcpp::VectorBase<REALSXP,RHS_NA,RHS_T> RHS_TYPE ; 118 119 typedef typename Rcpp::traits::Extractor<REALSXP, false, LHS_T>::type LHS_EXT ; 120 typedef typename Rcpp::traits::Extractor<REALSXP, RHS_NA, RHS_T>::type RHS_EXT ; 121 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)122 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 123 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} 124 125 inline double operator[]( R_xlen_t i ) const { 126 return lhs[i] + rhs[i] ; 127 } 128 size()129 inline R_xlen_t size() const { return lhs.size() ; } 130 131 private: 132 const LHS_EXT& lhs ; 133 const RHS_EXT& rhs ; 134 } ; 135 136 137 138 // specialization for RHS_NA = false 139 template <int RTYPE, bool LHS_NA, typename LHS_T, typename RHS_T > 140 class Plus_Vector_Vector<RTYPE,LHS_NA,LHS_T,false,RHS_T> : public Rcpp::VectorBase<RTYPE, true , Plus_Vector_Vector<RTYPE,LHS_NA,LHS_T,false,RHS_T> > { 141 public: 142 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 143 typedef typename Rcpp::VectorBase<RTYPE,LHS_NA,LHS_T> LHS_TYPE ; 144 typedef typename Rcpp::VectorBase<RTYPE,false,RHS_T> RHS_TYPE ; 145 146 typedef typename Rcpp::traits::Extractor< RTYPE, LHS_NA, LHS_T>::type LHS_EXT ; 147 typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; 148 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)149 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 150 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} 151 152 inline STORAGE operator[]( R_xlen_t i ) const { 153 STORAGE lhs_ = lhs[i] ; 154 if( traits::is_na<RTYPE>(lhs_) ) return lhs_ ; 155 return lhs_ + rhs[i] ; 156 } 157 size()158 inline R_xlen_t size() const { return lhs.size() ; } 159 160 private: 161 const LHS_EXT& lhs ; 162 const RHS_EXT& rhs ; 163 } ; 164 // RHS_NA = false, RTYPE = REALSXP 165 template <bool LHS_NA, typename LHS_T, typename RHS_T > 166 class Plus_Vector_Vector<REALSXP,LHS_NA,LHS_T,false,RHS_T> : 167 public Rcpp::VectorBase<REALSXP, true , Plus_Vector_Vector<REALSXP,LHS_NA,LHS_T,false,RHS_T> > { 168 public: 169 typedef typename Rcpp::VectorBase<REALSXP,LHS_NA,LHS_T> LHS_TYPE ; 170 typedef typename Rcpp::VectorBase<REALSXP,false,RHS_T> RHS_TYPE ; 171 172 typedef typename Rcpp::traits::Extractor<REALSXP, LHS_NA, LHS_T>::type LHS_EXT ; 173 typedef typename Rcpp::traits::Extractor<REALSXP, false, RHS_T>::type RHS_EXT ; 174 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)175 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 176 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} 177 178 inline double operator[]( R_xlen_t i ) const { 179 return lhs[i] + rhs[i] ; 180 } 181 size()182 inline R_xlen_t size() const { return lhs.size() ; } 183 184 private: 185 const LHS_EXT& lhs ; 186 const RHS_EXT& rhs ; 187 } ; 188 189 190 191 192 // specialization for RHS_NA = false and LHS_NA = false 193 template <int RTYPE, typename LHS_T, typename RHS_T > 194 class Plus_Vector_Vector<RTYPE,false,LHS_T,false,RHS_T> : public Rcpp::VectorBase<RTYPE, false , Plus_Vector_Vector<RTYPE,false,LHS_T,false,RHS_T> > { 195 public: 196 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 197 typedef typename Rcpp::VectorBase<RTYPE,false,LHS_T> LHS_TYPE ; 198 typedef typename Rcpp::VectorBase<RTYPE,false,RHS_T> RHS_TYPE ; 199 200 typedef typename Rcpp::traits::Extractor< RTYPE, false, LHS_T>::type LHS_EXT ; 201 typedef typename Rcpp::traits::Extractor< RTYPE, false, RHS_T>::type RHS_EXT ; 202 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)203 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 204 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} 205 206 inline STORAGE operator[]( R_xlen_t i ) const { 207 return lhs[i] + rhs[i] ; 208 } 209 size()210 inline R_xlen_t size() const { return lhs.size() ; } 211 212 private: 213 const LHS_EXT& lhs ; 214 const RHS_EXT& rhs ; 215 } ; 216 // specialization for RHS_NA = false and LHS_NA = false, RTYPE = REALSXP 217 template <typename LHS_T, typename RHS_T > 218 class Plus_Vector_Vector<REALSXP,false,LHS_T,false,RHS_T> : 219 public Rcpp::VectorBase<REALSXP, false , Plus_Vector_Vector<REALSXP,false,LHS_T,false,RHS_T> > { 220 public: 221 typedef typename Rcpp::VectorBase<REALSXP,false,LHS_T> LHS_TYPE ; 222 typedef typename Rcpp::VectorBase<REALSXP,false,RHS_T> RHS_TYPE ; 223 224 typedef typename Rcpp::traits::Extractor<REALSXP, false, LHS_T>::type LHS_EXT ; 225 typedef typename Rcpp::traits::Extractor<REALSXP, false, RHS_T>::type RHS_EXT ; 226 Plus_Vector_Vector(const LHS_TYPE & lhs_,const RHS_TYPE & rhs_)227 Plus_Vector_Vector( const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) : 228 lhs(lhs_.get_ref()), rhs(rhs_.get_ref()){} 229 230 inline double operator[]( R_xlen_t i ) const { 231 return lhs[i] + rhs[i] ; 232 } 233 size()234 inline R_xlen_t size() const { return lhs.size() ; } 235 236 private: 237 const LHS_EXT& lhs ; 238 const RHS_EXT& rhs ; 239 } ; 240 241 242 243 244 245 246 247 template <int RTYPE, bool NA, typename T> 248 class Plus_Vector_Primitive : 249 public Rcpp::VectorBase<RTYPE,true, Plus_Vector_Primitive<RTYPE,NA,T> > { 250 public: 251 typedef typename Rcpp::VectorBase<RTYPE,NA,T> VEC_TYPE ; 252 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 253 254 typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; 255 Plus_Vector_Primitive(const VEC_TYPE & lhs_,STORAGE rhs_)256 Plus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : 257 lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na<RTYPE>(rhs_) ) 258 {} 259 260 inline STORAGE operator[]( R_xlen_t i ) const { 261 if( rhs_na ) return rhs ; 262 STORAGE x = lhs[i] ; 263 return Rcpp::traits::is_na<RTYPE>(x) ? x : (x + rhs) ; 264 } 265 size()266 inline R_xlen_t size() const { return lhs.size() ; } 267 268 private: 269 const EXT& lhs ; 270 STORAGE rhs ; 271 bool rhs_na ; 272 273 } ; 274 // RTYPE = REALSXP 275 template <bool NA, typename T> 276 class Plus_Vector_Primitive<REALSXP,NA,T> : 277 public Rcpp::VectorBase<REALSXP,true, Plus_Vector_Primitive<REALSXP,NA,T> > { 278 public: 279 typedef typename Rcpp::VectorBase<REALSXP,NA,T> VEC_TYPE ; 280 typedef typename Rcpp::traits::Extractor< REALSXP, NA, T>::type EXT ; 281 Plus_Vector_Primitive(const VEC_TYPE & lhs_,double rhs_)282 Plus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : 283 lhs(lhs_.get_ref()), rhs(rhs_) 284 {} 285 286 inline double operator[]( R_xlen_t i ) const { 287 return rhs + lhs[i] ; 288 } 289 size()290 inline R_xlen_t size() const { return lhs.size() ; } 291 292 private: 293 const EXT& lhs ; 294 double rhs ; 295 } ; 296 297 298 299 template <int RTYPE, typename T> 300 class Plus_Vector_Primitive<RTYPE,false,T> : public Rcpp::VectorBase<RTYPE,false, Plus_Vector_Primitive<RTYPE,false,T> > { 301 public: 302 typedef typename Rcpp::VectorBase<RTYPE,false,T> VEC_TYPE ; 303 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 304 305 typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; 306 Plus_Vector_Primitive(const VEC_TYPE & lhs_,STORAGE rhs_)307 Plus_Vector_Primitive( const VEC_TYPE& lhs_, STORAGE rhs_ ) : 308 lhs(lhs_.get_ref()), rhs(rhs_), rhs_na( Rcpp::traits::is_na<RTYPE>(rhs_) ) {} 309 310 inline STORAGE operator[]( R_xlen_t i ) const { 311 return rhs_na ? rhs : (rhs + lhs[i] ) ; 312 } 313 size()314 inline R_xlen_t size() const { return lhs.size() ; } 315 316 private: 317 const EXT& lhs ; 318 STORAGE rhs ; 319 bool rhs_na ; 320 } ; 321 // RTYPE = REALSXP 322 template <typename T> 323 class Plus_Vector_Primitive<REALSXP,false,T> : 324 public Rcpp::VectorBase<REALSXP,false, Plus_Vector_Primitive<REALSXP,false,T> > { 325 public: 326 typedef typename Rcpp::VectorBase<REALSXP,false,T> VEC_TYPE ; 327 328 typedef typename Rcpp::traits::Extractor< REALSXP, false, T>::type EXT ; 329 Plus_Vector_Primitive(const VEC_TYPE & lhs_,double rhs_)330 Plus_Vector_Primitive( const VEC_TYPE& lhs_, double rhs_ ) : 331 lhs(lhs_.get_ref()), rhs(rhs_) {} 332 333 inline double operator[]( R_xlen_t i ) const { 334 return rhs + lhs[i] ; 335 } 336 size()337 inline R_xlen_t size() const { return lhs.size() ; } 338 339 private: 340 const EXT& lhs ; 341 double rhs ; 342 } ; 343 344 345 346 347 348 349 // Vector * nona(primitive) 350 template <int RTYPE, bool NA, typename T> 351 class Plus_Vector_Primitive_nona : public Rcpp::VectorBase<RTYPE,true, Plus_Vector_Primitive_nona<RTYPE,NA,T> > { 352 public: 353 typedef typename Rcpp::VectorBase<RTYPE,NA,T> VEC_TYPE ; 354 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 355 typedef typename Rcpp::traits::Extractor< RTYPE, NA, T>::type EXT ; 356 Plus_Vector_Primitive_nona(const VEC_TYPE & lhs_,STORAGE rhs_)357 Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : 358 lhs(lhs_.get_ref()), rhs(rhs_) 359 {} 360 361 inline STORAGE operator[]( R_xlen_t i ) const { 362 STORAGE x = lhs[i] ; 363 return Rcpp::traits::is_na<RTYPE>(x) ? x : (x + rhs) ; 364 } 365 size()366 inline R_xlen_t size() const { return lhs.size() ; } 367 368 private: 369 const EXT& lhs ; 370 STORAGE rhs ; 371 372 } ; 373 template <bool NA, typename T> 374 class Plus_Vector_Primitive_nona<REALSXP,NA,T> : 375 public Rcpp::VectorBase<REALSXP,true, Plus_Vector_Primitive_nona<REALSXP,NA,T> > { 376 public: 377 typedef typename Rcpp::VectorBase<REALSXP,NA,T> VEC_TYPE ; 378 typedef typename Rcpp::traits::Extractor<REALSXP, NA, T>::type EXT ; 379 Plus_Vector_Primitive_nona(const VEC_TYPE & lhs_,double rhs_)380 Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : 381 lhs(lhs_.get_ref()), rhs(rhs_) 382 {} 383 384 inline double operator[]( R_xlen_t i ) const { 385 return rhs + lhs[i] ; 386 } 387 size()388 inline R_xlen_t size() const { return lhs.size() ; } 389 390 private: 391 const EXT& lhs ; 392 double rhs ; 393 394 } ; 395 396 397 398 template <int RTYPE, typename T> 399 class Plus_Vector_Primitive_nona<RTYPE,false,T> : public Rcpp::VectorBase<RTYPE,false, Plus_Vector_Primitive_nona<RTYPE,false,T> > { 400 public: 401 typedef typename Rcpp::VectorBase<RTYPE,false,T> VEC_TYPE ; 402 typedef typename traits::storage_type<RTYPE>::type STORAGE ; 403 404 typedef typename Rcpp::traits::Extractor< RTYPE, false, T>::type EXT ; 405 Plus_Vector_Primitive_nona(const VEC_TYPE & lhs_,STORAGE rhs_)406 Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, STORAGE rhs_ ) : 407 lhs(lhs_.get_ref()), rhs(rhs_) {} 408 409 inline STORAGE operator[]( R_xlen_t i ) const { 410 return rhs + lhs[i] ; 411 } 412 size()413 inline R_xlen_t size() const { return lhs.size() ; } 414 415 private: 416 const EXT& lhs ; 417 STORAGE rhs ; 418 419 } ; 420 // RTYPE = REALSXP 421 template <typename T> 422 class Plus_Vector_Primitive_nona<REALSXP,false,T> : 423 public Rcpp::VectorBase<REALSXP,false, Plus_Vector_Primitive_nona<REALSXP,false,T> > { 424 public: 425 typedef typename Rcpp::VectorBase<REALSXP,false,T> VEC_TYPE ; 426 typedef typename Rcpp::traits::Extractor< REALSXP, false, T>::type EXT ; 427 Plus_Vector_Primitive_nona(const VEC_TYPE & lhs_,double rhs_)428 Plus_Vector_Primitive_nona( const VEC_TYPE& lhs_, double rhs_ ) : 429 lhs(lhs_.get_ref()), rhs(rhs_) {} 430 431 inline double operator[]( R_xlen_t i ) const { 432 return rhs + lhs[i] ; 433 } 434 size()435 inline R_xlen_t size() const { return lhs.size() ; } 436 437 private: 438 const EXT& lhs ; 439 double rhs ; 440 441 } ; 442 443 } 444 445 446 template <int RTYPE,bool NA, typename T, typename U> 447 inline typename traits::enable_if<traits::is_convertible<typename traits::remove_const_and_reference<U>::type, typename traits::storage_type<RTYPE>::type>::value, typename sugar::Plus_Vector_Primitive<RTYPE,NA,T> >::type 448 operator+( 449 const VectorBase<RTYPE,NA,T>& lhs, 450 const U &rhs 451 ) { 452 return sugar::Plus_Vector_Primitive<RTYPE,NA,T>( lhs, rhs ) ; 453 } 454 455 456 template <int RTYPE,bool NA, typename T, typename U> 457 inline typename traits::enable_if<traits::is_convertible<typename traits::remove_const_and_reference<U>::type, typename traits::storage_type<RTYPE>::type>::value, typename sugar::Plus_Vector_Primitive< RTYPE , NA , T> >::type 458 operator+( 459 const U &rhs, 460 const VectorBase<RTYPE,NA,T>& lhs 461 ) { 462 return sugar::Plus_Vector_Primitive<RTYPE,NA, T >( lhs, rhs ) ; 463 } 464 465 466 467 template <int RTYPE,bool NA, typename T, typename U> 468 inline typename traits::enable_if<traits::is_convertible<typename traits::remove_const_and_reference<U>::type, typename traits::storage_type<RTYPE>::type>::value, sugar::Plus_Vector_Primitive_nona<RTYPE,NA,T> >::type 469 operator+( 470 const VectorBase<RTYPE,NA,T>& lhs, 471 const typename sugar::NonaPrimitive< U > &rhs 472 ) { 473 return sugar::Plus_Vector_Primitive_nona<RTYPE,NA,T>( lhs, rhs ) ; 474 } 475 476 template <int RTYPE,bool NA, typename T, typename U> 477 inline typename traits::enable_if<traits::is_convertible<typename traits::remove_const_and_reference<U>::type, typename traits::storage_type<RTYPE>::type>::value, sugar::Plus_Vector_Primitive_nona< RTYPE , NA , T> >::type 478 operator+( 479 const typename sugar::NonaPrimitive< U > &rhs, 480 const VectorBase<RTYPE,NA,T>& lhs 481 ) { 482 return sugar::Plus_Vector_Primitive_nona<RTYPE,NA, T >( lhs, rhs ) ; 483 } 484 485 486 template <int RTYPE,bool LHS_NA, typename LHS_T, bool RHS_NA, typename RHS_T> 487 inline sugar::Plus_Vector_Vector< 488 RTYPE , 489 LHS_NA, LHS_T, 490 RHS_NA, RHS_T 491 > 492 operator+( 493 const VectorBase<RTYPE,LHS_NA,LHS_T>& lhs, 494 const VectorBase<RTYPE,RHS_NA,RHS_T>& rhs 495 ) { 496 return sugar::Plus_Vector_Vector< 497 RTYPE, 498 LHS_NA, LHS_T, 499 RHS_NA, RHS_T 500 >( lhs, rhs ) ; 501 } 502 503 } 504 505 #endif 506