Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78177 - in branches/release/boost/spirit: . actor attribute core debug dynamic error_handling home home/qi/detail home/support/detail home/support/utree/detail include iterator meta phoenix repository/home/qi/directive repository/home/qi/operator repository/home/qi/operator/detail repository/home/support symbols tree utility
From: joel_at_[hidden]
Date: 2012-04-23 22:05:49


Author: djowel
Date: 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
New Revision: 78177
URL: http://svn.boost.org/trac/boost/changeset/78177

Log:
Merge from trunk
Removed:
   branches/release/boost/spirit/actor/
   branches/release/boost/spirit/actor.hpp
   branches/release/boost/spirit/attribute/
   branches/release/boost/spirit/attribute.hpp
   branches/release/boost/spirit/core/
   branches/release/boost/spirit/core.hpp
   branches/release/boost/spirit/debug/
   branches/release/boost/spirit/debug.hpp
   branches/release/boost/spirit/dynamic/
   branches/release/boost/spirit/dynamic.hpp
   branches/release/boost/spirit/error_handling/
   branches/release/boost/spirit/error_handling.hpp
   branches/release/boost/spirit/iterator/
   branches/release/boost/spirit/iterator.hpp
   branches/release/boost/spirit/meta/
   branches/release/boost/spirit/meta.hpp
   branches/release/boost/spirit/phoenix/
   branches/release/boost/spirit/phoenix.hpp
   branches/release/boost/spirit/symbols/
   branches/release/boost/spirit/symbols.hpp
   branches/release/boost/spirit/tree/
   branches/release/boost/spirit/utility/
   branches/release/boost/spirit/utility.hpp
Properties modified:
   branches/release/boost/spirit/ (props changed)
   branches/release/boost/spirit/home/ (props changed)
Text files modified:
   branches/release/boost/spirit/home/qi/detail/assign_to.hpp | 31 +
   branches/release/boost/spirit/home/support/detail/endian.hpp | 6
   branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp | 2
   branches/release/boost/spirit/include/version.hpp | 4
   branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp | 689 +++++++++++++++++++++++++++++++++++++--
   branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp | 634 +++++++++++++++++++++++++++++++++++-
   branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp | 424 ++++++------------------
   branches/release/boost/spirit/repository/home/support/kwd.hpp | 2
   8 files changed, 1403 insertions(+), 389 deletions(-)

Deleted: branches/release/boost/spirit/actor.hpp
==============================================================================
--- branches/release/boost/spirit/actor.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ACTOR
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ACTOR
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_actor.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_actor.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_actor.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/attribute.hpp
==============================================================================
--- branches/release/boost/spirit/attribute.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ATTRIBUTE
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ATTRIBUTE
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_attribute.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_attribute.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_attribute.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/core.hpp
==============================================================================
--- branches/release/boost/spirit/core.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_CORE
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_CORE
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_core.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_core.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_core.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/debug.hpp
==============================================================================
--- branches/release/boost/spirit/debug.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_DEBUG
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_DEBUG
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_debug.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_debug.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_debug.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/dynamic.hpp
==============================================================================
--- branches/release/boost/spirit/dynamic.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_DYNAMIC
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_DYNAMIC
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_dynamic.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_dynamic.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_dynamic.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/error_handling.hpp
==============================================================================
--- branches/release/boost/spirit/error_handling.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ERROR_HANDLING
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ERROR_HANDLING
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_error_handling.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_error_handling.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_error_handling.hpp>
-
-#endif

Modified: branches/release/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/detail/assign_to.hpp (original)
+++ branches/release/boost/spirit/home/qi/detail/assign_to.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -28,11 +28,25 @@
     // accept spirit's unused_type; all no-ops. Compiler optimization will
     // easily strip these away.
     ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename T>
+ struct is_iter_range : mpl::false_ {};
+
+ template <typename I>
+ struct is_iter_range<boost::iterator_range<I> > : mpl::true_ {};
+
+ template <typename C>
+ struct is_container_of_ranges
+ : is_iter_range<typename C::value_type> {};
+ }
+
     template <typename Attribute, typename Iterator, typename Enable>
     struct assign_to_attribute_from_iterators
     {
+ // Common case
         static void
- call(Iterator const& first, Iterator const& last, Attribute& attr)
+ call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::false_)
         {
             if (traits::is_empty(attr))
                 attr = Attribute(first, last);
@@ -41,6 +55,21 @@
                     push_back(attr, *i);
             }
         }
+
+ // If Attribute is a container with value_type==iterator_range<T> just push the
+ // iterator_range into it
+ static void
+ call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::true_)
+ {
+ typename Attribute::value_type rng(first, last);
+ push_back(attr, rng);
+ }
+
+ static void
+ call(Iterator const& first, Iterator const& last, Attribute& attr)
+ {
+ call(first, last, attr, detail::is_container_of_ranges<Attribute>());
+ }
     };
 
     template <typename Attribute, typename Iterator>

Modified: branches/release/boost/spirit/home/support/detail/endian.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/detail/endian.hpp (original)
+++ branches/release/boost/spirit/home/support/detail/endian.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -20,9 +20,9 @@
 
 // If Boost has the endian library, use it, otherwise use an adapted version
 // included with Spirit
-// #if BOOST_VERSION >= 105100
-// #include <boost/endian/integers.hpp>
-// #else
+#if BOOST_VERSION >= 105100
+#include <boost/endian/integers.hpp>
+#else
 #include <boost/spirit/home/support/detail/endian/endian.hpp>
 // #endif
 

Modified: branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp (original)
+++ branches/release/boost/spirit/home/support/utree/detail/utree_detail2.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -1043,7 +1043,7 @@
         if (!pos.node)
         {
             l.push_back(val);
- return utree::iterator(l.first, 0); // begin();
+ return utree::iterator(l.last, l.last->prev);
         }
         l.insert(val, pos);
         return utree::iterator(pos.node->prev, pos.node->prev->prev);

Modified: branches/release/boost/spirit/include/version.hpp
==============================================================================
--- branches/release/boost/spirit/include/version.hpp (original)
+++ branches/release/boost/spirit/include/version.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -14,7 +14,7 @@
 // This is the version of the current Spirit distribution
 //
 ///////////////////////////////////////////////////////////////////////////////
-#define SPIRIT_VERSION 0x2050
-#define SPIRIT_PIZZA_VERSION DEEP_PAN_BBQ // :-O
+#define SPIRIT_VERSION 0x2053
+#define SPIRIT_PIZZA_VERSION SUPER_HOT_SPANISH_SARDINES // :-O
 
 #endif

Deleted: branches/release/boost/spirit/iterator.hpp
==============================================================================
--- branches/release/boost/spirit/iterator.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_ITERATOR
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_ITERATOR
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_iterator.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_iterator.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_iterator.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/meta.hpp
==============================================================================
--- branches/release/boost/spirit/meta.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_META
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_META
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_meta.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_meta.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_meta.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/phoenix.hpp
==============================================================================
--- branches/release/boost/spirit/phoenix.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_PHOENIX
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_PHOENIX
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/phoenix1.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/phoenix1.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/phoenix1.hpp>
-
-#endif

Modified: branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/directive/kwd.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -35,50 +35,98 @@
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd // enables kwd(key)[p]
         , fusion::vector1<T > >
- > : traits::is_string<T> {};
+ > : mpl::true_ {};
     
     template < typename T>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd // enables ikwd(key)[p]
         , fusion::vector1<T > >
- > : traits::is_string<T> {};
+ > : mpl::true_ {};
     
+ template < typename T>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::dkwd // enables dkwd(key)[p]
+ , fusion::vector1<T > >
+ > : mpl::true_ {};
     
+ template < typename T>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::idkwd // enables idkwd(key)[p]
+ , fusion::vector1<T > >
+ > : mpl::true_ {};
+
+
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd // enables kwd(key,exact)[p]
         , fusion::vector2< T1, T2 > >
- > : traits::is_string<T1> {};
+ > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd // enables ikwd(key,exact)[p]
         , fusion::vector2< T1, T2 > >
