1 | /*=============================================================================
|
---|
2 | Copyright (c) 1998-2003 Joel de Guzman
|
---|
3 | http://spirit.sourceforge.net/
|
---|
4 |
|
---|
5 | Use, modification and distribution is subject to the Boost Software
|
---|
6 | License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
---|
7 | http://www.boost.org/LICENSE_1_0.txt)
|
---|
8 | =============================================================================*/
|
---|
9 | #if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
|
---|
10 | #define BOOST_SPIRIT_COMPOSITE_HPP
|
---|
11 |
|
---|
12 | ///////////////////////////////////////////////////////////////////////////////
|
---|
13 | #include <boost/compressed_pair.hpp>
|
---|
14 |
|
---|
15 | ///////////////////////////////////////////////////////////////////////////////
|
---|
16 | namespace boost { namespace spirit {
|
---|
17 |
|
---|
18 | ///////////////////////////////////////////////////////////////////////////
|
---|
19 | //
|
---|
20 | // unary class.
|
---|
21 | //
|
---|
22 | // Composite class composed of a single subject. This template class
|
---|
23 | // is parameterized by the subject type S and a base class to
|
---|
24 | // inherit from, BaseT. The unary class is meant to be a base class
|
---|
25 | // to inherit from. The inheritance structure, given the BaseT
|
---|
26 | // template parameter places the unary class in the middle of a
|
---|
27 | // linear, single parent hierarchy. For instance, given a class S
|
---|
28 | // and a base class B, a class D can derive from unary:
|
---|
29 | //
|
---|
30 | // struct D : public unary<S, B> {...};
|
---|
31 | //
|
---|
32 | // The inheritance structure is thus:
|
---|
33 | //
|
---|
34 | // B
|
---|
35 | // |
|
---|
36 | // unary (has S)
|
---|
37 | // |
|
---|
38 | // D
|
---|
39 | //
|
---|
40 | // The subject can be accessed from the derived class D as:
|
---|
41 | // this->subject();
|
---|
42 | //
|
---|
43 | // Typically, the subject S is specified as typename S::embed_t.
|
---|
44 | // embed_t specifies how the subject is embedded in the composite
|
---|
45 | // (See parser.hpp for details).
|
---|
46 | //
|
---|
47 | ///////////////////////////////////////////////////////////////////////////
|
---|
48 | template <typename S, typename BaseT>
|
---|
49 | class unary : public BaseT
|
---|
50 | {
|
---|
51 | public:
|
---|
52 |
|
---|
53 | typedef BaseT base_t;
|
---|
54 | typedef typename boost::call_traits<S>::param_type param_t;
|
---|
55 | typedef typename boost::call_traits<S>::const_reference return_t;
|
---|
56 | typedef S subject_t;
|
---|
57 | typedef typename S::embed_t subject_embed_t;
|
---|
58 |
|
---|
59 | unary(param_t subj_)
|
---|
60 | : base_t(), subj(subj_) {}
|
---|
61 |
|
---|
62 | unary(BaseT const& base, param_t subj_)
|
---|
63 | : base_t(base), subj(subj_) {}
|
---|
64 |
|
---|
65 | return_t
|
---|
66 | subject() const
|
---|
67 | { return subj; }
|
---|
68 |
|
---|
69 | private:
|
---|
70 |
|
---|
71 | subject_embed_t subj;
|
---|
72 | };
|
---|
73 |
|
---|
74 | ///////////////////////////////////////////////////////////////////////////
|
---|
75 | //
|
---|
76 | // binary class.
|
---|
77 | //
|
---|
78 | // Composite class composed of a pair (left and right). This
|
---|
79 | // template class is parameterized by the left and right subject
|
---|
80 | // types A and B and a base class to inherit from, BaseT. The binary
|
---|
81 | // class is meant to be a base class to inherit from. The
|
---|
82 | // inheritance structure, given the BaseT template parameter places
|
---|
83 | // the binary class in the middle of a linear, single parent
|
---|
84 | // hierarchy. For instance, given classes X and Y and a base class
|
---|
85 | // B, a class D can derive from binary:
|
---|
86 | //
|
---|
87 | // struct D : public binary<X, Y, B> {...};
|
---|
88 | //
|
---|
89 | // The inheritance structure is thus:
|
---|
90 | //
|
---|
91 | // B
|
---|
92 | // |
|
---|
93 | // binary (has X and Y)
|
---|
94 | // |
|
---|
95 | // D
|
---|
96 | //
|
---|
97 | // The left and right subjects can be accessed from the derived
|
---|
98 | // class D as: this->left(); and this->right();
|
---|
99 | //
|
---|
100 | // Typically, the pairs X and Y are specified as typename X::embed_t
|
---|
101 | // and typename Y::embed_t. embed_t specifies how the subject is
|
---|
102 | // embedded in the composite (See parser.hpp for details).
|
---|
103 | //
|
---|
104 | ///////////////////////////////////////////////////////////////////////////////
|
---|
105 | template <typename A, typename B, typename BaseT>
|
---|
106 | class binary : public BaseT
|
---|
107 | {
|
---|
108 | public:
|
---|
109 |
|
---|
110 | typedef BaseT base_t;
|
---|
111 | typedef typename boost::call_traits<A>::param_type left_param_t;
|
---|
112 | typedef typename boost::call_traits<A>::const_reference left_return_t;
|
---|
113 | typedef typename boost::call_traits<B>::param_type right_param_t;
|
---|
114 | typedef typename boost::call_traits<B>::const_reference right_return_t;
|
---|
115 | typedef A left_t;
|
---|
116 | typedef typename A::embed_t left_embed_t;
|
---|
117 | typedef B right_t;
|
---|
118 | typedef typename B::embed_t right_embed_t;
|
---|
119 |
|
---|
120 | binary(left_param_t a, right_param_t b)
|
---|
121 | : base_t(), subj(a, b) {}
|
---|
122 |
|
---|
123 | left_return_t
|
---|
124 | left() const
|
---|
125 | { return subj.first(); }
|
---|
126 |
|
---|
127 | right_return_t
|
---|
128 | right() const
|
---|
129 | { return subj.second(); }
|
---|
130 |
|
---|
131 | private:
|
---|
132 |
|
---|
133 | boost::compressed_pair<left_embed_t, right_embed_t> subj;
|
---|
134 | };
|
---|
135 |
|
---|
136 | }} // namespace boost::spirit
|
---|
137 |
|
---|
138 | #endif
|
---|