composite.hpp 5.4 KB

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