- > : traits::is_string<T1> {};
+ > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
+ , terminal_ex<repository::tag::dkwd // enables dkwd(key,exact)[p]
+ , fusion::vector2< T1, T2 > >
+ > : mpl::true_ {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::idkwd // enables idkwd(key,exact)[p]
+ , fusion::vector2< T1, T2 > >
+ > : mpl::true_ {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd // enables kwd(min, max)[p]
         , fusion::vector3< T1, T2, T2 > >
- > : traits::is_string<T1> {};
+ > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd // enables ikwd(min, max)[p]
         , fusion::vector3< T1, T2, T2 > >
- > : traits::is_string<T1> {};
+ > : mpl::true_ {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::dkwd // enables dkwd(min, max)[p]
+ , fusion::vector3< T1, T2, T2 > >
+ > : mpl::true_ {};
 
     template < typename T1, typename T2>
     struct use_directive<qi::domain
+ , terminal_ex<repository::tag::idkwd // enables idkwd(min, max)[p]
+ , fusion::vector3< T1, T2, T2 > >
+ > : mpl::true_ {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
       , terminal_ex<repository::tag::kwd // enables kwd(min, inf)[p]
         , fusion::vector3<T1, T2, inf_type > >
- > : traits::is_string<T1> {};
+ > : mpl::true_ {};
     
     template < typename T1, typename T2>
     struct use_directive<qi::domain
       , terminal_ex<repository::tag::ikwd // enables ikwd(min, inf)[p]
         , fusion::vector3<T1, T2, inf_type > >
- > : traits::is_string<T1> {};
+ > : mpl::true_ {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::dkwd // enables dkwd(min, inf)[p]
+ , fusion::vector3<T1, T2, inf_type > >
+ > : mpl::true_ {};
+
+ template < typename T1, typename T2>
+ struct use_directive<qi::domain
+ , terminal_ex<repository::tag::idkwd // enables idkwd(min, inf)[p]
+ , fusion::vector3<T1, T2, inf_type > >
+ > : mpl::true_ {};
 
 
   /* template <> // enables *lazy* kwd(exact)[p]
@@ -102,6 +150,8 @@
 {
     using repository::kwd;
     using repository::ikwd;
+ using repository::dkwd;
+ using repository::idkwd;
     using spirit::inf;
     using spirit::inf_type;
 
@@ -225,13 +275,14 @@
         int &counter;
     };
     
- template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase >
- struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase > >
+ template <typename Subject, typename KeywordType, typename LoopIter , typename NoCase, typename Distinct >
+ struct kwd_parser : spirit::qi::unary_parser<kwd_parser<Subject, KeywordType, LoopIter , NoCase, Distinct > >
     {
         struct kwd_parser_id;
         
         typedef Subject subject_type;
         typedef NoCase no_case_keyword;
+ typedef Distinct distinct;
                 
         typedef typename
             remove_const<typename traits::char_type_of<KeywordType>::type>::type
@@ -256,6 +307,13 @@
            , LoopIter const& iter)
           : subject(subject), iter(iter), keyword(keyword) {}
         
+ template<typename CharEncoding>
+ kwd_parser(Subject const& subject
+ , typename add_reference<KeywordType>::type keyword
+ , LoopIter const& iter, CharEncoding encoding)
+ : subject(subject), iter(iter), keyword(keyword,encoding) {}
+
+
         // Call the subject parser on a non container attribute
         template <typename Iterator, typename Context
           , typename Skipper, typename Attribute>
@@ -329,12 +387,14 @@
             , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
>::type predicate;
             
+
             // Parse the keyword
             bool flag = iter.flag_init();
             int counter = 0;
             Iterator save = first;
             spirit::qi::skip_over(first, last, skipper);
             if(keyword.parse(first,last,context,skipper,unused)){
+ if((!distinct::value) || skipper.parse(first,last,unused,unused,unused)){
                 // Followed by the subject parser
                 spirit::qi::skip_over(first, last, skipper);
                 if(parse_impl(first,last,context,skipper,attr, predicate()))
@@ -342,6 +402,7 @@
                     return iter.register_successful_parse(flag,counter);
                 }
             }
+ }
             first = save;
             return flag;
           }
@@ -350,16 +411,29 @@
         template <typename Context>
         info what(Context& context) const
         {
+ if(distinct::value){
             if(no_case_keyword::value)
+ return info("idkwd", subject.what(context));
+ else
+ return info("dkwd", subject.what(context));
+ }
+ else
+ {
+ if(no_case_keyword::value)
                 return info("ikwd", subject.what(context));
             else
                 return info("kwd", subject.what(context));
         }
+ }
 
         Subject subject;
         LoopIter iter;
         
- spirit::qi::literal_string<KeywordType, true> keyword;
+ typedef typename mpl::if_<
+ no_case_keyword,
+ spirit::qi::no_case_literal_string< KeywordType, true>,
+ spirit::qi::literal_string<KeywordType, true> >::type keyword_string_type;
+ keyword_string_type keyword;
     private:
         // silence MSVC warning C4512: assignment operator could not be generated
         kwd_parser& operator= (kwd_parser const&);
@@ -376,6 +450,151 @@
 
 
     };
+
+template <typename Subject, typename KeywordType, typename LoopIter, typename Distinct>
+ struct complex_kwd_parser : spirit::qi::unary_parser<complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct > >
+ {
+ struct complex_kwd_parser_id;
+ typedef Subject subject_type;
+ typedef Distinct distinct;
+
+ template <typename Context, typename Iterator>
+ struct attribute
+ {
+ typedef typename
+ traits::build_std_vector<
+ typename traits::attribute_of<
+ Subject, Context, Iterator>::type
+ >::type
+ type;
+ };
+
+
+ complex_kwd_parser(Subject const& subject
+ , typename add_reference<KeywordType>::type keyword
+ , LoopIter const& iter)
+ : subject(subject), iter(iter), keyword(keyword) {}
+
+ // Call the subject parser on a non container attribute
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_impl(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr,mpl::false_) const
+ {
+ return subject.parse(first,last,context,skipper,attr);
+ }
+
+ // Call the subject parser on a container attribute
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse_impl(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr,mpl::true_) const
+ {
+
+ // synthesized attribute needs to be default constructed
+ typename traits::container_value<Attribute>::type val =
+ typename traits::container_value<Attribute>::type();
+
+ Iterator save = first;
+ bool r = subject.parse(first,last,context,skipper, val);
+ if (r)
+ {
+ // push the parsed value into our attribute
+ r = traits::push_back(attr, val);
+ if (!r)
+ first = save;
+ }
+ return r;
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute,typename NoCasePass>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, skipper_keyword_marker<Skipper,NoCasePass> const& skipper
+ , Attribute &attr) const
+ {
+
+ typedef typename traits::attribute_of<
+ Subject, Context, Iterator>::type
+ subject_attribute;
+
+ typedef typename mpl::and_<
+ traits::is_container<Attribute>
+ , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
+ >::type predicate;
+
+ if(parse_impl(first,last,context,skipper.skipper,attr, predicate()))
+ return iter.register_successful_parse(skipper.flag,skipper.counter);
+ return false;
+ }
+
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ typedef typename traits::attribute_of<
+ Subject, Context, Iterator>::type
+ subject_attribute;
+
+ typedef typename mpl::and_<
+ traits::is_container<Attribute>
+ , mpl::not_< traits::is_weak_substitute< subject_attribute,Attribute > >
+ >::type predicate;
+
+
+ // Parse the keyword
+ bool flag = iter.flag_init();
+ int counter = 0;
+ Iterator save = first;
+ spirit::qi::skip_over(first, last, skipper);
+ if(keyword.parse(first,last,context,skipper,unused)){
+ if( !distinct::value || skipper.parse(first,last,unused,unused,unused)){
+ // Followed by the subject parser
+ spirit::qi::skip_over(first, last, skipper);
+ if(parse_impl(first,last,context,skipper,attr, predicate()))
+ {
+ return iter.register_successful_parse(flag,counter);
+ }
+ }
+ }
+ first = save;
+ return flag;
+ }
+
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ if(distinct::value)
+ return info("dkwd", subject.what(context));
+ else
+ return info("kwd", subject.what(context));
+ }
+
+ Subject subject;
+ LoopIter iter;
+
+ KeywordType keyword;
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ complex_kwd_parser& operator= (complex_kwd_parser const&);
+
+ template <typename Iterator, typename Context, typename Skipper>
+ static spirit::qi::detail::fail_function<Iterator, Context, Skipper>
+ fail_function(
+ Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper)
+ {
+ return spirit::qi::detail::fail_function<Iterator, Context, Skipper>
+ (first, last, context, skipper);
+ }
+
+ };
+
 }}}}
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -386,177 +605,546 @@
     // Parser generators: make_xxx function (objects)
     ///////////////////////////////////////////////////////////////////////////
     
+ template <typename T1, typename T2, typename Subject, typename Modifiers, typename Distinct, typename MakeDirectiveHelper>
+ struct make_directive_internal_2_args
+ {
+
+ // is the keyword a string keyword ?
+ typedef typename traits::is_string<T1> is_string_kwd_type;
+ // make the keyword type
+ typedef typename mpl::if_< is_string_kwd_type ,
+ T1 ,
+ typename result_of::compile<qi::domain, T1>::type
+ >::type keyword_type;
+
+ typedef typename add_const<keyword_type>::type const_keyword;
+ // select the pass iterator type
+ typedef typename MakeDirectiveHelper::iterator_type iterator_type;
+ // determine if a no case modifier applies to the context
+ typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+ // Determine the full type of the kwd / complex_kwd directive
+ typedef typename
+ mpl::if_<
+ is_string_kwd_type,
+ repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
+ repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct >
+ >::type result_type;
+
+ // Return a kwd parser object
+ template <typename Terminal>
+ result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_ ) const
+ {
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
+ return result_type(subject
+ ,MakeDirectiveHelper::make_iterator(term.args)
+ ,encoding
+ );
+ }
+ template <typename Terminal>
+ result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_ ) const
+ {
+ return result_type(subject
+ ,fusion::at_c<0>(term.args)
+ ,MakeDirectiveHelper::make_iterator(term.args)
+ );
+ }
+ template <typename Terminal>
+ result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const
+ {
+ return create_kwd_string(term,subject,no_case());
+ }
+ // Return a complex_kwd parser object
+ template <typename Terminal>
+ result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
+ {
+ return result_type(subject
+ ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
+ ,MakeDirectiveHelper::make_iterator(term.args)
+ );
+ }
+ // Select which object type to return
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+ {
+ return create_kwd(term, subject, modifiers, is_string_kwd_type());
+ }
+
+ };
+
      // Directive kwd(key)[p]
+ template <typename T1, typename Subject, typename Modifiers, typename Distinct>
+ struct make_directive_internal
+ {
+ // is the keyword a string keyword ?
+ typedef typename traits::is_string<T1> is_string_kwd_type;
+ // make the keyword type
+ typedef typename mpl::if_< is_string_kwd_type ,
+ T1 ,
+ typename result_of::compile<qi::domain, T1, Modifiers>::type
+ >::type keyword_type;
+
+ typedef typename add_const<keyword_type>::type const_keyword;
+ // select the pass iterator type
+ typedef repository::qi::kwd_pass_iterator<int> iterator_type;
+ // determine if a no case modifier applies to the context
+ typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+ // Determine the full type of the kwd / complex_kwd directive
+ typedef typename
+ mpl::if_<
+ is_string_kwd_type,
+ repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case, Distinct >,
+ repository::qi::complex_kwd_parser<Subject, const_keyword, iterator_type, Distinct>
+ >::type result_type;
+
+ // Return a kwd parser object
+ template <typename Terminal>
+ result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::true_) const
+ {
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
+
+ return result_type(subject
+ ,fusion::at_c<0>(term.args)
+ ,iterator_type()
+ ,encoding
+ );
+
+ }
+ template <typename Terminal>
+ result_type create_kwd_string(Terminal const &term, Subject const & subject, boost::mpl::false_) const
+ {
+ return result_type(subject
+ ,fusion::at_c<0>(term.args)
+ ,iterator_type()
+ );
+ }
+ template <typename Terminal>
+ result_type create_kwd(Terminal const &term, Subject const & subject, Modifiers const& modifiers, boost::mpl::true_ ) const
+ {
+ return create_kwd_string(term,subject,no_case());
+ }
+ // Return a complex_kwd parser object
+ template <typename Terminal>
+ result_type create_kwd(Terminal const &term , Subject const & subject, Modifiers const& modifiers, boost::mpl::false_ ) const
+ {
+ return result_type(subject
+ ,compile<qi::domain>(fusion::at_c<0>(term.args),modifiers)
+ ,iterator_type()
+ );
+ }
+ // Select which object type to return
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers ) const
+ {
+ return create_kwd(term, subject, modifiers, is_string_kwd_type());
+ }
+ };
+
     template <typename T1, typename Subject, typename Modifiers>
     struct make_directive<
         terminal_ex<repository::tag::kwd, fusion::vector1<T1> >, Subject, Modifiers>
     {
+ typedef make_directive_internal<T1, Subject, Modifiers, mpl::false_> make_directive_type;
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+ {
+
+ return make_directive_type()(term, subject, modifiers);
+ }
+
+ };
+
+ template <typename T1, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::dkwd, fusion::vector1<T1> >, Subject, Modifiers>
+ {
+ typedef make_directive_internal<T1, Subject, Modifiers, mpl::true_> make_directive_type;
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+ {
+
+ return make_directive_type()(term, subject, modifiers);
+ }
+
+ };
+
+
+
+ // Directive ikwd(key)[p]
+ template <typename T1, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
+ {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
         
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
                 
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
-
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
+
             return result_type(subject
                         ,fusion::at_c<0>(term.args)
                         ,iterator_type()
+ ,encoding
                         );
         }
     };
     
- // Directive ikwd(key)[p]
     template <typename T1, typename Subject, typename Modifiers>
     struct make_directive<
- terminal_ex<repository::tag::ikwd, fusion::vector1<T1> >, Subject, Modifiers>
+ terminal_ex<repository::tag::idkwd, fusion::vector1<T1> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_pass_iterator<int> iterator_type;
         
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
- /* typename spirit::detail::get_encoding<Modifiers,
- spirit::char_encoding::standard>::type encoding;*/
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
                 
             return result_type(subject
                         ,fusion::at_c<0>(term.args)
                         ,iterator_type()
+ ,encoding
                         );
         }
     };
     
     // Directive kwd(key,exact)[p]
+ template <typename T>
+ struct make_exact_helper
+ {
+ typedef repository::qi::kwd_exact_iterator<T> iterator_type;
+ template<typename Args>
+ static iterator_type make_iterator(Args const& args)
+ {
+ return iterator_type(fusion::at_c<1>(args));
+ }
+ };
+
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
         terminal_ex<repository::tag::kwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
     {
+ typedef make_directive_internal_2_args< T1
+ , T2
+ , Subject
+ , Modifiers
+ , mpl::false_
+ , make_exact_helper<T2>
+ > make_directive_type;
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+ {
+
+ return make_directive_type()(term,subject, modifiers);
+ }
+
+ };
+
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::dkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+ {
+ typedef make_directive_internal_2_args< T1
+ , T2
+ , Subject
+ , Modifiers
+ , mpl::true_
+ , make_exact_helper<T2>
+ > make_directive_type;
+
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+ {
+
+ return make_directive_type()(term, subject, modifiers);
+ }
+
+ };
+
+
+ // Directive ikwd(key,exact)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+ {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
         
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
         {
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
             return result_type(subject
                         ,fusion::at_c<0>(term.args)
                         ,fusion::at_c<1>(term.args)
+ , encoding
                         );
         }
     };
 
- // Directive ikwd(key,exact)[p]
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
- terminal_ex<repository::tag::ikwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
+ terminal_ex<repository::tag::idkwd, fusion::vector2<T1,T2> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_exact_iterator<T2> iterator_type;
         
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
         
         template <typename Terminal>
         result_type operator()(
- Terminal const& term, Subject const& subject, unused_type) const
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
         {
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
             return result_type(subject
                         , fusion::at_c<0>(term.args)
                         , fusion::at_c<1>(term.args)
+ , encoding
                         );
         }
     };
     
+
     // Directive kwd(min, max)[p]
+
+ template <typename T>
+ struct make_finite_helper
+ {
+ typedef repository::qi::kwd_finite_iterator<T> iterator_type;
+ template<typename Args>
+ static iterator_type make_iterator(Args const& args)
+ {
+ return iterator_type(fusion::at_c<1>(args),fusion::at_c<2>(args));
+ }
+
+ };
+
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
         terminal_ex<repository::tag::kwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
     {
+ typedef make_directive_internal_2_args< T1
+ , T2
+ , Subject
+ , Modifiers
+ , mpl::false_
+ , make_finite_helper<T2>
+ > make_directive_type;
+
+
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+ {
+
+ return make_directive_type()(term,subject, modifiers);
+ }
+
+ };
+
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,T2> >, Subject, Modifiers>
+ {
+
+ typedef make_directive_internal_2_args< T1
+ , T2
+ , Subject
+ , Modifiers
+ , mpl::true_
+ , make_finite_helper<T2>
+ > make_directive_type;
+
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, Modifiers const& modifiers) const
+ {
+
+ return make_directive_type()(term,subject, modifiers);
+ }
+
+ };
+
+ // Directive ikwd(min, max)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
+ {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
                     
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
+
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
             return result_type(subject, fusion::at_c<0>(term.args),
                 iterator_type(
                     fusion::at_c<1>(term.args)
                   , fusion::at_c<2>(term.args)
+ , encoding
                 )
             );
         }
     };
 
