text: /*=============================================================================
      Copyright (c) 2001-2007 Joel de Guzman
  
      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_RULE_FEB_12_2007_0440PM)
  #define BOOST_SPIRIT_RULE_FEB_12_2007_0440PM
  
  #include <boost/spirit/home/qi/nonterminal/virtual_component_base.hpp>
  #include <boost/assert.hpp>
  
  namespace boost { namespace spirit { namespace qi { namespace detail
  {
      template <
          typename Iterator, typename Component
        , typename Context, typename Skipper
        , typename Auto
      >
      struct virtual_component : virtual_component_base<Iterator, Context, Skipper>
      {
          typedef virtual_component_base<Iterator, Context, Skipper> base_type;
          typedef typename base_type::skipper_type skipper_type;
          typedef typename base_type::take_no_skipper take_no_skipper;
  
          virtual_component(Component const& component)
            : component(component)
          {
          }
  
          virtual ~virtual_component()
          {
          }
  
          template <typename T>
          static void clear(T& attr)
          {
              attr = T();
          }
  
          template <typename Skipper_>
          bool parse_main(
              Iterator& first
            , Iterator const& last
            , Context& context
            , Skipper_ const& skipper
            , mpl::false_)
          {
              // If Auto is false, the component's attribute is unused.
  
              typedef typename Component::director director;
              return director::parse(
                  component, first, last, context, skipper, unused);
          }
  
          template <typename Skipper_>
          bool parse_main(
              Iterator& first
            , Iterator const& last
            , Context& context
            , Skipper_ const& skipper
            , mpl::true_)
          {
              // If Auto is true, we synthesize the rule's attribute and pass
              // it on to the component. On successful parse, this attribute
              // is swapped back to the the rule's attribute.
  
              typename
                  remove_reference<
                      typename fusion::result_of::value_at_c<
                          typename fusion::result_of::value_at_c<Context, 0>::type
                        , 0
                      >::type
                  >::type
              attribute; // default constructed
              typedef typename Component::director director;
              if (director::parse(
                  component, first, last, context, skipper, attribute))
              {
                  // $$$ need to optimize this for fusion sequences $$$
                  std::swap(fusion::at_c<0>(fusion::at_c<0>(context)), attribute);
                  return true;
              }
              return false;
          }
  
          bool parse_main(
              Iterator& /*first*/
            , Iterator const& /*last*/
            , Context&
            , take_no_skipper
            , mpl::false_)
          {
              BOOST_ASSERT(false); // this should never be called
              return false;
          }
  
          bool parse_main(
              Iterator& /*first*/
            , Iterator const& /*last*/
            , Context& /*context*/
            , take_no_skipper
            , mpl::true_)
          {
              BOOST_ASSERT(false); // this should never be called
              return false;
          }
  
          virtual bool
          parse(
              Iterator& first
            , Iterator const& last
            , Context& context
            , skipper_type const& skipper)
          {
              return parse_main(first, last, context, skipper, Auto());
          }
  
          virtual bool
          parse(
              Iterator& first
            , Iterator const& last
            , Context& context
            , no_skipper)
          {
              return parse_main(first, last, context, unused, Auto());
          }
  
          Component component;
      };
  }}}}
  
  #endif
  