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