- // Directive ikwd(min, max)[p]
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
- terminal_ex<repository::tag::ikwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
+ terminal_ex<repository::tag::idkwd, fusion::vector3< T1, T2, T2> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_finite_iterator<T2> iterator_type;
                 
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
         
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
             return result_type(subject, fusion::at_c<0>(term.args),
                 iterator_type(
                     fusion::at_c<1>(term.args)
                   , fusion::at_c<2>(term.args)
+ , encoding
                 )
             );
         }
     };
     
+
     // Directive kwd(min, inf)[p]
+
+ template <typename T>
+ struct make_infinite_helper
+ {
+ typedef repository::qi::kwd_infinite_iterator<T> iterator_type;
+ template<typename Args>
+ static iterator_type make_iterator(Args const& args)
+ {
+ return iterator_type(fusion::at_c<1>(args));
+ }
+
+ };
+
+
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
- terminal_ex<repository::tag::kwd
+ terminal_ex<repository::tag::kwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
+ {
+ typedef make_directive_internal_2_args< T1
+ , T2
+ , Subject
+ , Modifiers
+ , mpl::false_
+ , make_infinite_helper<T2>
+ > make_directive_type;
+
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+
+ return make_directive_type()(term,subject, unused_type());
+ }
+
+ };
+
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::dkwd, fusion::vector3<T1,T2,inf_type> >, Subject, Modifiers>
+ {
+ typedef make_directive_internal_2_args< T1
+ , T2
+ , Subject
+ , Modifiers
+ , mpl::false_
+ , make_infinite_helper<T2>
+ > make_directive_type;
+
+ typedef typename make_directive_type::result_type result_type;
+ template <typename Terminal>
+ result_type operator()(
+ Terminal const& term, Subject const& subject, unused_type) const
+ {
+
+ return make_directive_type()(term,subject, unused_type());
+ }
+
+ };
+
+
+ // Directive ikwd(min, inf)[p]
+ template <typename T1, typename T2, typename Subject, typename Modifiers>
+ struct make_directive<
+ terminal_ex<repository::tag::ikwd
         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
- typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
         
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, no_case > result_type;
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::false_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
             Terminal const& term, Subject const& subject, unused_type) const
         {
+ typename spirit::detail::get_encoding<Modifiers,
+ spirit::char_encoding::standard>::type encoding;
+
             return result_type(subject
                 , fusion::at_c<0>(term.args)
                 , fusion::at_c<1>(term.args)
+ , encoding
                 );
         }
     };
     
- // Directive ikwd(min, inf)[p]
     template <typename T1, typename T2, typename Subject, typename Modifiers>
     struct make_directive<
- terminal_ex<repository::tag::ikwd
+ terminal_ex<repository::tag::idkwd
         , fusion::vector3<T1, T2, inf_type> >, Subject, Modifiers>
     {
         typedef typename add_const<T1>::type const_keyword;
         typedef repository::qi::kwd_infinite_iterator<T2> iterator_type;
         
- typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_ > result_type;
+ typedef repository::qi::kwd_parser<Subject, const_keyword, iterator_type, mpl::true_, mpl::true_ > result_type;
 
         template <typename Terminal>
         result_type operator()(
@@ -568,6 +1156,7 @@
             return result_type(subject
                 , fusion::at_c<0>(term.args)
                 , fusion::at_c<1>(term.args)
+ , encoding
                 );
         }
     };
@@ -578,10 +1167,32 @@
 namespace boost { namespace spirit { namespace traits
 {
     template <typename Subject, typename KeywordType
- , typename LoopIter, typename NoCase >
+ , typename LoopIter, typename NoCase , typename Distinct>
     struct has_semantic_action<
- repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase > >
+ repository::qi::kwd_parser< Subject, KeywordType, LoopIter, NoCase, Distinct > >
+ : unary_has_semantic_action<Subject> {};
+
+ template <typename Subject, typename KeywordType
+ , typename LoopIter, typename Distinct >
+ struct has_semantic_action<
+ repository::qi::complex_kwd_parser< Subject, KeywordType, LoopIter, Distinct > >
       : unary_has_semantic_action<Subject> {};
+
+ template <typename Subject, typename KeywordType
+ , typename LoopIter, typename NoCase, typename Attribute, typename Context
+ , typename Iterator, typename Distinct>
+ struct handles_container<repository::qi::kwd_parser<Subject, KeywordType, LoopIter, NoCase, Distinct>, Attribute
+ , Context, Iterator>
+ : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+
+ template <typename Subject, typename KeywordType
+ , typename LoopIter
+ , typename Attribute, typename Context
+ , typename Iterator, typename Distinct>
+ struct handles_container<repository::qi::complex_kwd_parser<Subject, KeywordType, LoopIter, Distinct>, Attribute
+ , Context, Iterator>
+ : unary_handles_container<Subject, Attribute, Context, Iterator> {};
+
 }}}
 
 #endif

Modified: branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/operator/detail/keywords.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -1,6 +1,5 @@
 /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
+ Copyright (c) 2011-2012 Thomas Bernard
 
     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)
@@ -11,39 +10,35 @@
 #if defined(_MSC_VER)
 #pragma once
 #endif
-
+#include <boost/fusion/include/nview.hpp>
+#include <boost/spirit/home/qi/string/lit.hpp>
+#include <boost/fusion/include/at.hpp>
 namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
-
- // This helper class enables jumping over intermediate directives
- // down the kwd parser iteration count checking policy
- struct register_successful_parse
- {
- template <typename Subject>
- static bool call(Subject const &subject,bool &flag, int &counter)
- {
- return subject.iter.register_successful_parse(flag,counter);
- }
- template <typename Subject, typename Action>
- static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
- {
- return subject.subject.iter.register_successful_parse(flag,counter);
- }
- template <typename Subject>
- static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
- {
- return subject.subject.iter.register_successful_parse(flag,counter);
- }
- };
         // Variant visitor class which handles dispatching the parsing to the selected parser
         // This also handles passing the correct attributes and flags/counters to the subject parsers
+ template<typename T>
+ struct is_distinct : T::distinct { };
  
+ template<typename T, typename Action>
+ struct is_distinct< spirit::qi::action<T,Action> > : T::distinct { };
+
+ template<typename T>
+ struct is_distinct< spirit::qi::hold_directive<T> > : T::distinct { };
+
+
+
         template < typename Elements, typename Iterator ,typename Context ,typename Skipper
                   ,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
