$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66465 - branches/release/boost/spirit/home/classic/dynamic/impl
From: hartmut.kaiser_at_[hidden]
Date: 2010-11-08 17:41:30
Author: hkaiser
Date: 2010-11-08 17:41:27 EST (Mon, 08 Nov 2010)
New Revision: 66465
URL: http://svn.boost.org/trac/boost/changeset/66465
Log:
Spirit: fixed #4825: boost/spirit/home/classic/dynamic/impl/switch.ipp missing a chunk in release branch
Text files modified: 
   branches/release/boost/spirit/home/classic/dynamic/impl/switch.ipp |   307 ++++++++++++++++++++++++++++++++++++++++
   1 files changed, 307 insertions(+), 0 deletions(-)
Modified: branches/release/boost/spirit/home/classic/dynamic/impl/switch.ipp
==============================================================================
--- branches/release/boost/spirit/home/classic/dynamic/impl/switch.ipp	(original)
+++ branches/release/boost/spirit/home/classic/dynamic/impl/switch.ipp	2010-11-08 17:41:27 EST (Mon, 08 Nov 2010)
@@ -103,6 +103,313 @@
     template <
         typename ParserT, typename DefaultT,
         typename ValueT, typename ScannerT
+    >
+    static typename parser_result<ParserT, ScannerT>::type
+    parse (ValueT const &value, ParserT const &p, DefaultT const &d,
+        ScannerT const &scan, typename ScannerT::iterator_t const save)
+    {
+        //  Since there is a default_p case branch defined, the corresponding
+        //  parser shouldn't be the nothing_parser
+        BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
+        if (value == N)
+            return delegate_parse(p, scan, save);
+
+        return delegate_parse(d, scan, save);
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  Look through the case parser chain to test, if there is a default case
+//  branch defined (returned by 'value').
+template <typename CaseT, bool IsSimple = CaseT::is_simple>
+struct default_case;
+
+////////////////////////////////////////
+template <typename ResultT, bool IsDefault>
+struct get_default_parser {
+
+    template <typename ParserT>
+    static ResultT
+    get(parser<ParserT> const &p)
+    {
+        return default_case<typename ParserT::derived_t::left_t>::
+            get(p.derived().left());
+    }
+};
+
+template <typename ResultT>
+struct get_default_parser<ResultT, true> {
+
+    template <typename ParserT>
+    static ResultT
+    get(parser<ParserT> const &p) { return p.derived().right(); }
+};
+
+////////////////////////////////////////
+template <typename CaseT, bool IsSimple>
+struct default_case {
+
+    //  The 'value' constant is true, if the current case_parser or one of its
+    //  left siblings is a default_p generated case_parser.
+    BOOST_STATIC_CONSTANT(bool, value =
+        (CaseT::is_default || default_case<typename CaseT::left_t>::value));
+
+    //  The 'is_epsilon' constant is true, if the current case_parser or one of
+    //  its left siblings is a default_p generated parser with an attached
+    //  epsilon_p (this is generated by the plain default_p).
+    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
+        (CaseT::is_default && CaseT::is_epsilon) ||
+            default_case<typename CaseT::left_t>::is_epsilon
+    ));
+
+    //  The computed 'type' represents the type of the default case branch
+    //  parser (if there is one) or nothing_parser (if there isn't any default
+    //  case branch).
+    typedef typename boost::mpl::if_c<
+            CaseT::is_default, typename CaseT::right_embed_t,
+            typename default_case<typename CaseT::left_t>::type
+        >::type type;
+
+    //  The get function returns the parser attached to the default case branch
+    //  (if there is one) or an instance of a nothing_parser (if there isn't
+    //  any default case branch).
+    template <typename ParserT>
+    static type
+    get(parser<ParserT> const &p)
+    { return get_default_parser<type, CaseT::is_default>::get(p); }
+};
+
+////////////////////////////////////////
+template <typename ResultT, bool IsDefault>
+struct get_default_parser_simple {
+
+    template <typename ParserT>
+    static ResultT
+    get(parser<ParserT> const &p) { return p.derived(); }
+};
+
+template <typename ResultT>
+struct get_default_parser_simple<ResultT, false> {
+
+    template <typename ParserT>
+    static nothing_parser
+    get(parser<ParserT> const &) { return nothing_p; }
+};
+
+////////////////////////////////////////
+//  Specialization of the default_case template for the last (leftmost) element
+//  of the case parser chain.
+template <typename CaseT>
+struct default_case<CaseT, true> {
+
+    //  The 'value' and 'is_epsilon' constant, the 'type' type and the function
+    //  'get' are described above.
+
+    BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
+    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
+        CaseT::is_default && CaseT::is_epsilon
+    ));
+
+    typedef typename boost::mpl::if_c<
+            CaseT::is_default, CaseT, nothing_parser
+        >::type type;
+
+    template <typename ParserT>
+    static type
+    get(parser<ParserT> const &p)
+    { return get_default_parser_simple<type, value>::get(p); }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  The case_chain template calculates recursivly the depth of the left
+//  subchain of the given case branch node.
+template <typename CaseT, bool IsSimple = CaseT::is_simple>
+struct case_chain {
+
+    BOOST_STATIC_CONSTANT(int, depth = (
+        case_chain<typename CaseT::left_t>::depth + 1
+    ));
+};
+
+template <typename CaseT>
+struct case_chain<CaseT, true> {
+
+    BOOST_STATIC_CONSTANT(int, depth = 0);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  The chain_parser template is used to extract the type and the instance of
+//  a left or a right parser, burried arbitrary deep inside the case parser
+//  chain.
+template <int Depth, typename CaseT>
+struct chain_parser {
+
+    typedef typename CaseT::left_t our_left_t;
+
+    typedef typename chain_parser<Depth-1, our_left_t>::left_t  left_t;
+    typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;
+
+    static left_t
+    left(CaseT const &p)
+    { return chain_parser<Depth-1, our_left_t>::left(p.left()); }
+
+    static right_t
+    right(CaseT const &p)
+    { return chain_parser<Depth-1, our_left_t>::right(p.left()); }
+};
+
+template <typename CaseT>
+struct chain_parser<1, CaseT> {
+
+    typedef typename CaseT::left_t  left_t;
+    typedef typename CaseT::right_t right_t;
+
+    static left_t left(CaseT const &p) { return p.left(); }
+    static right_t right(CaseT const &p) { return p.right(); }
+};
+
+template <typename CaseT>
+struct chain_parser<0, CaseT>;      // shouldn't be instantiated
+
+///////////////////////////////////////////////////////////////////////////////
+//  Type computing meta function for calculating the type of the return value
+//  of the used conditional switch expression
+template <typename TargetT, typename ScannerT>
+struct condition_result {
+
+    typedef typename TargetT::template result<ScannerT>::type type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+template <typename LeftT, typename RightT, bool IsDefault>
+struct compound_case_parser
+:   public binary<LeftT, RightT,
+        parser<compound_case_parser<LeftT, RightT, IsDefault> > >
+{
+    typedef compound_case_parser<LeftT, RightT, IsDefault>    self_t;
+    typedef binary_parser_category                  parser_category_t;
+    typedef binary<LeftT, RightT, parser<self_t> >  base_t;
+
+    BOOST_STATIC_CONSTANT(int, value = RightT::value);
+    BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
+    BOOST_STATIC_CONSTANT(bool, is_simple = false);
+    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
+        is_default &&
+            boost::is_same<typename RightT::subject_t, epsilon_parser>::value
+    ));
+
+    compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
+    :   base_t(lhs.derived(), rhs.derived())
+    {}
+
+    template <typename ScannerT>
+    struct result
+    {
+        typedef typename match_result<ScannerT, nil_t>::type type;
+    };
+
+    template <typename ScannerT, typename CondT>
+    typename parser_result<self_t, ScannerT>::type
+    parse(ScannerT const& scan, CondT const &cond) const;
+
+    template <int N1, typename ParserT1, bool IsDefault1>
+    compound_case_parser<
+        self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
+    >
+    operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
+    {
+        //  If the following compile time assertion fires, you've probably used
+        //  more than one default_p case inside the switch_p parser construct.
+        BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);
+
+        //  If this compile time assertion fires, you've probably want to use
+        //  more case_p/default_p case branches, than possible.
+        BOOST_STATIC_ASSERT(
+            case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
+        );
+
+        typedef case_parser<N1, ParserT1, IsDefault1> right_t;
+        return compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//  The parse_switch::do_ functions dispatch to the correct parser, which is
+//  selected through the given conditional switch value.
+template <int Value, int Depth, bool IsDefault>
+struct parse_switch;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  The following generates a couple of parse_switch template specializations
+//  with an increasing number of handled case branches (for 1..N).
+//
+//      template <int Value, bool IsDefault>
+//      struct parse_switch<Value, N, IsDefault> {
+//
+//          template <typename ParserT, typename ScannerT>
+//          static typename parser_result<ParserT, ScannerT>::type
+//          do_(ParserT const &p, ScannerT const &scan, long cond_value,
+//              typename ScannerT::iterator_t const &save)
+//          {
+//              typedef ParserT left_t0;
+//              typedef typename left_t0::left left_t1;
+//              ...
+//
+//              switch (cond_value) {
+//              case left_tN::value:
+//                  return delegate_parse(chain_parser<
+//                          case_chain<ParserT>::depth, ParserT
+//                      >::left(p), scan, save);
+//              ...
+//              case left_t1::value:
+//                  return delegate_parse(chain_parser<
+//                          1, left_t1
+//                      >::right(p.left()), scan, save);
+//
+//              case left_t0::value:
+//              default:
+//                  typedef default_case<ParserT> default_t;
+//                  typedef default_delegate_parse<
+//                              Value, IsDefault, default_t::value>
+//                      default_parse_t;
+//
+//                  return default_parse_t::parse(cond_value, p.right(),
+//                      default_t::get(p), scan, save);
+//              }
+//          }
+//      };
+//
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _)                         \
+    typedef typename BOOST_PP_CAT(left_t, N)::left_t                        \
+        BOOST_PP_CAT(left_t, BOOST_PP_INC(N));                              \
+    /**/
+
+#define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _)                            \
+    case (long)(BOOST_PP_CAT(left_t, N)::value):                            \
+        return delegate_parse(chain_parser<N, left_t1>::right(p.left()),    \
+            scan, save);                                                    \
+    /**/
+
+#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _)                                \
+    template <int Value, bool IsDefault>                                    \
+    struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> {                \
+                                                                            \
+        template <typename ParserT, typename ScannerT>                      \
+        static typename parser_result<ParserT, ScannerT>::type              \
+        do_(ParserT const &p, ScannerT const &scan, long cond_value,        \
+            typename ScannerT::iterator_t const &save)                      \
+        {                                                                   \
+            typedef ParserT left_t0;                                        \
+            BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N),               \
+                BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _)                      \
+                                                                            \
+            switch (cond_value) {                                           \
+            case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value):      \
+                return delegate_parse(                                      \
+                    chain_parser<                                           \
+                        case_chain<ParserT>::depth, ParserT                 \
                >::left(p), scan, save);                                \
                                                                             \
             BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N),               \