Hex  1.0
Hydrogen-electron collision solver
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
arrithm.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2  * *
3  * / / / / __ \ \ / / *
4  * / /__ / / / _ \ \ \/ / *
5  * / ___ / | |/_/ / /\ \ *
6  * / / / / \_\ / / \ \ *
7  * *
8  * Jakub Benda (c) 2014 *
9  * Charles University in Prague *
10  * *
11 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12 
13 #ifndef HEX_ARRITHM
14 #define HEX_ARRITHM
15 
16 #include <type_traits>
17 
18 #include "arrays.h"
19 #include "misc.h"
20 
21 //
22 // unary operators
23 //
24 
25 #define declareDeepUnaryOperatorTemplates(IN,OP) \
26  \
27 template <class T> \
28 IN<T> operator OP (IN<T> const & a) \
29 { \
30  IN<T> b(a); \
31  for (T & e : b) \
32  e = OP e; \
33  return b; \
34 }
35 
37 
38 //
39 // reduced arithmetic operators
40 //
41 
42 #define declareDeepReducedArithmeticTemplates(OUT,OP,IN) \
43  \
44 template < \
45  class T1, \
46  class T2, \
47  class = typename std::enable_if<is_scalar<T2>::value>::type \
48 > OUT<T1> operator OP##= (OUT<T1> & a, T2 const & b) \
49 { \
50  T1 * restrict pa = a.data(); \
51  \
52  size_t N = a.size(); \
53  for (size_t i = 0; i < N; i++) \
54  pa[i] OP##= b; \
55  \
56  return a; \
57 } \
58  \
59 template <class T1, class T2> \
60 OUT<T1> operator OP##= (OUT<T1> & a, IN<T2> const & b) \
61 { \
62  assert(a.size() == b.size()); \
63  \
64  T1 * restrict pa = a.data(); \
65  T2 const * restrict pb = b.data(); \
66  \
67  size_t N = a.size(); \
68  for (size_t i = 0; i < N; i++) \
69  pa[i] OP##= pb[i]; \
70  \
71  return a; \
72 }
73 
76 declareDeepReducedArithmeticTemplates(NumberArray, *, NumberArray)
77 declareDeepReducedArithmeticTemplates(NumberArray, /, NumberArray)
78 
79 #define declareShallowReducedArithmeticTemplates(OUT,OP,IN) \
80  \
81 template < \
82  class T1, \
83  class T2, \
84  class = typename std::enable_if<is_scalar<T2>::value>::type \
85 > OUT<T1> operator OP##= (OUT<T1> a, T2 const & b) \
86 { \
87  T1 * restrict pa = a.data(); \
88  \
89  size_t N = a.size(); \
90  for (size_t i = 0; i < N; i++) \
91  pa[i] OP##= b; \
92  \
93  return a; \
94 } \
95  \
96 template <class T1, class T2> \
97 OUT<T1> operator OP##= (OUT<T1> a, IN<T2> b) \
98 { \
99  assert(a.size() == b.size()); \
100  \
101  T1 * restrict pa = a.data(); \
102  T2 const * restrict pb = b.data(); \
103  \
104  size_t N = a.size(); \
105  for (size_t i = 0; i < N; i++) \
106  pa[i] OP##= pb[i]; \
107  \
108  return a; \
109 }
110 
113 declareShallowReducedArithmeticTemplates(ArrayView, *, ArrayView)
114 declareShallowReducedArithmeticTemplates(ArrayView, /, ArrayView)
115 
116 //
117 // binary arithmetic operators for NumberArray
118 //
119 
120 #define declareDeepBinaryOperatorTemplates(OUT,OP,IN) \
121  \
122 template < \
123  class T1, \
124  class T2, \
125  class T3 = decltype(T1(1) OP T2(1)) \
126 > OUT<T3> operator OP (IN<T1> const & a, IN<T2> const & b) \
127 { \
128  assert(a.size() == b.size()); \
129  \
130  size_t N = a.size(); \
131  OUT<T3> c(N); \
132  \
133  T1 const * restrict pa = a.data(); \
134  T2 const * restrict pb = b.data(); \
135  T3 * restrict pc = c.data(); \
136  \
137  for (size_t i = 0; i < N; i++) \
138  pc[i] = pa[i] OP pb[i]; \
139  \
140  return c; \
141 } \
142  \
143 template < \
144  class T1, \
145  class T2, \
146  class T3 = decltype(T1(1) OP T2(1)), \
147  class = typename std::enable_if<is_scalar<T2>::value>::type \
148 > OUT<T3> operator OP (IN<T1> const & a, T2 const & b) \
149 { \
150  size_t N = a.size(); \
151  OUT<T3> c(N); \
152  \
153  T1 const * restrict pa = a.data(); \
154  T3 * restrict pc = c.data(); \
155  \
156  for (size_t i = 0; i < N; i++) \
157  pc[i] = pa[i] OP b; \
158  \
159  return c; \
160 } \
161 template < \
162  class T1, \
163  class T2, \
164  class T3 = decltype(T1(1) OP T2(1)), \
165  class = typename std::enable_if<is_scalar<T1>::value>::type \
166 > OUT<T3> operator OP (T1 const & a, IN<T2> const & b) \
167 { \
168  size_t N = b.size(); \
169  OUT<T3> c(N); \
170  \
171  T2 const * restrict pb = b.data(); \
172  T3 * restrict pc = c.data(); \
173  \
174  for (size_t i = 0; i < N; i++) \
175  pc[i] = a OP pb[i]; \
176  \
177  return c; \
178 } \
179 
180 declareDeepBinaryOperatorTemplates(NumberArray, +, NumberArray)
181 declareDeepBinaryOperatorTemplates(NumberArray, -, NumberArray)
182 declareDeepBinaryOperatorTemplates(NumberArray, *, NumberArray)
183 declareDeepBinaryOperatorTemplates(NumberArray, /, NumberArray)
184 
186 declareDeepBinaryOperatorTemplates(Array, -, ArrayView)
187 declareDeepBinaryOperatorTemplates(Array, *, ArrayView)
188 declareDeepBinaryOperatorTemplates(Array, /, ArrayView)
189 
190 #endif
Array view.
Definition: arrays.h:186
#define declareDeepBinaryOperatorTemplates(OUT, OP, IN)
Definition: arrithm.h:120
A comfortable number array class.
Definition: arrays.h:171
#define declareDeepReducedArithmeticTemplates(OUT, OP, IN)
Definition: arrithm.h:42
#define declareShallowReducedArithmeticTemplates(OUT, OP, IN)
Definition: arrithm.h:79
#define declareDeepUnaryOperatorTemplates(IN, OP)
Definition: arrithm.h:25
A comfortable data array class.
Definition: arrays.h:151