1 // -*- C++ -*-
2 // ACL:license
3 // ----------------------------------------------------------------------
4 // This software and ancillary information (herein called "SOFTWARE")
5 // called PETE (Portable Expression Template Engine) is
6 // made available under the terms described here.  The SOFTWARE has been
7 // approved for release with associated LA-CC Number LA-CC-99-5.
8 //
9 // Unless otherwise indicated, this SOFTWARE has been authored by an
10 // employee or employees of the University of California, operator of the
11 // Los Alamos National Laboratory under Contract No.  W-7405-ENG-36 with
12 // the U.S. Department of Energy.  The U.S. Government has rights to use,
13 // reproduce, and distribute this SOFTWARE. The public may copy, distribute,
14 // prepare derivative works and publicly display this SOFTWARE without
15 // charge, provided that this Notice and any statement of authorship are
16 // reproduced on all copies.  Neither the Government nor the University
17 // makes any warranty, express or implied, or assumes any liability or
18 // responsibility for the use of this SOFTWARE.
19 //
20 // If SOFTWARE is modified to produce derivative works, such modified
21 // SOFTWARE should be clearly marked, so as not to confuse it with the
22 // version available from LANL.
23 //
24 // For more information about PETE, send e-mail to pete@acl.lanl.gov,
25 // or visit the PETE web page at http://www.acl.lanl.gov/pete/.
26 // ----------------------------------------------------------------------
27 // ACL:license
28 
29 #ifndef PETE_PETE_FUNCTORS_H
30 #define PETE_PETE_FUNCTORS_H
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 //
34 // WARNING: THIS FILE IS FOR INTERNAL PETE USE. DON'T INCLUDE IT YOURSELF
35 //
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 //-----------------------------------------------------------------------------
39 // Include files.
40 //-----------------------------------------------------------------------------
41 
42 #include <iterator>
43 
44 namespace qmcplusplus
45 {
46 //-----------------------------------------------------------------------------
47 //
48 // CLASS NAME
49 //   LeafFunctor<LeafType, LeafTag>
50 //
51 // DESCRIPTION
52 //   LeafType is the type of something at the leaf of the expression tree.
53 //   LeafTag specifies the operation being applied.
54 //
55 //   LeafFunctors are used by ForEach to apply operations to the leaves of the
56 //   expression tree. Typical functors are evaluators, counters, etc.
57 //   Users define functors for use with ForEach by specializing
58 //   the struct LeafFunctor<LeafType, LeafTag> for the user defined Functor and
59 //   any Leaf types that are necessary.
60 //
61 //   This isn't a functor in the conventional sense since it isn't invoked
62 //   operator() on a LeafFunctor object. Instead, the static apply member
63 //   function is called without an object. In a lot of ways, this is better
64 //   and more flexible than a regular functor.
65 //
66 //   LeafFunctor specializations must define the following:
67 //
68 //      typedef ... Type_t;
69 //         - the return type of the functor.
70 //      static Type_t apply(const LeafType &l, const LeafTag &f) {}
71 //         - evaluates the functor on leaf l.
72 //
73 //-----------------------------------------------------------------------------
74 
75 template<class LeafType, class LeafTag>
76 struct LeafFunctor
77 {};
78 
79 
80 //-----------------------------------------------------------------------------
81 //
82 // CLASS NAMES
83 //   EvalLeaf1-7, LeafFunctor<Scalar<T>, EvalLeaf1-7 >
84 //
85 // DESCRIPTION
86 //   EvalLeaf1 through EvalLeaf7 are used to evaluate leaves using 1 to 7
87 //   integer indices. We supply the tags and scalar versions here. Users must
88 //   supply specializations for their own containers.
89 //
90 //-----------------------------------------------------------------------------
91 
92 // 1D
93 
94 struct EvalLeaf1
95 {
96   int i1_m;
EvalLeaf1EvalLeaf197   inline EvalLeaf1(int i1) : i1_m(i1) {}
val1EvalLeaf198   inline int val1() const { return i1_m; }
99 };
100 
101 template<class T>
102 struct LeafFunctor<Scalar<T>, EvalLeaf1>
103 {
104   typedef T Type_t;
105   inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf1&) { return s.value(); }
106 };
107 
108 // 2D
109 
110 struct EvalLeaf2
111 {
112   int i1_m, i2_m;
113   inline EvalLeaf2(int i1, int i2) : i1_m(i1), i2_m(i2) {}
114   inline int val1() const { return i1_m; }
115   inline int val2() const { return i2_m; }
116 };
117 
118 template<class T>
119 struct LeafFunctor<Scalar<T>, EvalLeaf2>
120 {
121   typedef T Type_t;
122   inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf2&) { return s.value(); }
123 };
124 
125 // 3D
126 
127 struct EvalLeaf3
128 {
129   int i1_m, i2_m, i3_m;
130   inline EvalLeaf3(int i1, int i2, int i3) : i1_m(i1), i2_m(i2), i3_m(i3) {}
131   inline int val1() const { return i1_m; }
132   inline int val2() const { return i2_m; }
133   inline int val3() const { return i3_m; }
134 };
135 
136 template<class T>
137 struct LeafFunctor<Scalar<T>, EvalLeaf3>
138 {
139   typedef T Type_t;
140   inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf3&) { return s.value(); }
141 };
142 
143 // 4D
144 
145 struct EvalLeaf4
146 {
147   int i1_m, i2_m, i3_m, i4_m;
148   inline EvalLeaf4(int i1, int i2, int i3, int i4) : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4) {}
149   inline int val1() const { return i1_m; }
150   inline int val2() const { return i2_m; }
151   inline int val3() const { return i3_m; }
152   inline int val4() const { return i4_m; }
153 };
154 
155 template<class T>
156 struct LeafFunctor<Scalar<T>, EvalLeaf4>
157 {
158   typedef T Type_t;
159   inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf4&) { return s.value(); }
160 };
161 
162 // 5D
163 
164 struct EvalLeaf5
165 {
166   int i1_m, i2_m, i3_m, i4_m, i5_m;
167   inline EvalLeaf5(int i1, int i2, int i3, int i4, int i5) : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5) {}
168   inline int val1() const { return i1_m; }
169   inline int val2() const { return i2_m; }
170   inline int val3() const { return i3_m; }
171   inline int val4() const { return i4_m; }
172   inline int val5() const { return i5_m; }
173 };
174 
175 template<class T>
176 struct LeafFunctor<Scalar<T>, EvalLeaf5>
177 {
178   typedef T Type_t;
179   inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf5&) { return s.value(); }
180 };
181 
182 // 6D
183 
184 struct EvalLeaf6
185 {
186   int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m;
187   inline EvalLeaf6(int i1, int i2, int i3, int i4, int i5, int i6)
188       : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6)
189   {}
190   inline int val1() const { return i1_m; }
191   inline int val2() const { return i2_m; }
192   inline int val3() const { return i3_m; }
193   inline int val4() const { return i4_m; }
194   inline int val5() const { return i5_m; }
195   inline int val6() const { return i6_m; }
196 };
197 
198 template<class T>
199 struct LeafFunctor<Scalar<T>, EvalLeaf6>
200 {
201   typedef T Type_t;
202   inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf6&) { return s.value(); }
203 };
204 
205 // 7D
206 
207 struct EvalLeaf7
208 {
209   int i1_m, i2_m, i3_m, i4_m, i5_m, i6_m, i7_m;
210   inline EvalLeaf7(int i1, int i2, int i3, int i4, int i5, int i6, int i7)
211       : i1_m(i1), i2_m(i2), i3_m(i3), i4_m(i4), i5_m(i5), i6_m(i6), i7_m(i7)
212   {}
213   inline int val1() const { return i1_m; }
214   inline int val2() const { return i2_m; }
215   inline int val3() const { return i3_m; }
216   inline int val4() const { return i4_m; }
217   inline int val5() const { return i5_m; }
218   inline int val6() const { return i6_m; }
219   inline int val7() const { return i7_m; }
220 };
221 
222 template<class T>
223 struct LeafFunctor<Scalar<T>, EvalLeaf7>
224 {
225   typedef T Type_t;
226   inline static const Type_t& apply(const Scalar<T>& s, const EvalLeaf7&) { return s.value(); }
227 };
228 
229 
230 //-----------------------------------------------------------------------------
231 //
232 // CLASS NAME
233 //   IncrementLeaf, LeafFunctor<{T, Scalar<T>}, IncrementLeaf >
234 //
235 // DESCRIPTION
236 //   A leaf-tag and functor used to increment an iterator for scalars and
237 //   leaves made up of STL iterators.
238 //
239 //-----------------------------------------------------------------------------
240 
241 struct IncrementLeaf
242 {};
243 
244 template<class T>
245 struct LeafFunctor<T, IncrementLeaf>
246 {
247   typedef int Type_t;
248   inline static Type_t apply(const T& cl, const IncrementLeaf&)
249   {
250     T& l = const_cast<T&>(cl);
251     ++l;
252     return 0;
253   }
254 };
255 
256 #if defined(__MWERKS__)
257 
258 // Workaround for screwy CWPro 4.1 bug.
259 
260 template<class T>
261 struct LeafFunctor<const T*, IncrementLeaf>
262 {
263   typedef int Type_t;
264   inline static Type_t apply(const T*& const ci, const IncrementLeaf&)
265   {
266     T*& i = const_cast<T*&>(ci);
267     ++i;
268     return 0;
269   }
270 };
271 
272 #endif
273 
274 template<class T>
275 struct LeafFunctor<Scalar<T>, IncrementLeaf>
276 {
277   typedef int Type_t;
278   inline static Type_t apply(const Scalar<T>&, const IncrementLeaf&) { return 0; }
279 };
280 
281 
282 //-----------------------------------------------------------------------------
283 //
284 // CLASS NAME
285 //   DecrementLeaf, LeafFunctor<{T, Scalar<T>}, DecrementLeaf >
286 //
287 // DESCRIPTION
288 //   A leaf-tag and functor used to decrement an iterator for scalars and
289 //   leaves made up of STL iterators.
290 //
291 //-----------------------------------------------------------------------------
292 
293 struct DecrementLeaf
294 {};
295 
296 template<class T>
297 struct LeafFunctor<T, DecrementLeaf>
298 {
299   typedef int Type_t;
300   inline static Type_t apply(const T& cl, const DecrementLeaf&)
301   {
302     T& l = const_cast<T&>(cl);
303     --l;
304     return 0;
305   }
306 };
307 
308 #if defined(__MWERKS__)
309 // Workaround for screwy CWPro 4.1 bug.
310 template<class T>
311 struct LeafFunctor<const T*, DecrementLeaf>
312 {
313   typedef int Type_t;
314   inline static Type_t apply(const T*& const ci, const IncrementLeaf&)
315   {
316     T*& i = const_cast<T*&>(ci);
317     --i;
318     return 0;
319   }
320 };
321 #endif
322 
323 template<class T>
324 struct LeafFunctor<Scalar<T>, DecrementLeaf>
325 {
326   typedef int Type_t;
327   inline static Type_t apply(const Scalar<T>&, const DecrementLeaf&) { return 0; }
328 };
329 
330 //-----------------------------------------------------------------------------
331 //
332 // CLASS NAME
333 //   DereferenceLeaf, LeafFunctor<{T, Scalar<T>}, DereferenceLeaf >
334 //
335 // DESCRIPTION
336 //   A leaf-tag and functor used to dereference an iterator for scalars and
337 //   leaves made up of STL iterators.
338 //
339 //-----------------------------------------------------------------------------
340 
341 struct DereferenceLeaf
342 {};
343 
344 template<class ForwardIterator>
345 struct LeafFunctor<ForwardIterator, DereferenceLeaf>
346 {
347   typedef typename std::iterator_traits<ForwardIterator>::value_type Type_t;
348   inline static Type_t apply(const ForwardIterator& i, const DereferenceLeaf&) { return *i; }
349 };
350 
351 #if defined(__MWERKS__)
352 // Workaround for screwy CWPro 4.1 bug.
353 template<class T>
354 struct LeafFunctor<const T*, DereferenceLeaf>
355 {
356   typedef T Type_t;
357   inline static Type_t apply(const T* i, const DereferenceLeaf&) { return *i; }
358 };
359 #endif
360 
361 template<class T>
362 struct LeafFunctor<Scalar<T>, DereferenceLeaf>
363 {
364   typedef T Type_t;
365   inline static const Type_t& apply(const Scalar<T>& s, const DereferenceLeaf&) { return s.value(); }
366 };
367 
368 } // namespace qmcplusplus
369 
370 #endif // PETE_PETE_FUNCTORS_H
371 
372 // ACL:rcsinfo
373