- class parse_dispatcher
+ struct parse_dispatcher
             : public boost::static_visitor<bool>
         {
+
+ typedef Iterator iterator_type;
+ typedef Context context_type;
+ typedef Skipper skipper_type;
+ typedef Elements elements_type;
+
             typedef typename add_reference<Attribute>::type attr_reference;
-
             public:
             parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
           , Context& context, Skipper const& skipper
@@ -65,7 +60,8 @@
                 , Index& idx ) const
             {
                 Iterator save = first;
- skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+ skipper_keyword_marker<Skipper,NoCasePass>
+ marked_skipper(skipper,flags[Index::value],counters[Index::value]);
                 
                 if(subject.parse(first,last,context,marked_skipper,unused))
                 {
@@ -84,7 +80,8 @@
             {
                
                 Iterator save = first;
- skipper_keyword_marker<Skipper,NoCasePass> marked_skipper(skipper,flags[Index::value],counters[Index::value]);
+ skipper_keyword_marker<Skipper,NoCasePass>
+ marked_skipper(skipper,flags[Index::value],counters[Index::value]);
                 if(subject.parse(first,last,context,marked_skipper,fusion::at_c<Index::value>(attr)))
                 {
                         return true;
@@ -95,12 +92,28 @@
 
             // Handle unused attributes
             template <typename T> bool call(T &idx, mpl::false_) const{
+
+ typedef typename mpl::at<Elements,T>::type ElementType;
+ if(
+ (!is_distinct<ElementType>::value)
+ || skipper.parse(first,last,unused,unused,unused)
+ ){
+ spirit::qi::skip_over(first, last, skipper);
                 return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
             }
+ return false;
+ }
             // Handle normal attributes
             template <typename T> bool call(T &idx, mpl::true_) const{
+ typedef typename mpl::at<Elements,T>::type ElementType;
+ if(
+ (!is_distinct<ElementType>::value)
+ || skipper.parse(first,last,unused,unused,unused)
+ ){
                 return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
             }
+ return false;
+ }
             
             const Elements &elements;
             Iterator &first;
@@ -111,7 +124,572 @@
             Counters &counters;
             attr_reference attr;
         };
+ // string keyword loop handler
+ template <typename Elements, typename StringKeywords, typename IndexList, typename FlagsType, typename Modifiers>
+ struct string_keywords
+ {
+ // Create a variant type to be able to store parser indexes in the embedded symbols parser
+ typedef typename
+ spirit::detail::as_variant<
+ IndexList >::type parser_index_type;
       
+ ///////////////////////////////////////////////////////////////////////////
+ // build_char_type_sequence
+ //
+ // Build a fusion sequence from the kwd directive specified character type.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence >
+ struct build_char_type_sequence
+ {
+ struct element_char_type
+ {
+ template <typename T>
+ struct result;
+
+ template <typename F, typename Element>
+ struct result<F(Element)>
+ {
+ typedef typename Element::char_type type;
+
+ };
+ template <typename F, typename Element,typename Action>
+ struct result<F(spirit::qi::action<Element,Action>) >
+ {
+ typedef typename Element::char_type type;
+ };
+ template <typename F, typename Element>
+ struct result<F(spirit::qi::hold_directive<Element>)>
+ {
+ typedef typename Element::char_type type;
+ };
+
+ // never called, but needed for decltype-based result_of (C++0x)
+ template <typename Element>
+ typename result<element_char_type(Element)>::type
+ operator()(Element&) const;
+ };
+
+ // Compute the list of character types of the child kwd directives
+ typedef typename
+ fusion::result_of::transform<Sequence, element_char_type>::type
+ type;
+ };
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ // get_keyword_char_type
+ //
+ // Collapses the character type comming from the subject kwd parsers and
+ // and checks that they are all identical (necessary in order to be able
+ // to build a tst parser to parse the keywords.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence>
+ struct get_keyword_char_type
+ {
+ // Make sure each of the types occur only once in the type list
+ typedef typename
+ mpl::fold<
+ Sequence, mpl::vector<>,
+ mpl::if_<
+ mpl::contains<mpl::_1, mpl::_2>,
+ mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
+ >
+ >::type
+ no_duplicate_char_types;
+
+ // If the compiler traps here this means you mixed
+ // character type for the keywords specified in the
+ // kwd directive sequence.
+ BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
+
+ typedef typename mpl::front<no_duplicate_char_types>::type type;
+
+ };
+
+ // Get the character type for the tst parser
+ typedef typename build_char_type_sequence< StringKeywords >::type char_types;
+ typedef typename get_keyword_char_type<
+ typename mpl::if_<
+ mpl::equal_to<
+ typename mpl::size < char_types >::type
+ , mpl::int_<0>
+ >
+ , mpl::vector< boost::spirit::standard::char_type >
+ , char_types >::type
+ >::type char_type;
+
+ // Our symbols container
+ typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
+
+ // Filter functor used for case insensitive parsing
+ template <typename CharEncoding>
+ struct no_case_filter
+ {
+ char_type operator()(char_type ch) const
+ {
+ return static_cast<char_type>(CharEncoding::tolower(ch));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // build_case_type_sequence
+ //
+ // Build a fusion sequence from the kwd/ikwd directives
+ // in order to determine if case sensitive and case insensitive
+ // keywords have been mixed.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence >
+ struct build_case_type_sequence
+ {
+ struct element_case_type
+ {
+ template <typename T>
+ struct result;
+
+ template <typename F, typename Element>
+ struct result<F(Element)>
+ {
+ typedef typename Element::no_case_keyword type;
+
+ };
+ template <typename F, typename Element,typename Action>
+ struct result<F(spirit::qi::action<Element,Action>) >
+ {
+ typedef typename Element::no_case_keyword type;
+ };
+ template <typename F, typename Element>
+ struct result<F(spirit::qi::hold_directive<Element>)>
+ {
+ typedef typename Element::no_case_keyword type;
+ };
+
+ // never called, but needed for decltype-based result_of (C++0x)
+ template <typename Element>
+ typename result<element_case_type(Element)>::type
+ operator()(Element&) const;
+ };
+
+ // Compute the list of character types of the child kwd directives
+ typedef typename
+ fusion::result_of::transform<Sequence, element_case_type>::type
+ type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // get_nb_case_types
+ //
+ // Counts the number of entries in the case type sequence matching the
+ // CaseType parameter (mpl::true_ -> case insensitve
+ // , mpl::false_ -> case sensitive
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Sequence,typename CaseType>
+ struct get_nb_case_types
+ {
+ // Make sure each of the types occur only once in the type list
+ typedef typename
+ mpl::count_if<
+ Sequence, mpl::equal_to<mpl::_,CaseType>
+ >::type type;
+
+
+ };
+ // Build the case type sequence
+ typedef typename build_case_type_sequence< StringKeywords >::type case_type_sequence;
+ // Count the number of case sensitive entries and case insensitve entries
+ typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
+ typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
+ // Get the size of the original sequence
+ typedef typename mpl::size<IndexList>::type nb_elements;
+ // Determine if all the kwd directive are case sensitive/insensitive
+ typedef typename mpl::and_<
+ typename mpl::greater< nb_elements, mpl::int_<0> >::type
+ , typename mpl::equal_to< ikwd_count, nb_elements>::type
+ >::type all_ikwd;
+
+ typedef typename mpl::and_<
+ typename mpl::greater< nb_elements, mpl::int_<0> >::type
+ , typename mpl::equal_to< kwd_count, nb_elements>::type
+ >::type all_kwd;
+
+ typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
+
+ // Do we have a no case modifier
+ typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
+
+ // Should the no_case filter always be used ?
+ typedef typename mpl::or_<
+ no_case_modifier,
+ mpl::and_<
+ all_directives_of_same_type
+ ,all_ikwd
+ >
+ >::type
+ no_case;
+
+ typedef no_case_filter<
+ typename spirit::detail::get_encoding_with_case<
+ Modifiers
+ , char_encoding::standard
+ , no_case::value>::type>
+ nc_filter;
+ // Determine the standard case filter type
+ typedef typename mpl::if_<
+ no_case
+ , nc_filter
+ , spirit::qi::tst_pass_through >::type
+ first_pass_filter_type;
+
+ typedef typename mpl::or_<
+ all_directives_of_same_type
+ , no_case_modifier
+ >::type requires_one_pass;
+
+
+ // Functor which adds all the keywords/subject parser indexes
+ // collected from the subject kwd directives to the keyword tst parser
+ struct keyword_entry_adder
+ {
+ typedef int result_type;
+
+ keyword_entry_adder(shared_ptr<keywords_type> lookup,FlagsType &flags, Elements &elements) :
+ lookup(lookup)
+ ,flags(flags)
+ ,elements(elements)
+ {}
+
+ template <typename T>
+ int operator()(const T &index) const
+ {
+ return call(fusion::at_c<T::value>(elements),index);
+ }
+
+ template <typename T, typename Position, typename Action>
+ int call(const spirit::qi::action<T,Action> &parser, const Position position ) const
+ {
+
+ // Make the keyword/parse index entry in the tst parser
+ lookup->add(
+ traits::get_begin<char_type>(parser.subject.keyword.str),
+ traits::get_end<char_type>(parser.subject.keyword.str),
+ position
+ );
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.subject.iter.flag_init();
+ return 0;
+ }
+
+ template <typename T, typename Position>
+ int call( const T & parser, const Position position) const
+ {
+ // Make the keyword/parse index entry in the tst parser
+ lookup->add(
+ traits::get_begin<char_type>(get_string(parser.keyword)),
+ traits::get_end<char_type>(get_string(parser.keyword)),
+ position
+ );
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.iter.flag_init();
+ return 0;
+ }
+
+ template <typename T, typename Position>
+ int call( const spirit::qi::hold_directive<T> & parser, const Position position) const
+ {
+ // Make the keyword/parse index entry in the tst parser
+ lookup->add(
+ traits::get_begin<char_type>(parser.subject.keyword.str),
+ traits::get_end<char_type>(parser.subject.keyword.str),
+ position
+ );
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.subject.iter.flag_init();
+ return 0;
+ }
+
+ template <typename String, bool no_attribute>
+ const String & get_string(const boost::spirit::qi::literal_string<String,no_attribute> &parser) const
+ {
+ return parser.str;
+ }
+
+ template <typename String, bool no_attribute>
+ const typename boost::spirit::qi::no_case_literal_string<String,no_attribute>::string_type &
+ get_string(const boost::spirit::qi::no_case_literal_string<String,no_attribute> &parser) const
+ {
+ return parser.str_lo;
+ }
+
+
+
+ shared_ptr<keywords_type> lookup;
+ FlagsType & flags;
+ Elements &elements;
+ };
+
+ string_keywords(Elements &elements,FlagsType &flags_init) : lookup(new keywords_type())
+ {
+ // Loop through all the subject parsers to build the keyword parser symbol parser
+ IndexList indexes;
+ keyword_entry_adder f1(lookup,flags_init,elements);
+ fusion::for_each(indexes,f1);
+
+ }
+ template <typename Iterator,typename ParseVisitor, typename Skipper>
+ bool parse(
+ Iterator &first,
+ const Iterator &last,
+ const ParseVisitor &parse_visitor,
+ const Skipper &skipper) const
+ {
+ if(parser_index_type* val_ptr =
+ lookup->find(first,last,first_pass_filter_type()))
+ {
+ if(!apply_visitor(parse_visitor,*val_ptr)){
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
+ bool parse(
+ Iterator &first,
+ const Iterator &last,
+ const ParseVisitor &parse_visitor,
+ const NoCaseParseVisitor &no_case_parse_visitor,
+ const Skipper &skipper) const
+ {
+ Iterator saved_first = first;
+ if(parser_index_type* val_ptr =
+ lookup->find(first,last,first_pass_filter_type()))
+ {
+ if(!apply_visitor(parse_visitor,*val_ptr)){
+ return false;
+ }
+ return true;
+ }
+ // Second pass case insensitive
+ else if(parser_index_type* val_ptr
+ = lookup->find(saved_first,last,nc_filter()))
+ {
+ first = saved_first;
+ if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+ shared_ptr<keywords_type> lookup;
+
+
+ };
+
+ struct empty_keywords_list
+ {
+ typedef mpl::true_ requires_one_pass;
+
+ empty_keywords_list()
+ {}
+ template<typename Elements>
+ empty_keywords_list(const Elements &)
+ {}
+
+ template<typename Elements, typename FlagsInit>
+ empty_keywords_list(const Elements &, const FlagsInit &)
+ {}
+
+ template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
+ bool parse(
+ Iterator &first,
+ const Iterator &last,
+ const ParseVisitor &parse_visitor,
+ const NoCaseParseVisitor &no_case_parse_visitor,
+ const Skipper &skipper) const
+ {
+ return false;
+ }
+
+ template <typename Iterator,typename ParseVisitor, typename Skipper>
+ bool parse(
+ Iterator &first,
+ const Iterator &last,
+ const ParseVisitor &parse_visitor,
+ const Skipper &skipper) const
+ {
+ return false;
+ }
+
+ template <typename ParseFunction>
+ bool parse( ParseFunction &function ) const
+ {
+ return false;
+ }
+ };
+
+ template<typename ComplexKeywords>
+ struct complex_keywords
+ {
+ // Functor which performs the flag initialization for the complex keyword parsers
+ template <typename FlagsType, typename Elements>
+ struct flag_init_value_setter
+ {
+ typedef int result_type;
+
+ flag_init_value_setter(Elements &elements,FlagsType &flags)
+ :flags(flags)
+ ,elements(elements)
+ {}
+
+ template <typename T>
+ int operator()(const T &index) const
+ {
+ return call(fusion::at_c<T::value>(elements),index);
+ }
+
+ template <typename T, typename Position, typename Action>
+ int call(const spirit::qi::action<T,Action> &parser, const Position position ) const
+ {
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.subject.iter.flag_init();
+ return 0;
+ }
+
+ template <typename T, typename Position>
+ int call( const T & parser, const Position position) const
+ {
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.iter.flag_init();
+ return 0;
+ }
+
+ template <typename T, typename Position>
+ int call( const spirit::qi::hold_directive<T> & parser, const Position position) const
+ {
+ // Get the initial state of the flags array and store it in the flags initializer
+ flags[Position::value]=parser.subject.iter.flag_init();
+ return 0;
+ }
+
+ FlagsType & flags;
+ Elements &elements;
+ };
+
+ template <typename Elements, typename Flags>
+ complex_keywords(Elements &elements, Flags &flags)
+ {
+ flag_init_value_setter<Flags,Elements> flag_initializer(elements,flags);
+ fusion::for_each(complex_keywords_inst,flag_initializer);
+ }
+
+ template <typename ParseFunction>
+ bool parse( ParseFunction &function ) const
+ {
+ return fusion::any(complex_keywords_inst,function);
+ }
+
+ ComplexKeywords complex_keywords_inst;
+ };
+ // This helper class enables jumping over intermediate directives
+ // down the kwd parser iteration count checking policy
+ struct register_successful_parse
+ {
+ template <typename Subject>
+ static bool call(Subject const &subject,bool &flag, int &counter)
+ {
+ return subject.iter.register_successful_parse(flag,counter);
+ }
+ template <typename Subject, typename Action>
+ static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
+ {
+ return subject.subject.iter.register_successful_parse(flag,counter);
+ }
+ template <typename Subject>
+ static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
+ {
+ return subject.subject.iter.register_successful_parse(flag,counter);
+ }
+ };
+
+ // This helper class enables jumping over intermediate directives
+ // down the kwd parser
+ struct extract_keyword
+ {
+ template <typename Subject>
+ static Subject const& call(Subject const &subject)
+ {
+ return subject;
+ }
+ template <typename Subject, typename Action>
+ static Subject const& call(spirit::qi::action<Subject, Action> const &subject)
+ {
+ return subject.subject;
+ }
+ template <typename Subject>
+ static Subject const& call(spirit::qi::hold_directive<Subject> const &subject)
+ {
+ return subject.subject;
+ }
+ };
+
+ template <typename ParseDispatcher>
+ struct complex_kwd_function
+ {
+ typedef typename ParseDispatcher::iterator_type Iterator;
+ typedef typename ParseDispatcher::context_type Context;
+ typedef typename ParseDispatcher::skipper_type Skipper;
+ complex_kwd_function(
+ Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper, ParseDispatcher &dispatcher)
+ : first(first)
+ , last(last)
+ , context(context)
+ , skipper(skipper)
+ , dispatcher(dispatcher)
+ {
+ }
+
+ template <typename Component>
+ bool operator()(Component const& component)
+ {
+ Iterator save = first;
+ if(
+ extract_keyword::call(
+ fusion::at_c<
+ Component::value
+ ,typename ParseDispatcher::elements_type
+ >(dispatcher.elements)
+ )
+ .keyword.parse(
+ first
+ ,last
+ ,context
+ ,skipper
+ ,unused)
+ )
+ {
+ if(!dispatcher(component)){
+ first = save;
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ Iterator& first;
+ Iterator const& last;
+ Context& context;
+ Skipper const& skipper;
+ ParseDispatcher const& dispatcher;
+
+ private:
+ // silence MSVC warning C4512: assignment operator could not be generated
+ complex_kwd_function& operator= (complex_kwd_function const&);
+ };
+
+
 }}}}}
 
 #endif

Modified: branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp (original)
+++ branches/release/boost/spirit/repository/home/qi/operator/keywords.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -1,6 +1,6 @@
 /*=============================================================================
     Copyright (c) 2001-2011 Joel de Guzman
- Copyright (c) 2011 Thomas Bernard
+ Copyright (c) 2011-2012 Thomas Bernard
 
     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)
@@ -22,6 +22,7 @@
 #include <boost/fusion/include/iter_fold.hpp>
 #include <boost/fusion/include/at.hpp>
 #include <boost/fusion/include/value_at.hpp>
+#include <boost/fusion/include/mpl.hpp>
 #include <boost/optional.hpp>
 #include <boost/foreach.hpp>
 #include <boost/array.hpp>
@@ -35,10 +36,14 @@
 #include <boost/mpl/size.hpp>
 #include <boost/mpl/equal_to.hpp>
 #include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/filter_view.hpp>
+#include <boost/fusion/include/zip_view.hpp>
+#include <boost/fusion/include/as_vector.hpp>
 #include <boost/variant/static_visitor.hpp>
 #include <boost/type_traits/remove_const.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
+#include <boost/fusion/include/any.hpp>
 
 
 namespace boost { namespace spirit
@@ -62,6 +67,7 @@
     namespace detail
     {
         BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(complex_kwd_parser_id)
 
     
     }
@@ -76,6 +82,16 @@
     template <typename Subject>
     struct is_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_kwd_parser_id<Subject> {};
 
+ template <typename T>
+ struct is_complex_kwd_parser : detail::has_complex_kwd_parser_id<T> {};
+
+ template <typename Subject, typename Action>
+ struct is_complex_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_complex_kwd_parser_id<Subject> {};
+
+ template <typename Subject>
+ struct is_complex_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_complex_kwd_parser_id<Subject> {};
+
+
     // Keywords operator
     template <typename Elements, typename Modifiers>
     struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
@@ -101,10 +117,15 @@
         typedef typename mpl::count_if<
                 Elements,
                         mpl::not_<
+ mpl::or_<
                             is_kwd_parser<
                                 mpl::_1
+ > ,
+ is_complex_kwd_parser<
+ mpl::_1
>
>
+ >
> non_kwd_subject_count;
         
         /// If the assertion fails here then you probably forgot to wrap a
@@ -130,208 +151,38 @@
             typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
             
             // Transform the range_c to an mpl vector in order to be able to transform it into a variant
- typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type int_vector;
+ typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type type;
         
- // Build the variant type containing the indexes of the parsers
- typedef typename
- spirit::detail::as_variant<
- int_vector >::type type;
         };
+ // Build an index mpl vector
+ typedef typename build_parser_tags< Elements >::type parser_index_vector;
         
- // Create a variant type to be able to store parser indexes in the embedded symbols parser
- typedef typename build_parser_tags< Elements >::type parser_index_type;
-
- ///////////////////////////////////////////////////////////////////////////
- // build_char_type_sequence
- //
- // Build a fusion sequence from the kwd directive specified character type.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_char_type_sequence
- {
- struct element_char_type
- {
- template <typename T>
- struct result;
+ template <typename idx>
+ struct is_complex_kwd_parser_filter : is_complex_kwd_parser< typename mpl::at<Elements, idx>::type >
+ {};
+
+ template <typename idx>
+ struct is_kwd_parser_filter : is_kwd_parser< typename mpl::at<Elements, idx>::type >
+ {};
 
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::char_type type;
+ // filter out the string kwd directives
+ typedef typename mpl::filter_view< Elements, is_kwd_parser<mpl_::_> >::type string_keywords;
                         
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::char_type type;
- };
- template <typename F, typename Element>
- struct result<F(spirit::qi::hold_directive<Element>)>
- {
- typedef typename Element::char_type type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_char_type(Element)>::type
- operator()(Element&) const;
- };
+ typedef typename mpl::filter_view< parser_index_vector ,
+ is_kwd_parser_filter< mpl::_ >
+ >::type string_keyword_indexes;
+ // filter out the complex keywords
+ typedef typename mpl::filter_view< parser_index_vector ,
+ is_complex_kwd_parser_filter< mpl::_ >
+ >::type complex_keywords_indexes;
 
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_char_type>::type
- type;
- };
-
-
- ///////////////////////////////////////////////////////////////////////////
- // get_keyword_char_type
- //
- // Collapses the character type comming from the subject kwd parsers and
- // and checks that they are all identical (necessary in order to be able
- // to build a tst parser to parse the keywords.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence>
- struct get_keyword_char_type
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::fold<
- Sequence, mpl::vector<>,
- mpl::if_<
- mpl::contains<mpl::_1, mpl::_2>,
- mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
- >
- >::type
- no_duplicate_char_types;
-
- // If the compiler traps here this means you mixed
- // character type for the keywords specified in the
- // kwd directive sequence.
- BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
-
- typedef typename mpl::front<no_duplicate_char_types>::type type;
-
- };
-
- /// Get the character type for the tst parser
- typedef typename build_char_type_sequence< Elements >::type char_types;
- typedef typename get_keyword_char_type< char_types >::type char_type;
-
- /// Our symbols container
- typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
-
- // Filter functor used for case insensitive parsing
- template <typename CharEncoding>
- struct no_case_filter
- {
- char_type operator()(char_type ch) const
- {
- return static_cast<char_type>(CharEncoding::tolower(ch));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // build_case_type_sequence
- //
- // Build a fusion sequence from the kwd/ikwd directives
- // in order to determine if case sensitive and case insensitive
- // keywords have been mixed.
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence >
- struct build_case_type_sequence
- {
- struct element_case_type
- {
- template <typename T>
- struct result;
-
- template <typename F, typename Element>
- struct result<F(Element)>
- {
- typedef typename Element::no_case_keyword type;
-
- };
- template <typename F, typename Element,typename Action>
- struct result<F(spirit::qi::action<Element,Action>) >
- {
- typedef typename Element::no_case_keyword type;
- };
- template <typename F, typename Element>
- struct result<F(spirit::qi::hold_directive<Element>)>
- {
- typedef typename Element::no_case_keyword type;
- };
-
- // never called, but needed for decltype-based result_of (C++0x)
- template <typename Element>
- typename result<element_case_type(Element)>::type
- operator()(Element&) const;
- };
+ //typedef typename fusion::filter_view< Elements, is_complex_kwd_parser< mpl::_ > > complex_keywords_view;
 
- // Compute the list of character types of the child kwd directives
- typedef typename
- fusion::result_of::transform<Sequence, element_case_type>::type
- type;
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // get_nb_case_types
- //
- // Counts the number of entries in the case type sequence matching the
- // CaseType parameter (mpl::true_ -> case insensitve
- // , mpl::false_ -> case sensitive
- ///////////////////////////////////////////////////////////////////////////
- template <typename Sequence,typename CaseType>
- struct get_nb_case_types
- {
- // Make sure each of the types occur only once in the type list
- typedef typename
- mpl::count_if<
- Sequence, mpl::equal_to<mpl::_,CaseType>
- >::type type;
-
-
- };
- // Build the case type sequence
- typedef typename build_case_type_sequence<Elements>::type case_type_sequence;
- // Count the number of case sensitive entries and case insensitve entries
- typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
- typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
- // Get the size of the original sequence
- typedef typename mpl::size<Elements>::type nb_elements;
- // Determine if all the kwd directive are case sensitive/insensitive
- typedef typename mpl::equal_to< ikwd_count, nb_elements>::type all_ikwd;
- typedef typename mpl::equal_to< kwd_count, nb_elements>::type all_kwd;
-
- typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
-
- // Do we have a no case modifier
- typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
-
- // Should the no_case filter always be used ?
- typedef typename mpl::or_<
- no_case_modifier,
- mpl::and_<
- all_directives_of_same_type
- ,all_ikwd
- >
- >::type
- no_case;
-
- typedef no_case_filter<
- typename spirit::detail::get_encoding_with_case<
- Modifiers
- , char_encoding::standard
- , no_case::value>::type>
- nc_filter;
- // Determine the standard case filter type
         typedef typename mpl::if_<
- no_case
- , nc_filter
- , spirit::qi::tst_pass_through >::type
- filter_type;
-
+ typename mpl::empty<complex_keywords_indexes>::type,
+ detail::empty_keywords_list,
+ detail::complex_keywords< complex_keywords_indexes >
+ >::type complex_keywords_type;
         
         // build a bool array and an integer array which will be used to
         // check that the repetition constraints of the kwd parsers are
@@ -339,91 +190,24 @@
         typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
         typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
         
-
-
- // Functor which adds all the keywords/subject parser indexes
- // collected from the subject kwd directives to the keyword tst parser
- template< typename Sequence >
- struct keyword_entry_adder
+ typedef typename mpl::if_<
+ typename mpl::empty<string_keyword_indexes>::type,
+ detail::empty_keywords_list,
+ detail::string_keywords<
+ Elements,
+ string_keywords,
+ string_keyword_indexes,
+ flags_type,
+ Modifiers>
+ >::type string_keywords_type;
+
+ keywords(Elements const& elements_) :
+ elements(elements_)
+ , string_keywords_inst(elements,flags_init)
+ , complex_keywords_inst(elements,flags_init)
         {
- typedef int result_type;
-
- keyword_entry_adder(shared_ptr<keywords_type> lookup,flags_type &flags) :
- lookup(lookup)
- ,flags(flags)
- {}
-
- typedef typename fusion::result_of::begin< Sequence >::type sequence_begin;
-
- template <typename T>
- int operator()(const int i, const T &parser) const
- {
- // Determine the current position being handled
- typedef typename fusion::result_of::distance< sequence_begin, T >::type position_raw;
- // Transform the position to a parser index tag
- typedef typename mpl::integral_c<int,position_raw::value> position;
-
- return call(i,fusion::deref(parser),position());
                 }
 
- template <typename T, typename Position, typename Action>
- int call( const int i, const spirit::qi::action<T,Action> &parser, const Position position ) const
- {
-
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const T & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.keyword.str),
- traits::get_end<char_type>(parser.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.iter.flag_init();
- return 0;
- }
-
- template <typename T, typename Position>
- int call( const int i, const spirit::qi::hold_directive<T> & parser, const Position position) const
- {
- // Make the keyword/parse index entry in the tst parser
- lookup->add(
- traits::get_begin<char_type>(parser.subject.keyword.str),
- traits::get_end<char_type>(parser.subject.keyword.str),
- position
- );
- // Get the initial state of the flags array and store it in the flags initializer
- flags[Position::value]=parser.subject.iter.flag_init();
- return 0;
- }
-
-
- shared_ptr<keywords_type> lookup;
- flags_type & flags;
- };
-
-
- keywords(Elements const& elements) :
- elements(elements)
- , lookup(new keywords_type())
- {
- // Loop through all the subject parsers to build the keyword parser symbol parser
- keyword_entry_adder<Elements> f1(lookup,flags_init);
- fusion::iter_fold(this->elements,0,f1);
- }
-
         template <typename Iterator, typename Context
           , typename Skipper, typename Attribute>
         bool parse(Iterator& first, Iterator const& last
@@ -434,7 +218,7 @@
             // We need to handle the case where kwd / ikwd directives have been mixed
             // This is where we decide which function should be called.
             return parse_impl(first, last, context, skipper, attr_,
- typename mpl::or_<all_directives_of_same_type, no_case>::type()
+ typename string_keywords_type::requires_one_pass()
                              );
         }
         
@@ -442,7 +226,7 @@
           , typename Skipper, typename Attribute>
         bool parse_impl(Iterator& first, Iterator const& last
           , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::true_ /* no ikwd */) const
+ , Attribute& attr_,mpl::true_ /* one pass */) const
           {
            
             // wrap the attribute in a tuple if it is not a tuple
@@ -458,10 +242,16 @@
                                     , flags_type, counters_type
                                     , typename traits::wrap_if_not_tuple<Attribute>::type
                                     , mpl::false_ > parser_visitor_type;
+
             parser_visitor_type parse_visitor(elements, first, last
                                              , context, skipper, flags
                                              , counters, attr);
             
+ typedef repository::qi::detail::complex_kwd_function< parser_visitor_type > complex_kwd_function_type;
+
+ complex_kwd_function_type
+ complex_function(first,last,context,skipper,parse_visitor);
+
             // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
             // array.
             // The kwd directive sets and increments the counter when a successeful parse occured
@@ -471,35 +261,36 @@
             // The parsing takes place here in two steps:
             // 1) parse a keyword and fetch the parser index associated with that keyword
             // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
+
             while(true)
             {
                 
                 spirit::qi::skip_over(first, last, skipper);
- if (parser_index_type* val_ptr
- = lookup->find(first, last, filter_type()))
+ Iterator save = first;
+ if (string_keywords_inst.parse(first, last,parse_visitor,skipper))
                 {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
                     save = first;
                 }
- else
+ else {
+ // restore the position to the last successful keyword parse
+ first = save;
+ if(!complex_keywords_inst.parse(complex_function))
                 {
+ first = save;
                     // Check that we are leaving the keywords parser in a successfull state
                     BOOST_FOREACH(bool &valid,flags)
                     {
                         if(!valid)
                         {
- first = save;
                             return false;
                         }
                     }
                     return true;
                 }
+ else
+ save = first;
             }
+ }
             return false;
         }
         
@@ -508,7 +299,7 @@
           , typename Skipper, typename Attribute>
         bool parse_impl(Iterator& first, Iterator const& last
           , Context& context, Skipper const& skipper
- , Attribute& attr_,mpl::false_) const
+ , Attribute& attr_,mpl::false_ /* two passes */) const
           {
            
             // wrap the attribute in a tuple if it is not a tuple
@@ -536,6 +327,12 @@
             no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
                                              ,context,skipper,flags,counters,attr);
             
+ typedef repository::qi::detail::complex_kwd_function< parser_visitor_type > complex_kwd_function_type;
+
+ complex_kwd_function_type
+ complex_function(first,last,context,skipper,parse_visitor);
+
+
             // We have a bool array 'flags' with one flag for each parser as well as a 'counter'
             // array.
             // The kwd directive sets and increments the counter when a successeful parse occured
@@ -545,47 +342,37 @@
             // The parsing takes place here in two steps:
             // 1) parse a keyword and fetch the parser index associated with that keyword
             // 2) call the associated parser and store the parsed value in the matching attribute.
- Iterator save = first;
+
             while(true)
             {
                 spirit::qi::skip_over(first, last, skipper);
- // First pass case sensitive
- Iterator saved_first = first;
- if (parser_index_type* val_ptr
- = lookup->find(first, last, spirit::qi::tst_pass_through()))
+ Iterator save = first;
+ // String keywords pass
+ if (string_keywords_inst.parse(first,last,parse_visitor,no_case_parse_visitor,skipper))
                 {
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(parse_visitor,*val_ptr)){
- first = save;
- return false;
- }
                     save = first;
                 }
- // Second pass case insensitive
- else if(parser_index_type* val_ptr
- = lookup->find(saved_first,last,nc_filter()))
+ else {
+ first = save;
+
+ if(!complex_keywords_inst.parse(complex_function))
                 {
- first = saved_first;
- spirit::qi::skip_over(first, last, skipper);
- if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
                             first = save;
- return false;
- }
- save = first;
- }
- else
- {
                     // Check that we are leaving the keywords parser in a successfull state
                     BOOST_FOREACH(bool &valid,flags)
                     {
                         if(!valid)
                         {
- first = save;
                             return false;
                         }
                     }
                     return true;
                 }
+ else
+ {
+ save = first;
+ }
+ }
             }
             return false;
         }
@@ -600,7 +387,8 @@
         }
         flags_type flags_init;
         Elements elements;
- shared_ptr<keywords_type> lookup;
+ string_keywords_type string_keywords_inst;
+ complex_keywords_type complex_keywords_inst;
         
     };
 }}}}
