Chombo + EB  3.0
Metaprograms.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 // These are about ten times faster than the STL analogues, since here the
12 // number of elements is known at compile time. These functions are as
13 // fast as hand-unrolled loops (but you need -O3 or better on gcc).
14 //
15 // For examples, see lib/src/BoxTools/BaseFabImplem.H in the "template" branch
16 // of the Chombo_prev module under ~tdsternberg/my-cvsroot.
17 //
18 // Author: Ted
19 //
20 
21 #ifndef _METAPROGRAMS_H_
22 #define _METAPROGRAMS_H_
23 
24 #include <functional>
25 
26 namespace Metaprograms
27 {
28 
29 template<typename T> struct Identity
30 {
31  T const& operator()( T const& t )
32  {
33  return t;
34  }
35 };
36 
37 //-------------------------------------------------------------------
38 template<int N, typename T, typename RT, typename PlusT, typename TimesT>
40 {
41  //
42  // Binary mode with null-constructed functors.
43  //
44  RT operator()( T const* v1, T const* v2 )
45  {
46  return PlusT()( InnerProduct<N-1,T,RT,PlusT,TimesT>()(v1,v2),
47  TimesT()(v1[N-1],v2[N-1]) );
48  }
49  RT operator()( T const* v, T const& x )
50  {
51  return PlusT()( InnerProduct<N-1,T,RT,PlusT,TimesT>()(v,x),
52  TimesT()(v[N-1],x) );
53 
54  }
55 };
56 
57 template<typename PlusT, typename T, typename RT, typename TimesT>
58 struct InnerProduct<1,T,RT,PlusT,TimesT>
59 {
60  RT operator()( T const* v1, T const* v2 )
61  {
62  return TimesT()( v1[0], v2[0] );
63  }
64  RT operator()( T const* v, T const& x )
65  {
66  return TimesT()( v[0], x );
67  }
68 };
69 //-------------------------------------------------------------------
70 
71 //-------------------------------------------------------------------
72 template<int N, typename T, typename CompareT>
73 inline bool pointwiseCompare( T const* v1, T const* v2 )
74 {
75  return InnerProduct< N,T,bool,
76  std::logical_and<bool>,
77  CompareT >()( v1, v2 );
78 }
79 
80 template<int N, typename T, typename CompareT>
81 inline bool pointwiseCompare( T const* v, T const& x )
82 {
83  return InnerProduct< N,T,bool,
84  std::logical_and<bool>,
85  CompareT >()( v, x );
86 }
87 //-------------------------------------------------------------------
88 
89 //-------------------------------------------------------------------
90 template<int N, typename T, typename ReduceT, typename TransformT=Identity<T> >
91 struct Accum
92 {
93  T operator()( T const * v ) const
94  {
95  return ReduceT()( TransformT()(v[N-1]), Accum<N-1,T,ReduceT,TransformT>()(v) );
96  }
97 
98  // Stateful TransformT
99  T operator()( T const * v, TransformT const& xform ) const
100  {
101  return ReduceT()( xform(v,N-1), Accum<N-1,T,ReduceT,TransformT>()(v,xform) );
102  }
103 };
104 
105 template<typename T, typename ReduceT, typename TransformT >
106 struct Accum<1,T,ReduceT,TransformT>
107 {
108  T operator()( T const * v ) const
109  {
110  return TransformT()(v[0]);
111  }
112 
113  // Stateful TransformT
114  T operator()( T const * v, TransformT const& xform ) const
115  {
116  return xform(v,0);
117  }
118 };
119 //-------------------------------------------------------------------
120 
121 //-------------------------------------------------------------------
122 template<int N, typename T> struct LexLT
123 {
124  bool operator()( const T* v1, const T* v2 )
125  {
126  return doit( v1+N, v2+N );
127  }
128 
129  static bool doit( const T* v1, const T* v2 )
130  {
131  if ( v1[-N] < v2[-N] ) return true;
132  else if ( v1[-N] > v2[-N] ) return false;
133  else return LexLT<N-1,T>::doit(v1,v2);
134  }
135 };
136 
137 
138 template<typename T> struct LexLT<1,T>
139 {
140  bool operator()( const T* v1, const T* v2 )
141  {
142  return doit(v1,v2);
143  }
144  static bool doit( const T* v1, const T* v2 )
145  {
146  if ( v1[-1] < v2[-1] ) return true;
147  else return false;
148  }
149 };
150 //-------------------------------------------------------------------
151 
152 //-------------------------------------------------------------------
153 template<int N, typename T, typename FunctorT> struct Transform
154 {
155  void operator()( T* v )
156  {
157  v[N-1] = FunctorT()(v[N-1]);
158  Transform<N-1,T,FunctorT>()(v);
159  }
160  void operator()( T* v, const T& x )
161  {
162  v[N-1] = FunctorT()(v[N-1],x);
163  Transform<N-1,T,FunctorT>()(v,x);
164  }
165  void operator()( T* v1, const T* v2 )
166  {
167  v1[N-1] = FunctorT()(v1[N-1],v2[N-1]);
168  Transform<N-1,T,FunctorT>()(v1,v2);
169  }
170 };
171 
172 template<typename T, typename FunctorT> struct Transform<1,T,FunctorT>
173 {
174  void operator()( T* v )
175  {
176  v[0] = FunctorT()(v[0]);
177  }
178  void operator()( T* v, const T& x )
179  {
180  v[0] = FunctorT()(v[0],x);
181  }
182  void operator()( T* v1, const T* v2 )
183  {
184  v1[0] = FunctorT()(v1[0],v2[0]);
185  }
186 };
187 //-------------------------------------------------------------------
188 
189 
190 //-------------------------------------------------------------------
191 template<int N, int P> struct Pow
192 {
193  static const int value = N * Pow<N,P-1>::value;
194 };
195 
196 template<int N> struct Pow<N,1>
197 {
198  static const int value = N;
199 };
200 //-------------------------------------------------------------------
201 
202 //-------------------------------------------------------------------
203 /**
204  Arbitrarily deep nested loop.
205  Example: This code will print all the integers from 0 to B^N-1, in base B:
206 
207  template<int N> struct BaseRep
208  {
209  void operator()( int* index )
210  {
211  for ( int i=N-1; i>=0; --i ) std::cout << index[i];
212  std::cout << '\n';
213  }
214  };
215 
216  main()
217  {
218  #define N 4
219  #define B 3
220  int index[N];
221  BaseRep<N> op;
222  Metaprograms::NestedLoop< N,BaseRep<N> >()( index, 0, B, op );
223  }
224 */
225 template<int N, class OP> struct NestedLoop
226 {
227  void operator()( int * index, int lo, int hi, OP& op ) const
228  {
229  for ( index[N-1]=lo; index[N-1]<hi; ++index[N-1] )
230  {
231  NestedLoop<N-1,OP>()( index, lo, hi, op );
232  }
233  }
234  void operator()( int * index, const int * lo, const int * hi, OP& op ) const
235  {
236  for ( index[N-1]=lo[N-1]; index[N-1]<hi[N-1]; ++index[N-1] )
237  {
238  NestedLoop<N-1,OP>()( index, lo, hi, op );
239  }
240  }
241 };
242 
243 
244 template<class OP> struct NestedLoop<0,OP>
245 {
246  void operator()( int * index, int lo, int hi, OP& op ) const
247  {
248  op( index );
249  }
250  void operator()( int * index, const int * lo, const int * hi, OP& op ) const
251  {
252  op( index );
253  }
254 };
255 //-------------------------------------------------------------------
256 
257 //-------------------------------------------------------------------
258 template<int N, class OP> struct NestedPrestagedLoop
259 {
260  void operator()( int * index, int lo, int hi, OP& op ) const
261  {
262  for ( index[N-1]=lo; index[N-1]<hi; ++index[N-1] )
263  {
264  op.prestage(N-1);
265  NestedPrestagedLoop<N-1,OP>()( index, lo, hi, op );
266  }
267  }
268  void operator()( int * index, const int * lo, const int * hi, OP& op ) const
269  {
270  for ( index[N-1]=lo[N-1]; index[N-1]<hi[N-1]; ++index[N-1] )
271  {
272  op.prestage(N-1);
273  NestedPrestagedLoop<N-1,OP>()( index, lo, hi, op );
274  }
275  }
276 };
277 
278 
279 template<class OP> struct NestedPrestagedLoop<0,OP>
280 {
281  void operator()( int * index, int lo, int hi, OP& op ) const
282  {
283  op( index );
284  }
285  void operator()( int * index, const int * lo, const int * hi, OP& op ) const
286  {
287  op( index );
288  }
289 };
290 //-------------------------------------------------------------------
291 
292 //-------------------------------------------------------------------
293 /** Named for defunct D_TERM macro.
294  * Applies an operation once for n = 0,...N-1.
295 */
296 template<int N, class OP> struct dterm
297 {
298  void operator()( OP& op ) const
299  {
300  dterm<N-1,OP>()( op );
301  op( N-1 );
302  }
303 };
304 
305 template<class OP> struct dterm<1,OP>
306 {
307  void operator()( OP& op ) const
308  {
309  op( 0 );
310  }
311 };
312 //-------------------------------------------------------------------
313 
314 } // namespace Metaprograms
315 
316 #endif // include guard
T const & operator()(T const &t)
Definition: Metaprograms.H:31
bool operator()(const T *v1, const T *v2)
Definition: Metaprograms.H:140
void operator()(OP &op) const
Definition: Metaprograms.H:298
static bool doit(const T *v1, const T *v2)
Definition: Metaprograms.H:129
Definition: Metaprograms.H:258
void operator()(int *index, int lo, int hi, OP &op) const
Definition: Metaprograms.H:246
Definition: Metaprograms.H:153
RT operator()(T const *v1, T const *v2)
Definition: Metaprograms.H:60
RT operator()(T const *v, T const &x)
Definition: Metaprograms.H:64
T operator()(T const *v, TransformT const &xform) const
Definition: Metaprograms.H:114
Definition: Metaprograms.H:296
void operator()(int *index, int lo, int hi, OP &op) const
Definition: Metaprograms.H:260
void operator()(T *v1, const T *v2)
Definition: Metaprograms.H:165
void operator()(int *index, const int *lo, const int *hi, OP &op) const
Definition: Metaprograms.H:250
Definition: Metaprograms.H:225
void operator()(int *index, const int *lo, const int *hi, OP &op) const
Definition: Metaprograms.H:268
void operator()(int *index, const int *lo, const int *hi, OP &op) const
Definition: Metaprograms.H:234
void operator()(int *index, const int *lo, const int *hi, OP &op) const
Definition: Metaprograms.H:285
void operator()(T *v)
Definition: Metaprograms.H:155
T operator()(T const *v, TransformT const &xform) const
Definition: Metaprograms.H:99
void operator()(T *v1, const T *v2)
Definition: Metaprograms.H:182
void operator()(int *index, int lo, int hi, OP &op) const
Definition: Metaprograms.H:281
Definition: Metaprograms.H:29
void operator()(int *index, int lo, int hi, OP &op) const
Definition: Metaprograms.H:227
Definition: Metaprograms.H:26
static bool doit(const T *v1, const T *v2)
Definition: Metaprograms.H:144
void operator()(T *v, const T &x)
Definition: Metaprograms.H:160
Definition: Metaprograms.H:122
Definition: Metaprograms.H:39
RT operator()(T const *v, T const &x)
Definition: Metaprograms.H:49
Definition: Metaprograms.H:91
Definition: Metaprograms.H:191
RT operator()(T const *v1, T const *v2)
Definition: Metaprograms.H:44
T operator()(T const *v) const
Definition: Metaprograms.H:93
void operator()(OP &op) const
Definition: Metaprograms.H:307
T operator()(T const *v) const
Definition: Metaprograms.H:108
void operator()(T *v, const T &x)
Definition: Metaprograms.H:178
bool operator()(const T *v1, const T *v2)
Definition: Metaprograms.H:124
void operator()(T *v)
Definition: Metaprograms.H:174
bool pointwiseCompare(T const *v1, T const *v2)
Definition: Metaprograms.H:73