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_COMBINERS_H
30 #define PETE_PETE_COMBINERS_H
31
32 namespace qmcplusplus
33 {
34 ///////////////////////////////////////////////////////////////////////////////
35 //
36 // WARNING: THIS FILE IS FOR INTERNAL PETE USE. DON'T INCLUDE IT YOURSELF
37 //
38 ///////////////////////////////////////////////////////////////////////////////
39
40 //-----------------------------------------------------------------------------
41 //
42 // CLASS NAMES
43 // Combine1<A,Op,Tag>
44 // Combine2<A,B,Op,Tag>
45 // Combine3<A,B,C,Op,Tag>
46 //
47 // DESCRIPTION
48 // A,B, and C are the types of the combined arguments
49 // Op is the type of the operator from the expression tree
50 // Tag is the tag type which selects the type of combiner operation
51 //
52 // Users create their own combiner operations by specializing these
53 // three structs for a particular user defined tag. A typical example
54 // might be an operation that compares the domains of all the leaves in
55 // an expression.
56 //
57 // Combine1 requires the user to define:
58 // typedef ... Type_t;
59 // - the return type of the combination
60 // static Type_t combine(const A &a, const Op &op, const Tag &t) {}
61 // - a function that combines a
62 //
63 // Combine2 requires the user to define:
64 // typedef ... Type_t;
65 // - the return type of the combination
66 // static Type_t combine(const A &a, const B &b, const Op &op,
67 // const Tag &t) {}
68 // - a function that combines a and b
69 //
70 // Combine3 requires the user to define:
71 // typedef ... Type_t;
72 // - the return type of the combination
73 // static Type_t combine(const A &a, const B &b, const C &c,
74 // const const Op &op, const Tag &t) {}
75 // - a function that combines a and b and c
76 //
77 // The default actions for combiners are:
78 //
79 // Combine1 - returns the arguments
80 // Combine2 - no default action... the user must define this at least
81 // Combine3 - uses Combine2 to combine a and b and combine that with c
82 //
83 //-----------------------------------------------------------------------------
84
85 template<class A, class Op, class Tag>
86 struct Combine1
87 {
88 typedef A Type_t;
combineCombine189 inline static Type_t combine(const A& a, const Op&, const Tag&) { return a; }
90 };
91
92 template<class A, class B, class Op, class Tag>
93 struct Combine2
94 {
95 // no default action. It's an error to not specialize this struct.
96 };
97
98 template<class A, class B, class C, class Op, class Tag>
99 struct Combine3
100 {
101 typedef typename Combine2<A, B, Op, Tag>::Type_t Type1_t;
102 typedef typename Combine2<Type1_t, C, Op, Tag>::Type_t Type_t;
combineCombine3103 inline static Type_t combine(const A& a, const B& b, const C& c, const Op& op, const Tag& t)
104 {
105 return Combine2<Type1_t, C, Op, Tag>::combine(Combine2<A, B, Op, Tag>::combine(a, b, op, t), c, op, t);
106 }
107 };
108
109 //-----------------------------------------------------------------------------
110 //
111 // FUNCTION NAME
112 // peteCombine()
113 //
114 // DESCRIPTION
115 // These functions provide a simple user interface to PETE's CombineN
116 // functors. For example:
117 //
118 // peteCombine(a, b, op, tag);
119 //
120 // is a synonym for:
121 //
122 // Combine2<A, B, Op, Tag>::combine(a, b, op, tag);
123 //
124 //-----------------------------------------------------------------------------
125
126 template<class A, class Op, class Tag>
peteCombine(const A & a,const Op & op,const Tag & t)127 inline typename Combine1<A, Op, Tag>::Type_t peteCombine(const A& a, const Op& op, const Tag& t)
128 {
129 return Combine1<A, Op, Tag>::combine(a, op, t);
130 }
131
132 template<class A, class B, class Op, class Tag>
peteCombine(const A & a,const B & b,const Op & op,const Tag & t)133 inline typename Combine2<A, B, Op, Tag>::Type_t peteCombine(const A& a, const B& b, const Op& op, const Tag& t)
134 {
135 return Combine2<A, B, Op, Tag>::combine(a, b, op, t);
136 }
137
138 template<class A, class B, class C, class Op, class Tag>
peteCombine(const A & a,const B & b,const C & c,const Op & op,const Tag & t)139 inline typename Combine3<A, B, C, Op, Tag>::Type_t peteCombine(const A& a,
140 const B& b,
141 const C& c,
142 const Op& op,
143 const Tag& t)
144 {
145 return Combine3<A, B, C, Op, Tag>::combine(a, b, c, op, t);
146 }
147
148 //-----------------------------------------------------------------------------
149 //
150 // CLASS NAME
151 // TreeCombine
152 //
153 // DESCRIPTION
154 // This combiner is provided so that the user can write a functor
155 // that modifies the leaves of an expression and use
156 // ForEach<Expr,UserFunctor,TreeCombine> to get the entire expression
157 // back with modified leaves.
158 //
159 // This type of operation is useful when expressions are being
160 // passed around. For example, you might subset and expression and pass
161 // that result to another function. The type of expression tree that you
162 // are passing has subsetted nodes, and could be a different type from the
163 // original expression.
164 //
165 //-----------------------------------------------------------------------------
166
167 struct TreeCombine
168 {
169 PETE_EMPTY_CONSTRUCTORS(TreeCombine)
170 };
171
172 template<class A, class Op>
173 struct Combine1<A, Op, TreeCombine>
174 {
175 typedef UnaryNode<Op, A> Type_t;
176 inline static Type_t combine(const A& a, const Op& op, const TreeCombine& t) { return Type_t(op, a); }
177 };
178
179 template<class A, class B, class Op>
180 struct Combine2<A, B, Op, TreeCombine>
181 {
182 typedef BinaryNode<Op, A, B> Type_t;
183 inline static Type_t combine(const A& a, const B& b, const Op& op, const TreeCombine& t) { return Type_t(op, a, b); }
184 };
185
186 template<class A, class B, class C, class Op>
187 struct Combine3<A, B, C, Op, TreeCombine>
188 {
189 typedef TrinaryNode<Op, A, B, C> Type_t;
190 inline static Type_t combine(const A& a, const B& b, const C& c, const Op& op, const TreeCombine& t)
191 {
192 return Type_t(op, a, b, c);
193 }
194 };
195
196
197 //-----------------------------------------------------------------------------
198 //
199 // CLASS NAME
200 // OpCombine
201 //
202 // DESCRIPTION
203 // A combiner that uses the operations in the expression tree.
204 //
205 //-----------------------------------------------------------------------------
206
207 struct OpCombine
208 {
209 PETE_EMPTY_CONSTRUCTORS(OpCombine)
210 };
211
212 template<class A, class Op>
213 struct Combine1<A, Op, OpCombine>
214 {
215 typedef typename UnaryReturn<A, Op>::Type_t Type_t;
216 inline static Type_t combine(A a, Op op, OpCombine) { return op(a); }
217 };
218
219 template<class A, class B, class Op>
220 struct Combine2<A, B, Op, OpCombine>
221 {
222 typedef typename BinaryReturn<A, B, Op>::Type_t Type_t;
223 inline static Type_t combine(A a, B b, Op op, OpCombine) { return op(a, b); }
224 };
225
226 template<class A, class B, class C, class Op>
227 struct Combine3<A, B, C, Op, OpCombine>
228 {
229 typedef typename TrinaryReturn<A, B, C, Op>::Type_t Type_t;
230 inline static Type_t combine(A a, B b, C c, Op op, OpCombine) { return op(a, b, c); }
231 };
232
233
234 //-----------------------------------------------------------------------------
235 //
236 // CLASS NAME
237 // AndCombine
238 //
239 // DESCRIPTION
240 // A handy combiner for extracting bool queries from expressions.
241 //
242 //-----------------------------------------------------------------------------
243
244 struct AndCombine
245 {
246 PETE_EMPTY_CONSTRUCTORS(AndCombine)
247 };
248
249 template<class Op>
250 struct Combine2<bool, bool, Op, AndCombine>
251 {
252 typedef bool Type_t;
253 inline static Type_t combine(bool a, bool b, Op, AndCombine) { return (a && b); }
254 };
255
256
257 //-----------------------------------------------------------------------------
258 //
259 // CLASS NAME
260 // OrCombine
261 //
262 // DESCRIPTION
263 // A handy combiner for extracting bool queries from expressions.
264 //
265 //-----------------------------------------------------------------------------
266
267 struct OrCombine
268 {
269 PETE_EMPTY_CONSTRUCTORS(OrCombine)
270 };
271
272 template<class Op>
273 struct Combine2<bool, bool, Op, OrCombine>
274 {
275 typedef bool Type_t;
276 inline static Type_t combine(bool a, bool b, Op, OrCombine) { return (a || b); }
277 };
278
279
280 //-----------------------------------------------------------------------------
281 //
282 // CLASS NAME
283 // NullCombine
284 //
285 // DESCRIPTION
286 // This combiner doesn't do anything. Used when the combination isn't meant
287 // return anything since combiners cannot return void.
288 //
289 //-----------------------------------------------------------------------------
290
291 struct NullCombine
292 {
293 PETE_EMPTY_CONSTRUCTORS(NullCombine)
294 };
295
296 template<class Op>
297 struct Combine2<int, int, Op, NullCombine>
298 {
299 typedef int Type_t;
300 inline static Type_t combine(int, int, Op, NullCombine) { return 0; }
301 };
302
303
304 //-----------------------------------------------------------------------------
305 //
306 // CLASS NAME
307 // SumCombine
308 //
309 // DESCRIPTION
310 // This combiner can be used to count things in expressions.
311 //
312 //-----------------------------------------------------------------------------
313
314 struct SumCombine
315 {
316 PETE_EMPTY_CONSTRUCTORS(SumCombine)
317 };
318
319 template<class Op>
320 struct Combine2<int, int, Op, SumCombine>
321 {
322 typedef int Type_t;
323 inline static Type_t combine(int a, int b, Op, SumCombine) { return a + b; }
324 };
325
326
327 } // namespace qmcplusplus
328 #endif // PETE_PETE_COMBINERS_H
329
330 // ACL:rcsinfo
331