| /*============================================================================= |
| Copyright (c) 1998-2003 Joel de Guzman |
| http://spirit.sourceforge.net/ |
| |
| Distributed under the Boost Software License, Version 1.0. (See accompanying |
| file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| =============================================================================*/ |
| #if !defined(BOOST_SPIRIT_COMPOSITE_HPP) |
| #define BOOST_SPIRIT_COMPOSITE_HPP |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| #include <boost/compressed_pair.hpp> |
| #include <boost/spirit/home/classic/namespace.hpp> |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| namespace boost { namespace spirit { |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN |
| |
| #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) |
| #pragma warning(push) |
| #pragma warning(disable:4512) //assignment operator could not be generated |
| #endif |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // unary class. |
| // |
| // Composite class composed of a single subject. This template class |
| // is parameterized by the subject type S and a base class to |
| // inherit from, BaseT. The unary class is meant to be a base class |
| // to inherit from. The inheritance structure, given the BaseT |
| // template parameter places the unary class in the middle of a |
| // linear, single parent hierarchy. For instance, given a class S |
| // and a base class B, a class D can derive from unary: |
| // |
| // struct D : public unary<S, B> {...}; |
| // |
| // The inheritance structure is thus: |
| // |
| // B |
| // | |
| // unary (has S) |
| // | |
| // D |
| // |
| // The subject can be accessed from the derived class D as: |
| // this->subject(); |
| // |
| // Typically, the subject S is specified as typename S::embed_t. |
| // embed_t specifies how the subject is embedded in the composite |
| // (See parser.hpp for details). |
| // |
| /////////////////////////////////////////////////////////////////////////// |
| template <typename S, typename BaseT> |
| class unary : public BaseT |
| { |
| public: |
| |
| typedef BaseT base_t; |
| typedef typename boost::call_traits<S>::param_type param_t; |
| typedef typename boost::call_traits<S>::const_reference return_t; |
| typedef S subject_t; |
| typedef typename S::embed_t subject_embed_t; |
| |
| unary(param_t subj_) |
| : base_t(), subj(subj_) {} |
| |
| unary(BaseT const& base, param_t subj_) |
| : base_t(base), subj(subj_) {} |
| |
| return_t |
| subject() const |
| { return subj; } |
| |
| private: |
| |
| subject_embed_t subj; |
| }; |
| |
| /////////////////////////////////////////////////////////////////////////// |
| // |
| // binary class. |
| // |
| // Composite class composed of a pair (left and right). This |
| // template class is parameterized by the left and right subject |
| // types A and B and a base class to inherit from, BaseT. The binary |
| // class is meant to be a base class to inherit from. The |
| // inheritance structure, given the BaseT template parameter places |
| // the binary class in the middle of a linear, single parent |
| // hierarchy. For instance, given classes X and Y and a base class |
| // B, a class D can derive from binary: |
| // |
| // struct D : public binary<X, Y, B> {...}; |
| // |
| // The inheritance structure is thus: |
| // |
| // B |
| // | |
| // binary (has X and Y) |
| // | |
| // D |
| // |
| // The left and right subjects can be accessed from the derived |
| // class D as: this->left(); and this->right(); |
| // |
| // Typically, the pairs X and Y are specified as typename X::embed_t |
| // and typename Y::embed_t. embed_t specifies how the subject is |
| // embedded in the composite (See parser.hpp for details). |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| template <typename A, typename B, typename BaseT> |
| class binary : public BaseT |
| { |
| public: |
| |
| typedef BaseT base_t; |
| typedef typename boost::call_traits<A>::param_type left_param_t; |
| typedef typename boost::call_traits<A>::const_reference left_return_t; |
| typedef typename boost::call_traits<B>::param_type right_param_t; |
| typedef typename boost::call_traits<B>::const_reference right_return_t; |
| typedef A left_t; |
| typedef typename A::embed_t left_embed_t; |
| typedef B right_t; |
| typedef typename B::embed_t right_embed_t; |
| |
| binary(left_param_t a, right_param_t b) |
| : base_t(), subj(a, b) {} |
| |
| left_return_t |
| left() const |
| { return subj.first(); } |
| |
| right_return_t |
| right() const |
| { return subj.second(); } |
| |
| private: |
| |
| boost::compressed_pair<left_embed_t, right_embed_t> subj; |
| }; |
| |
| BOOST_SPIRIT_CLASSIC_NAMESPACE_END |
| |
| }} // namespace BOOST_SPIRIT_CLASSIC_NS |
| |
| #endif |