@@ -634,6 +422,14 @@
     template <typename Elements, typename Modifiers>
     struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
       : nary_has_semantic_action<Elements> {};
+
+ template <typename Elements, typename Attribute, typename Context
+ , typename Iterator, typename Modifiers>
+ struct handles_container<repository::qi::keywords<Elements,Modifiers>, Attribute
+ , Context, Iterator>
+ : nary_handles_container<Elements, Attribute, Context, Iterator> {};
+
+
 }}}
 
 #endif

Modified: branches/release/boost/spirit/repository/home/support/kwd.hpp
==============================================================================
--- branches/release/boost/spirit/repository/home/support/kwd.hpp (original)
+++ branches/release/boost/spirit/repository/home/support/kwd.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
@@ -15,7 +15,7 @@
 namespace boost { namespace spirit { namespace repository
 {
     // The distinct extended terminal
- BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(( kwd, kwd_type )( ikwd, ikwd_type ) )
+ BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(( kwd, kwd_type )( ikwd, ikwd_type )(dkwd, dkwd_type)(idkwd, idkwd_type) )
 
 }}}
 

Deleted: branches/release/boost/spirit/symbols.hpp
==============================================================================
--- branches/release/boost/spirit/symbols.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_SYMBOLS
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_SYMBOLS
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_symbols.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_symbols.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_symbols.hpp>
-
-#endif

Deleted: branches/release/boost/spirit/utility.hpp
==============================================================================
--- branches/release/boost/spirit/utility.hpp 2012-04-23 22:05:47 EDT (Mon, 23 Apr 2012)
+++ (empty file)
@@ -1,27 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2008 Joel de Guzman
- Copyright (c) 2001-2008 Hartmut Kaiser
- 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)
-=============================================================================*/
-#ifndef BOOST_SPIRIT_DEPRECATED_INCLUDE_UTILITY
-#define BOOST_SPIRIT_DEPRECATED_INCLUDE_UTILITY
-
-#include <boost/version.hpp>
-
-#if BOOST_VERSION >= 103800
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_utility.hpp")
-#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_utility.hpp"
-#endif
-#endif
-
-#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
-#define BOOST_SPIRIT_USE_OLD_NAMESPACE
-#endif
-#include <boost/spirit/include/classic_utility.hpp>
-
-#endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk