QDP++
TreeNodes.h
Go to the documentation of this file.
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_TREENODES_H
30#define PETE_PETE_TREENODES_H
31
33//
34// WARNING: THIS FILE IS FOR INTERNAL PETE USE. DON'T INCLUDE IT YOURSELF
35//
37
38// For some reason, IBM xlC barfs on these usages. Turn them off.
39#define MAKES_XLC_BARF
40
41//-----------------------------------------------------------------------------
42//
43// CLASS NAME
44// Reference<T>
45//
46// DESCRIPTION
47// Reference is a special kind of node that contains a reference to an object
48// of type T. It can be converted to a (const T &), and other tree objects
49// will perform this conversion before returning their elements.
50//
51//-----------------------------------------------------------------------------
52
53template<class T>
55{
56 //---------------------------------------------------------------------------
57 // Export the type of thing we're referencing.
58
59 typedef T Type_t;
60
61 //---------------------------------------------------------------------------
62 // Reference can be created from a const ref.
63
64 inline
67 { }
68
69 //---------------------------------------------------------------------------
70 // Copy constructor
71
72 inline
73 Reference(const Reference<T> &model)
74 : reference_m(model.reference())
75 { }
76
77 //---------------------------------------------------------------------------
78 // Reference can be converted to a const ref
79
80 inline
81 const T &reference() const
82 {
83 return reference_m;
84 }
85
86 //---------------------------------------------------------------------------
87 // Conversion operators.
88
89 operator const T& () const { return reference_m; }
90 operator T& () const { return const_cast<T&>(reference_m); }
91// operator T& () { return const_cast<T&>(reference_m); }
92
93 const T &reference_m;
94};
95
96//-----------------------------------------------------------------------------
97//
98// CLASS NAME
99// DeReference<T>
100//
101// DESCRIPTION
102// DeReference is a simple traits class that unwraps the Reference struct.
103// If T is not a reference object then DeReference gives (const T &).
104// If T is a Reference object, then DeReference gives a const ref to the
105// wrapped object.
106//
107//-----------------------------------------------------------------------------
108
109template<class T>
111{
112 typedef const T &Return_t;
113 typedef T Type_t;
114 static inline Return_t apply(const T &a) { return a; }
115};
116
117template<class T>
119{
120 typedef const T &Return_t;
121 typedef T Type_t;
122 static inline Return_t apply(const Reference<T> &a) { return a.reference(); }
123};
124
125//-----------------------------------------------------------------------------
126//
127// CLASS NAME
128// UnaryNode<Op, Child>
129//
130// DESCRIPTION
131// A tree node for representing unary expressions. The node holds a
132// child (of type Child), which is the type of the expression sub tree and a
133// an operation (of type Op), which is typically the operation applied to
134// the sub tree.
135//
136//-----------------------------------------------------------------------------
137
138template<class Op, class Child>
140{
141public:
142
143 //---------------------------------------------------------------------------
144 // Accessors making the operation and child available to the outside.
145
146 inline
147 const Op &operation() const { return op_m; }
148
149 inline
151 child() const { return DeReference<Child>::apply(child_m); }
152
153 //---------------------------------------------------------------------------
154 // Constructor using both a operation and the child.
155
156 inline
157 UnaryNode(const Op &o, const Child &c)
158 : op_m(o), child_m(c) { }
159
160 //---------------------------------------------------------------------------
161 // Constructor using just the child.
162
163 inline
164 UnaryNode(const Child &c)
165 : child_m(c) { }
166
167 //---------------------------------------------------------------------------
168 // Copy constructor.
169
170 inline
172 : op_m(t.operation()), child_m(t.child()) { }
173
174 //---------------------------------------------------------------------------
175 // Constructor using a UnaryNode with a different child and/or a different
176 // storage tag. Note: for this to work, a Child must be constructable
177 // from an OtherChild.
178
179 template<class OtherChild>
180 inline
182 : op_m(t.operation()), child_m(t.child()) { }
183
184#if ! defined(MAKES_XLC_BARF)
185 //---------------------------------------------------------------------------
186 // Constructor using a UnaryNode with a different child,
187 // some arbitrary argument, and a different storage tag.
188 // Note: for this to work, a Child must be constructable
189 // from an OtherChild and an Arg.
190
191 template<class OtherChild, class Arg>
192 inline
193 UnaryNode(const UnaryNode<Op, OtherChild> &t, const Arg &a)
194 : op_m(t.operation()), child_m(t.child(), a) { }
195#endif
196
197#if ! defined(MAKES_XLC_BARF)
198 //---------------------------------------------------------------------------
199 // Constructor using a BinaryNode with a different Child and
200 // two arbitrary arguments.
201 // Note: for this to work, a Child must be constructable
202 // from an OtherChild and an Arg1 & Arg2.
203
204 template<class OtherChild, class Arg1, class Arg2>
205 inline
207 const Arg1 &a1, const Arg2 &a2)
208 : op_m(t.operation()), child_m(t.child(), a1, a2)
209 { }
210#endif
211
212private:
213
214 Op op_m;
215 Child child_m;
216
217};
218
219
220//-----------------------------------------------------------------------------
221//
222// CLASS NAME
223// BinaryNode<Op, Left, Right>
224//
225// DESCRIPTION
226// A tree node for representing binary expressions. The node holds a
227// left child (of type Left), which is the type of the LHS expression
228// sub tree, a right child (of type Right), which is the type of the RHS
229// expression sub tree, and an operation (of type OP), which is applied
230// to the two sub trees.
231//
232//-----------------------------------------------------------------------------
233
234template<class Op, class Left, class Right>
236{
237public:
238
239 //---------------------------------------------------------------------------
240 // Accessors making the operation and children available to the outside.
241
242 inline
243 const Op &operation() const { return op_m; }
244
245 inline
247 left() const { return DeReference<Left>::apply(left_m); }
248
249 inline
251 right() const { return DeReference<Right>::apply(right_m); }
252
253 //---------------------------------------------------------------------------
254 // Constructor using both the operation and the two children.
255
256 inline
257 BinaryNode(const Op &o, const Left &l, const Right &r)
258 : op_m(o), left_m(l), right_m(r)
259 { }
260
261 //---------------------------------------------------------------------------
262 // Constructor using just the two children.
263
264 inline
265 BinaryNode(const Left &l, const Right &r)
266 : left_m(l), right_m(r)
267 { }
268
269 //---------------------------------------------------------------------------
270 // Copy constructor.
271
272 inline
274 : op_m(t.operation()), left_m(t.left()), right_m(t.right())
275 { }
276
277 //---------------------------------------------------------------------------
278 // Constructor using a BinaryNode with a different Left/Right.
279 // Note: for this to work, the Left/Right must be constructable
280 // from an OtherLeft/OtherRight.
281
282 template<class OtherLeft, class OtherRight>
283 inline
285 : op_m(t.operation()), left_m(t.left()), right_m(t.right())
286 { }
287
288#if ! defined(MAKES_XLC_BARF)
289 //---------------------------------------------------------------------------
290 // Constructor using a BinaryNode with a different Left/Right and
291 // some arbitrary argument.
292 // Note: for this to work, a Left/Right must be constructable
293 // from an OtherLeft/OtherRight and an Arg.
294
295 template<class OtherLeft, class OtherRight, class Arg>
296 inline
298 const Arg &a)
299 : op_m(t.operation()), left_m(t.left(), a), right_m(t.right(), a)
300 { }
301#endif
302
303#if ! defined(MAKES_XLC_BARF)
304 //---------------------------------------------------------------------------
305 // Constructor using a BinaryNode with a different Left/Right and
306 // two arbitrary arguments.
307 // Note: for this to work, a Left/Right must be constructable
308 // from an OtherLeft/OtherRight and an Arg1 & Arg2.
309
310 template<class OtherLeft, class OtherRight, class Arg1, class Arg2>
311 inline
313 const Arg1 &a1, const Arg2 &a2)
314 : op_m(t.operation()),
315 left_m(t.left(), a1, a2), right_m(t.right(), a1, a2)
316 { }
317#endif
318
319private:
320
321 //---------------------------------------------------------------------------
322 // The operation and left/right sub expressions stored in this node of the
323 // tree.
324
325 Op op_m;
326 Left left_m;
327 Right right_m;
328
329};
330
331
332//-----------------------------------------------------------------------------
333//
334// CLASS NAME
335// TrinaryNode<Op, Left, Middle, Right>
336//
337// DESCRIPTION
338// A tree node for representing trinary expressions. The node holds a
339// Left child (of type Left), which is the type of the LHS expression
340// sub tree (typically a comparison operation); a Middle child (of type
341// Middle), which is the type of the middle (true branch) expression
342// sub tree; a Right child (of type Right), which is the type of
343// the expression (false branch) sub tree; and an operation (of type Op),
344// which is applied to the three sub trees.
345//
346//-----------------------------------------------------------------------------
347
348template< class Op, class Left, class Middle, class Right>
350{
351public:
352
353 //---------------------------------------------------------------------------
354 // Accessors making the operation and children available to the outside.
355
356 inline
357 const Op &operation() const { return op_m; }
358
359 inline
361 left() const { return DeReference<Left>::apply(left_m); }
362
363 inline
365 right() const { return DeReference<Right>::apply(right_m); }
366
367 inline
369 middle() const { return DeReference<Middle>::apply(middle_m); }
370
371 //---------------------------------------------------------------------------
372 // Constructor using the operation and three children.
373
374 inline
375 TrinaryNode(const Op &o, const Left &l, const Middle &m, const Right &r)
376 : op_m(o), left_m(l), middle_m(m), right_m(r)
377 { }
378
379 //---------------------------------------------------------------------------
380 // Constructor with just the three children.
381
382 inline
383 TrinaryNode(const Left &l, const Middle &m, const Right &r)
384 : left_m(l), middle_m(m), right_m(r)
385 { }
386
387 //---------------------------------------------------------------------------
388 // Copy constructor.
389
390 inline
392 : op_m(t.operation()), left_m(t.left()), middle_m(t.middle()),
393 right_m(t.right())
394 { }
395
396 //---------------------------------------------------------------------------
397 // Constructor using a TrinaryNode with a different Left/Middle/Right.
398 // Note: for this to work, the Left/Middle/Right must be constructable
399 // from an OtherLeft/OtherMiddle/OtherRight.
400
401 template<class OtherLeft, class OtherMiddle, class OtherRight>
402 inline
404 : op_m(t.operation()), left_m(t.left()), middle_m(t.middle()),
405 right_m(t.right())
406 { }
407
408#if ! defined(MAKES_XLC_BARF)
409 //---------------------------------------------------------------------------
410 // Constructor using a TrinaryNode with a different Left/Middle/Right and
411 // some arbitrary argument.
412 // Note: for this to work, a Left/Middle/Right must be constructable
413 // from an OtherLeft/OtherMiddle/OtherRight and an Arg.
414
415 template<class OtherLeft, class OtherMiddle, class OtherRight, class Arg>
416 inline
418 const Arg &a)
419 : op_m(t.operation()), left_m(t.left(), a), middle_m(t.middle(), a),
420 right_m(t.right(), a)
421 { }
422#endif
423
424#if ! defined(MAKES_XLC_BARF)
425 //---------------------------------------------------------------------------
426 // Constructor using a TrinaryNode with a different Left/Middle/Right and
427 // two arbitrary arguments.
428 // Note: for this to work, a Left/Middle/Right must be constructable
429 // from an OtherLeft/OtherMiddle/OtherRight and an Arg1 & Arg2.
430
431 template<class OtherLeft, class OtherMiddle, class OtherRight,
432 class Arg1, class Arg2>
433 inline
435 const Arg1 &a1, const Arg2 &a2)
436 : op_m(t.operation()), left_m(t.left(), a1, a2),
437 middle_m(t.middle(), a1, a2) , right_m(t.right(), a1, a2)
438 { }
439#endif
440
441private:
442
443 //---------------------------------------------------------------------------
444 // The operation and left, right, and middle sub trees stored at this node.
445
446 Op op_m;
447 Left left_m;
448 Middle middle_m;
449 Right right_m;
450
451};
452
453#endif // PETE_PETE_TREENODES_H
454
455// ACL:rcsinfo
456// ----------------------------------------------------------------------
457// $RCSfile: TreeNodes.h,v $ $Author: edwards $
458// $Revision: 1.2 $ $Date: 2002-12-05 19:11:30 $
459// ----------------------------------------------------------------------
460// ACL:rcsinfo
DeReference< Left >::Return_t left() const
Definition TreeNodes.h:247
BinaryNode(const Op &o, const Left &l, const Right &r)
Definition TreeNodes.h:257
DeReference< Right >::Return_t right() const
Definition TreeNodes.h:251
BinaryNode(const Left &l, const Right &r)
Definition TreeNodes.h:265
const Op & operation() const
Definition TreeNodes.h:243
BinaryNode(const BinaryNode< Op, Left, Right > &t)
Definition TreeNodes.h:273
BinaryNode(const BinaryNode< Op, OtherLeft, OtherRight > &t)
Definition TreeNodes.h:284
DeReference< Left >::Return_t left() const
Definition TreeNodes.h:361
DeReference< Right >::Return_t right() const
Definition TreeNodes.h:365
TrinaryNode(const TrinaryNode< Op, OtherLeft, OtherMiddle, OtherRight > &t)
Definition TreeNodes.h:403
DeReference< Middle >::Return_t middle() const
Definition TreeNodes.h:369
TrinaryNode(const Left &l, const Middle &m, const Right &r)
Definition TreeNodes.h:383
const Op & operation() const
Definition TreeNodes.h:357
TrinaryNode(const TrinaryNode< Op, Left, Middle, Right > &t)
Definition TreeNodes.h:391
TrinaryNode(const Op &o, const Left &l, const Middle &m, const Right &r)
Definition TreeNodes.h:375
UnaryNode(const Op &o, const Child &c)
Definition TreeNodes.h:157
DeReference< Child >::Return_t child() const
Definition TreeNodes.h:151
UnaryNode(const UnaryNode< Op, Child > &t)
Definition TreeNodes.h:171
UnaryNode(const Child &c)
Definition TreeNodes.h:164
UnaryNode(const UnaryNode< Op, OtherChild > &t)
Definition TreeNodes.h:181
const Op & operation() const
Definition TreeNodes.h:147
static Return_t apply(const Reference< T > &a)
Definition TreeNodes.h:122
static Return_t apply(const T &a)
Definition TreeNodes.h:114
const T & Return_t
Definition TreeNodes.h:112
Reference(const T &reference)
Definition TreeNodes.h:65
const T & reference_m
Definition TreeNodes.h:93
const T & reference() const
Definition TreeNodes.h:81
Reference(const Reference< T > &model)
Definition TreeNodes.h:73