Line data Source code
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 : 66 0 : unary(param_t subj_) 67 0 : : base_t(), subj(subj_) {} 68 : 69 : unary(BaseT const& base, param_t subj_) 70 : : base_t(base), subj(subj_) {} 71 : 72 : return_t 73 0 : subject() const 74 0 : { 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 : 127 0 : binary(left_param_t a, right_param_t b) 128 0 : : base_t(), subj(a, b) {} 129 : 130 : left_return_t 131 0 : left() const 132 0 : { return subj.first(); } 133 : 134 : right_return_t 135 0 : right() const 136 0 : { 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