1 /*!
2  * \file   include/TFEL/Math/Vector/VectorUtilities.hxx
3  * \brief  This file implements various helper functions used by tvector.
4  * \author Thomas Helfer
5  * \date   05 May 2006
6  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
7  * reserved.
8  * This project is publicly released under either the GNU GPL Licence
9  * or the CECILL-A licence. A copy of thoses licences are delivered
10  * with the sources of TFEL. CEA or EDF may also distribute this
11  * project under specific licensing conditions.
12  */
13 
14 #ifndef LIB_TFEL_VECTOR_UTILITIES_HXX
15 #define LIB_TFEL_VECTOR_UTILITIES_HXX
16 
17 #include"TFEL/Config/TFELConfig.hxx"
18 
19 namespace tfel{
20 
21   namespace math {
22 
23     /*!
24      * \brief the class VectorUtilities contains a set of functions to
25      * be applied to every item of a vector.
26      * Those functions are implemented recursively and inlined.
27      * \tparam N : index treated
28      */
29     template<unsigned short N>
30     struct VectorUtilities{
31       /*!
32        * \brief copy the element of a vector in another vector
33        * \tparam T    : type of the copied vector
34        * \tparam T2   : type of the destination vector
35        * \param[in] a : source vector
36        * \param[in] b : destination vector
37        * \pre T value type must be assignable to T2 value type
38        */
39       template<typename T, typename T2>
40       static TFEL_MATH_INLINE
copytfel::math::VectorUtilities41       void copy(const T& a, T2& b){
42 	b(N-1) = a(N-1);
43 	VectorUtilities<N-1>::copy(a,b);
44       }
45       /*!
46        * \brief add the element of a vector to the element of another
47        * vector so that b(N-1)+=a(N-1)
48        * \tparam T    : type of the modified vector
49        * \tparam T2   : type of the added vector
50        * \param[in] b : result vector
51        * \param[in] a : vector added to b
52        * \pre T2 value type must be assignable to T value type
53        */
54       template<typename T, typename T2>
55       static TFEL_MATH_INLINE
PlusEqualtfel::math::VectorUtilities56       void PlusEqual(T& b, const T2& a){
57 	b(N-1) += a(N-1);
58 	VectorUtilities<N-1>::PlusEqual(b,a);
59       }
60 
61       template<typename T, typename T2>
62       static TFEL_MATH_INLINE
MinusEqualtfel::math::VectorUtilities63       void MinusEqual(T& b, const T2& a){
64 	b(N-1) -= a(N-1);
65 	VectorUtilities<N-1>::MinusEqual(b,a);
66       }
67 
68       template<typename T, typename T2>
69       static TFEL_MATH_INLINE
MultEqualtfel::math::VectorUtilities70       void MultEqual(T& b, const T2& a){
71 	b(N-1) *= a(N-1);
72 	VectorUtilities<N-1>::MinusEqual(b,a);
73       }
74 
75       template<typename T, typename T2>
76       static TFEL_MATH_INLINE
assign_to_scalartfel::math::VectorUtilities77       void assign_to_scalar(T& a, const T2& b){
78 	a(N-1) = b;
79 	VectorUtilities<N-1>::assign_to_scalar(a,b);
80       }
81 
82       template<typename T, typename T2>
83       static TFEL_MATH_INLINE
scaletfel::math::VectorUtilities84       void scale(T& a, const T2& b){
85 	a(N-1) *= b;
86 	VectorUtilities<N-1>::scale(a,b);
87       }
88     };
89     /*!
90      * \brief This partial specialisation for N=0 is used to end the
91      * recursion
92      */
93     template<>
94     struct VectorUtilities<0u>{
95 
96       template<typename T, typename T2>
97       static TFEL_MATH_INLINE
copytfel::math::VectorUtilities98       void copy(const T&, T2&){}
99 
100       template<typename T, typename T2>
101       static TFEL_MATH_INLINE
PlusEqualtfel::math::VectorUtilities102       void PlusEqual(T&, const T2&){}
103 
104       template<typename T, typename T2>
105       static TFEL_MATH_INLINE
MinusEqualtfel::math::VectorUtilities106       void MinusEqual(T&, const T2&){}
107 
108       template<typename T, typename T2>
109       static TFEL_MATH_INLINE
MultEqualtfel::math::VectorUtilities110       void MultEqual(T&, const T2&){}
111 
112       template<typename T, typename T2>
113       static TFEL_MATH_INLINE
assign_to_scalartfel::math::VectorUtilities114       void assign_to_scalar(T&, const T2&){}
115 
116       template<typename T, typename T2>
117       static TFEL_MATH_INLINE
scaletfel::math::VectorUtilities118       void scale(T&, const T2&){}
119 
120     };
121 
122     /*!
123      * \brief This structure copy a vector to an array
124      * \tparam N : size of the array to be copied
125      */
126     template<unsigned short N>
127     struct vectorToTab{
128       /*!
129        * copy a vector to its destination
130        * \tparam T       : vector type of the source
131        * \tparam T2      : array type of the destination
132        * \param[in] src  : source
133        * \param[in] dest : destination
134        * \pre the destination vector must be greater than the source vector.
135        * \pre the value type of T must be assignable to the value type T2.
136        */
137       template<typename T,typename T2>
138       static TFEL_MATH_INLINE
exetfel::math::vectorToTab139       void exe(const T& src, T2& dest)
140       {
141 	dest[N-1] = src(N-1);
142 	vectorToTab<N-1>::exe(src,dest);
143       }
144     };
145     /*!
146      * \brief partial specialisation for N=0 to end the recursion.
147      */
148     template<>
149     struct vectorToTab<0u>{
150       /*!
151        * copy a vector to its destination
152        * \tparam T       : vector type of the source
153        * \tparam T2      : array type of the destination
154        */
155       template<typename T,typename T2>
156       static TFEL_MATH_INLINE
exetfel::math::vectorToTab157       void exe(T&, T2&)
158       {}
159     };
160 
161     /*!
162      * \brief partial specialisation for N=1.
163      */
164     template<>
165     struct vectorToTab<1u>{
166       /*!
167        * copy a vector to its destination
168        * \tparam T       : vector type of the source
169        * \tparam T2      : array type of the destination
170        * \param[in] src  : source
171        * \param[in] dest : destination
172        * \pre the destination vector must be greater than the source vector.
173        * \pre the value type of T must be assignable to the value type T2.
174        */
175       template<typename T,typename T2>
176       static TFEL_MATH_INLINE
exetfel::math::vectorToTab177       void exe(const T& src, T2& dest)
178       {
179 	dest[0] = src(0);
180       }
181     };
182     /*!
183      * \brief partial specialisation for N=2.
184      */
185     template<>
186     struct vectorToTab<2u>{
187       /*!
188        * copy a vector to its destination
189        * \tparam T       : vector type of the source
190        * \tparam T2      : array type of the destination
191        * \param[in] src  : source
192        * \param[in] dest : destination
193        * \pre the destination vector must be greater than the source vector.
194        * \pre the value type of T must be assignable to the value type T2.
195        */
196       template<typename T,typename T2>
197       static TFEL_MATH_INLINE
exetfel::math::vectorToTab198       void exe(const T& src, T2& dest)
199       {
200 	dest[1] = src(1);
201 	dest[0] = src(0);
202       }
203     };
204     /*!
205      * \brief partial specialisation for N=3.
206      */
207     template<>
208     struct vectorToTab<3u>{
209       /*!
210        * copy a vector to its destination
211        * \tparam T       : vector type of the source
212        * \tparam T2      : array type of the destination
213        * \param[in] src  : source
214        * \param[in] dest : destination
215        * \pre the destination vector must be greater than the source vector.
216        * \pre the value type of T must be assignable to the value type T2.
217        */
218       template<typename T,typename T2>
219       static TFEL_MATH_INLINE
exetfel::math::vectorToTab220       void exe(const T& src, T2& dest)
221       {
222 	dest[2] = src(2);
223 	dest[1] = src(1);
224 	dest[0] = src(0);
225       }
226     };
227     /*!
228      * \brief partial specialisation for N=4.
229      */
230     template<>
231     struct vectorToTab<4u>{
232       /*!
233        * copy a vector to its destination
234        * \tparam T       : vector type of the source
235        * \tparam T2      : array type of the destination
236        * \param[in] src  : source
237        * \param[in] dest : destination
238        * \pre the destination vector must be greater than the source vector.
239        * \pre the value type of T must be assignable to the value type T2.
240        */
241       template<typename T,typename T2>
242       static TFEL_MATH_INLINE
exetfel::math::vectorToTab243       void exe(const T& src, T2& dest)
244       {
245 	dest[3] = src(3);
246 	dest[2] = src(2);
247 	dest[1] = src(1);
248 	dest[0] = src(0);
249       }
250     };
251     /*!
252      * \brief partial specialisation for N=5.
253      */
254     template<>
255     struct vectorToTab<5u>{
256       /*!
257        * copy a vector to its destination
258        * \tparam T       : vector type of the source
259        * \tparam T2      : array type of the destination
260        * \param[in] src  : source
261        * \param[in] dest : destination
262        * \pre the destination vector must be greater than the source vector.
263        * \pre the value type of T must be assignable to the value type T2.
264        */
265       template<typename T,typename T2>
266       static TFEL_MATH_INLINE
exetfel::math::vectorToTab267       void exe(const T& src, T2& dest)
268       {
269 	dest[4] = src(4);
270 	dest[3] = src(3);
271 	dest[2] = src(2);
272 	dest[1] = src(1);
273 	dest[0] = src(0);
274       }
275     };
276     /*!
277      * \brief partial specialisation for N=6.
278      */
279     template<>
280     struct vectorToTab<6u>{
281       /*!
282        * copy a vector to its destination
283        * \tparam T       : vector type of the source
284        * \tparam T2      : array type of the destination
285        * \param[in] src  : source
286        * \param[in] dest : destination
287        * \pre the destination vector must be greater than the source vector.
288        * \pre the value type of T must be assignable to the value type T2.
289        */
290       template<typename T,typename T2>
291       static TFEL_MATH_INLINE
exetfel::math::vectorToTab292       void exe(const T& src, T2& dest)
293       {
294 	dest[5] = src(5);
295 	dest[4] = src(4);
296 	dest[3] = src(3);
297 	dest[2] = src(2);
298 	dest[1] = src(1);
299 	dest[0] = src(0);
300       }
301     };
302     /*!
303      * \brief partial specialisation for N=7.
304      */
305     template<>
306     struct vectorToTab<7u>{
307       /*!
308        * copy a vector to its destination
309        * \tparam T       : vector type of the source
310        * \tparam T2      : array type of the destination
311        * \param[in] src  : source
312        * \param[in] dest : destination
313        * \pre the destination vector must be greater than the source vector.
314        * \pre the value type of T must be assignable to the value type T2.
315        */
316       template<typename T,typename T2>
317       static TFEL_MATH_INLINE
exetfel::math::vectorToTab318       void exe(const T& src, T2& dest)
319       {
320 	dest[6] = src(6);
321 	dest[5] = src(5);
322 	dest[4] = src(4);
323 	dest[3] = src(3);
324 	dest[2] = src(2);
325 	dest[1] = src(1);
326 	dest[0] = src(0);
327       }
328     };
329     /*!
330      * \brief Partial specialisation of the vectorToTab class for N=8.
331      */
332     template<>
333     struct vectorToTab<8u>{
334       /*!
335        * copy a vector to its destination
336        * \tparam T       : vector type of the source
337        * \tparam T2      : array type of the destination
338        * \param[in] src  : source
339        * \param[in] dest : destination
340        * \pre the destination vector must be greater than the source vector.
341        * \pre the value type of T must be assignable to the value type T2.
342        */
343       template<typename T,typename T2>
344       static TFEL_MATH_INLINE
exetfel::math::vectorToTab345       void exe(const T& src, T2& dest)
346       {
347 	dest[7] = src(7);
348 	dest[6] = src(6);
349 	dest[5] = src(5);
350 	dest[4] = src(4);
351 	dest[3] = src(3);
352 	dest[2] = src(2);
353 	dest[1] = src(1);
354 	dest[0] = src(0);
355       }
356     };
357     /*!
358      * \brief partial specialisation for N=9.
359      */
360     template<>
361     struct vectorToTab<9u>{
362       /*!
363        * copy a vector to its destination
364        * \tparam T       : vector type of the source
365        * \tparam T2      : array type of the destination
366        * \param[in] src  : source
367        * \param[in] dest : destination
368        * \pre the destination vector must be greater than the source vector.
369        * \pre the value type of T must be assignable to the value type T2.
370        */
371       template<typename T,typename T2>
372       static TFEL_MATH_INLINE
exetfel::math::vectorToTab373       void exe(const T& src, T2& dest)
374       {
375 	dest[8] = src(8);
376 	dest[7] = src(7);
377 	dest[6] = src(6);
378 	dest[5] = src(5);
379 	dest[4] = src(4);
380 	dest[3] = src(3);
381 	dest[2] = src(2);
382 	dest[1] = src(1);
383 	dest[0] = src(0);
384       }
385     };
386     /*!
387      * \brief partial specialisation for N=10.
388      */
389     template<>
390     struct vectorToTab<10u>{
391       /*!
392        * copy a vector to its destination
393        * \tparam T       : vector type of the source
394        * \tparam T2      : array type of the destination
395        * \param[in] src  : source
396        * \param[in] dest : destination
397        * \pre the destination vector must be greater than the source vector.
398        * \pre the value type of T must be assignable to the value type T2.
399        */
400       template<typename T,typename T2>
401       static TFEL_MATH_INLINE
exetfel::math::vectorToTab402       void exe(const T& src, T2& dest)
403       {
404 	dest[9] = src(9);
405 	dest[8] = src(8);
406 	dest[7] = src(7);
407 	dest[6] = src(6);
408 	dest[5] = src(5);
409 	dest[4] = src(4);
410 	dest[3] = src(3);
411 	dest[2] = src(2);
412 	dest[1] = src(1);
413 	dest[0] = src(0);
414       }
415     };
416 
417   } // end of namespace math
418 
419 } // end of namespace tfel
420 
421 #endif /* LIB_TFEL_VECTOR_UTILITIES_HXX */
422 
423