QMCPACK
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 
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 NAME
43 // Reference<T>
44 //
45 // DESCRIPTION
46 // Reference is a special kind of node that contains a reference to an object
47 // of type T. It can be converted to a (const T &), and other tree objects
48 // will perform this conversion before returning their elements.
49 //
50 //-----------------------------------------------------------------------------
51 
52 template<class T>
53 struct Reference
54 {
55  //---------------------------------------------------------------------------
56  // Export the type of thing we're referencing.
57 
58  using Type_t = T;
59 
60  //---------------------------------------------------------------------------
61  // Reference can be created from a const ref.
62 
63  inline Reference(const T& reference) : reference_m(reference) {}
64 
65  //---------------------------------------------------------------------------
66  // Copy constructor
67 
68  inline Reference(const Reference<T>& model) : reference_m(model.reference()) {}
69 
70  //---------------------------------------------------------------------------
71  // Reference can be converted to a const ref
72 
73  inline const T& reference() const { return reference_m; }
74 
75  //---------------------------------------------------------------------------
76  // Conversion operators.
77 
78  operator const T&() const { return reference_m; }
79  operator T&() const { return const_cast<T&>(reference_m); }
80 
81  const T& reference_m;
82 };
83 
84 //-----------------------------------------------------------------------------
85 //
86 // CLASS NAME
87 // DeReference<T>
88 //
89 // DESCRIPTION
90 // DeReference is a simple traits class that unwraps the Reference struct.
91 // If T is not a reference object then DeReference gives (const T &).
92 // If T is a Reference object, then DeReference gives a const ref to the
93 // wrapped object.
94 //
95 //-----------------------------------------------------------------------------
96 
97 template<class T>
99 {
100  using Return_t = const T&;
101  using Type_t = T;
102  static inline Return_t apply(const T& a) { return a; }
103 };
104 
105 template<class T>
107 {
108  using Return_t = const T&;
109  using Type_t = T;
110  static inline Return_t apply(const Reference<T>& a) { return a.reference(); }
111 };
112 
113 //-----------------------------------------------------------------------------
114 //
115 // CLASS NAME
116 // UnaryNode<Op, Child>
117 //
118 // DESCRIPTION
119 // A tree node for representing unary expressions. The node holds a
120 // child (of type Child), which is the type of the expression sub tree and a
121 // an operation (of type Op), which is typically the operation applied to
122 // the sub tree.
123 //
124 //-----------------------------------------------------------------------------
125 
126 template<class Op, class Child>
128 {
129 public:
130  //---------------------------------------------------------------------------
131  // Accessors making the operation and child available to the outside.
132 
133  inline const Op& operation() const { return op_m; }
134 
136 
137  //---------------------------------------------------------------------------
138  // Constructor using both a operation and the child.
139 
140  inline UnaryNode(const Op& o, const Child& c) : op_m(o), child_m(c) {}
141 
142  //---------------------------------------------------------------------------
143  // Constructor using just the child.
144 
145  inline UnaryNode(const Child& c) : child_m(c) {}
146 
147  //---------------------------------------------------------------------------
148  // Copy constructor.
149 
150  inline UnaryNode(const UnaryNode<Op, Child>& t) : op_m(t.operation()), child_m(t.child()) {}
151 
152  //---------------------------------------------------------------------------
153  // Constructor using a UnaryNode with a different child and/or a different
154  // storage tag. Note: for this to work, a Child must be constructable
155  // from an OtherChild.
156 
157  template<class OtherChild>
159  {}
160 
161  //---------------------------------------------------------------------------
162  // Constructor using a UnaryNode with a different child,
163  // some arbitrary argument, and a different storage tag.
164  // Note: for this to work, a Child must be constructable
165  // from an OtherChild and an Arg.
166 
167  template<class OtherChild, class Arg>
168  inline UnaryNode(const UnaryNode<Op, OtherChild>& t, const Arg& a) : op_m(t.operation()), child_m(t.child(), a)
169  {}
170 
171  //---------------------------------------------------------------------------
172  // Constructor using a BinaryNode with a different Child and
173  // two arbitrary arguments.
174  // Note: for this to work, a Child must be constructable
175  // from an OtherChild and an Arg1 & Arg2.
176 
177  template<class OtherChild, class Arg1, class Arg2>
178  inline UnaryNode(const UnaryNode<Op, OtherChild>& t, const Arg1& a1, const Arg2& a2)
179  : op_m(t.operation()), child_m(t.child(), a1, a2)
180  {}
181 
182 private:
183  Op op_m;
184  Child child_m;
185 };
186 
187 
188 //-----------------------------------------------------------------------------
189 //
190 // CLASS NAME
191 // BinaryNode<Op, Left, Right>
192 //
193 // DESCRIPTION
194 // A tree node for representing binary expressions. The node holds a
195 // left child (of type Left), which is the type of the LHS expression
196 // sub tree, a right child (of type Right), which is the type of the RHS
197 // expression sub tree, and an operation (of type OP), which is applied
198 // to the two sub trees.
199 //
200 //-----------------------------------------------------------------------------
201 
202 template<class Op, class Left, class Right>
204 {
205 public:
206  //---------------------------------------------------------------------------
207  // Accessors making the operation and children available to the outside.
208 
209  inline const Op& operation() const { return op_m; }
210 
212 
214 
215  //---------------------------------------------------------------------------
216  // Constructor using both the operation and the two children.
217 
218  inline BinaryNode(const Op& o, const Left& l, const Right& r) : op_m(o), left_m(l), right_m(r) {}
219 
220  //---------------------------------------------------------------------------
221  // Constructor using just the two children.
222 
223  inline BinaryNode(const Left& l, const Right& r) : left_m(l), right_m(r) {}
224 
225  //---------------------------------------------------------------------------
226  // Copy constructor.
227 
229 
230  //---------------------------------------------------------------------------
231  // Constructor using a BinaryNode with a different Left/Right.
232  // Note: for this to work, the Left/Right must be constructable
233  // from an OtherLeft/OtherRight.
234 
235  template<class OtherLeft, class OtherRight>
237  : op_m(t.operation()), left_m(t.left()), right_m(t.right())
238  {}
239 
240  //---------------------------------------------------------------------------
241  // Constructor using a BinaryNode with a different Left/Right and
242  // some arbitrary argument.
243  // Note: for this to work, a Left/Right must be constructable
244  // from an OtherLeft/OtherRight and an Arg.
245 
246  template<class OtherLeft, class OtherRight, class Arg>
247  inline BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight>& t, const Arg& a)
248  : op_m(t.operation()), left_m(t.left(), a), right_m(t.right(), a)
249  {}
250 
251  //---------------------------------------------------------------------------
252  // Constructor using a BinaryNode with a different Left/Right and
253  // two arbitrary arguments.
254  // Note: for this to work, a Left/Right must be constructable
255  // from an OtherLeft/OtherRight and an Arg1 & Arg2.
256 
257  template<class OtherLeft, class OtherRight, class Arg1, class Arg2>
258  inline BinaryNode(const BinaryNode<Op, OtherLeft, OtherRight>& t, const Arg1& a1, const Arg2& a2)
259  : op_m(t.operation()), left_m(t.left(), a1, a2), right_m(t.right(), a1, a2)
260  {}
261 
262 private:
263  //---------------------------------------------------------------------------
264  // The operation and left/right sub expressions stored in this node of the
265  // tree.
266 
267  Op op_m;
268  Left left_m;
269  Right right_m;
270 };
271 
272 
273 //-----------------------------------------------------------------------------
274 //
275 // CLASS NAME
276 // TrinaryNode<Op, Left, Middle, Right>
277 //
278 // DESCRIPTION
279 // A tree node for representing trinary expressions. The node holds a
280 // Left child (of type Left), which is the type of the LHS expression
281 // sub tree (typically a comparison operation); a Middle child (of type
282 // Middle), which is the type of the middle (true branch) expression
283 // sub tree; a Right child (of type Right), which is the type of
284 // the expression (false branch) sub tree; and an operation (of type Op),
285 // which is applied to the three sub trees.
286 //
287 //-----------------------------------------------------------------------------
288 
289 template<class Op, class Left, class Middle, class Right>
291 {
292 public:
293  //---------------------------------------------------------------------------
294  // Accessors making the operation and children available to the outside.
295 
296  inline const Op& operation() const { return op_m; }
297 
299 
301 
303 
304  //---------------------------------------------------------------------------
305  // Constructor using the operation and three children.
306 
307  inline TrinaryNode(const Op& o, const Left& l, const Middle& m, const Right& r)
308  : op_m(o), left_m(l), middle_m(m), right_m(r)
309  {}
310 
311  //---------------------------------------------------------------------------
312  // Constructor with just the three children.
313 
314  inline TrinaryNode(const Left& l, const Middle& m, const Right& r) : left_m(l), middle_m(m), right_m(r) {}
315 
316  //---------------------------------------------------------------------------
317  // Copy constructor.
318 
320  : op_m(t.operation()), left_m(t.left()), middle_m(t.middle()), right_m(t.right())
321  {}
322 
323  //---------------------------------------------------------------------------
324  // Constructor using a TrinaryNode with a different Left/Middle/Right.
325  // Note: for this to work, the Left/Middle/Right must be constructable
326  // from an OtherLeft/OtherMiddle/OtherRight.
327 
328  template<class OtherLeft, class OtherMiddle, class OtherRight>
330  : op_m(t.operation()), left_m(t.left()), middle_m(t.middle()), right_m(t.right())
331  {}
332 
333  //---------------------------------------------------------------------------
334  // Constructor using a TrinaryNode with a different Left/Middle/Right and
335  // some arbitrary argument.
336  // Note: for this to work, a Left/Middle/Right must be constructable
337  // from an OtherLeft/OtherMiddle/OtherRight and an Arg.
338 
339  template<class OtherLeft, class OtherMiddle, class OtherRight, class Arg>
341  : op_m(t.operation()), left_m(t.left(), a), middle_m(t.middle(), a), right_m(t.right(), a)
342  {}
343 
344  //---------------------------------------------------------------------------
345  // Constructor using a TrinaryNode with a different Left/Middle/Right and
346  // two arbitrary arguments.
347  // Note: for this to work, a Left/Middle/Right must be constructable
348  // from an OtherLeft/OtherMiddle/OtherRight and an Arg1 & Arg2.
349 
350  template<class OtherLeft, class OtherMiddle, class OtherRight, class Arg1, class Arg2>
351  inline TrinaryNode(const TrinaryNode<Op, OtherLeft, OtherMiddle, OtherRight>& t, const Arg1& a1, const Arg2& a2)
352  : op_m(t.operation()), left_m(t.left(), a1, a2), middle_m(t.middle(), a1, a2), right_m(t.right(), a1, a2)
353  {}
354 
355 private:
356  //---------------------------------------------------------------------------
357  // The operation and left, right, and middle sub trees stored at this node.
358 
359  Op op_m;
360  Left left_m;
361  Middle middle_m;
362  Right right_m;
363 };
364 
365 } // namespace qmcplusplus
366 #endif // PETE_PETE_TREENODES_H
367 
368 // ACL:rcsinfo
DeReference< Right >::Return_t right() const
Definition: TreeNodes.h:213
TrinaryNode(const Op &o, const Left &l, const Middle &m, const Right &r)
Definition: TreeNodes.h:307
BinaryNode(const Left &l, const Right &r)
Definition: TreeNodes.h:223
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
BinaryNode(const Op &o, const Left &l, const Right &r)
Definition: TreeNodes.h:218
TrinaryNode(const TrinaryNode< Op, OtherLeft, OtherMiddle, OtherRight > &t, const Arg1 &a1, const Arg2 &a2)
Definition: TreeNodes.h:351
Reference(const T &reference)
Definition: TreeNodes.h:63
const Op & operation() const
Definition: TreeNodes.h:296
const Op & operation() const
Definition: TreeNodes.h:133
BinaryNode(const BinaryNode< Op, OtherLeft, OtherRight > &t, const Arg &a)
Definition: TreeNodes.h:247
DeReference< Left >::Return_t left() const
Definition: TreeNodes.h:298
TrinaryNode(const Left &l, const Middle &m, const Right &r)
Definition: TreeNodes.h:314
UnaryNode(const UnaryNode< Op, OtherChild > &t)
Definition: TreeNodes.h:158
static Return_t apply(const Reference< T > &a)
Definition: TreeNodes.h:110
TrinaryNode(const TrinaryNode< Op, OtherLeft, OtherMiddle, OtherRight > &t, const Arg &a)
Definition: TreeNodes.h:340
const T & reference_m
Definition: TreeNodes.h:81
DeReference< Left >::Return_t left() const
Definition: TreeNodes.h:211
UnaryNode(const UnaryNode< Op, Child > &t)
Definition: TreeNodes.h:150
const T & reference() const
Definition: TreeNodes.h:73
UnaryNode(const UnaryNode< Op, OtherChild > &t, const Arg &a)
Definition: TreeNodes.h:168
const Op & operation() const
Definition: TreeNodes.h:209
UnaryNode(const Op &o, const Child &c)
Definition: TreeNodes.h:140
TrinaryNode(const TrinaryNode< Op, Left, Middle, Right > &t)
Definition: TreeNodes.h:319
UnaryNode(const UnaryNode< Op, OtherChild > &t, const Arg1 &a1, const Arg2 &a2)
Definition: TreeNodes.h:178
DeReference< Child >::Return_t child() const
Definition: TreeNodes.h:135
TrinaryNode(const TrinaryNode< Op, OtherLeft, OtherMiddle, OtherRight > &t)
Definition: TreeNodes.h:329
BinaryNode(const BinaryNode< Op, Left, Right > &t)
Definition: TreeNodes.h:228
DeReference< Middle >::Return_t middle() const
Definition: TreeNodes.h:302
Reference(const Reference< T > &model)
Definition: TreeNodes.h:68
static Return_t apply(const T &a)
Definition: TreeNodes.h:102
BinaryNode(const BinaryNode< Op, OtherLeft, OtherRight > &t, const Arg1 &a1, const Arg2 &a2)
Definition: TreeNodes.h:258
UnaryNode(const Child &c)
Definition: TreeNodes.h:145
DeReference< Right >::Return_t right() const
Definition: TreeNodes.h:300
BinaryNode(const BinaryNode< Op, OtherLeft, OtherRight > &t)
Definition: TreeNodes.h:236