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