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