$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: joel_at_[hidden]
Date: 2008-04-17 05:01:52
Author: djowel
Date: 2008-04-17 05:01:51 EDT (Thu, 17 Apr 2008)
New Revision: 44491
URL: http://svn.boost.org/trac/boost/changeset/44491
Log:
char-sets
Added:
   trunk/boost/spirit/home/qi/char/detail/basic_chset.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/spirit/home/qi/char/char.hpp         |    37 +++++++++++                             
   trunk/boost/spirit/home/qi/char/meta_grammar.hpp |   123 ++++++++++++++++++++++++++++++++++++++- 
   2 files changed, 154 insertions(+), 6 deletions(-)
Modified: trunk/boost/spirit/home/qi/char/char.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/char/char.hpp	(original)
+++ trunk/boost/spirit/home/qi/char/char.hpp	2008-04-17 05:01:51 EDT (Thu, 17 Apr 2008)
@@ -51,10 +51,24 @@
             typedef unused_type type;   // literal parsers have no attribute
         };
 
+        template <typename Char_, typename CharParam>
+        static bool test_impl(Char_ ch, CharParam param)
+        {
+            // tests plain chars
+            return ch == param;
+        }
+
+        template <typename Char_, typename CharParam>
+        static bool test_impl(Char_ const* ch, CharParam param)
+        {
+            // tests single char null terminated strings
+            return *ch == param;
+        }
+
         template <typename Component, typename CharParam, typename Context>
         static bool test(Component const& component, CharParam ch, Context&)
         {
-            return fusion::at_c<0>(component.elements) == ch;
+            return test_impl(fusion::at_c<0>(component.elements), ch);
         }
 
         template <typename Component>
@@ -62,12 +76,31 @@
         {
             return std::string("'")
                 + spirit::detail::to_narrow_char(
-                    fusion::at_c<0>(component.elements)) 
+                    fusion::at_c<0>(component.elements))
                 + '\'';
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////
+    // parse a character set
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct char_set : char_parser<char_set<Char>, Char>
+    {
+        template <typename Component, typename CharParam, typename Context>
+        static bool test(Component const& component, CharParam ch, Context&)
+        {
+            return component.ptr->test(ch);
+        }
+
+        template <typename Component>
+        static std::string what(Component const&)
+        {
+            return "char-set";
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
     // parse a lazy character
     ///////////////////////////////////////////////////////////////////////////
     struct lazy_char : char_parser<lazy_char>
Added: trunk/boost/spirit/home/qi/char/detail/basic_chset.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/char/detail/basic_chset.hpp	2008-04-17 05:01:51 EDT (Thu, 17 Apr 2008)
@@ -0,0 +1,244 @@
+/*=============================================================================
+    Copyright (c) 2001-2008 Joel de Guzman
+    Copyright (c) 2001-2003 Daniel Nuffer
+    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_BASIC_CHSET_APRIL_17_2008
+#define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
+
+///////////////////////////////////////////////////////////////////////////////
+#include <bitset>
+#include <boost/spirit/home/qi/char/detail/range_run.hpp>
+
+namespace boost { namespace spirit { namespace qi { namespace detail
+{
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  basic_chset: basic character set implementation using range_run
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct basic_chset
+    {
+        basic_chset() {}
+        basic_chset(basic_chset const& arg_)
+          : rr(arg_.rr) {}
+
+        bool
+        test(Char v) const
+        {
+            return rr.test(v);
+        }
+
+        void
+        set(Char from, Char to)
+        {
+            rr.set(range<Char>(from, to));
+        }
+
+        void
+        set(Char c)
+        {
+            rr.set(range<Char>(c, c));
+        }
+
+        void
+        clear(Char from, Char to)
+        {
+            rr.set(range<Char>(c, c));
+        }
+
+        void
+        clear(Char c)
+        {
+            rr.clear(range<Char>(from, to));
+        }
+
+        void
+        clear()
+        {
+            rr.clear();
+        }
+
+        void
+        inverse()
+        {
+            basic_chset inv;
+            inv.set(
+                (std::numeric_limits<Char>::min)(),
+                (std::numeric_limits<Char>::max)()
+            );
+            inv -= *this;
+            swap(inv);
+        }
+
+        void
+        swap(basic_chset& x)
+        {
+            rr.swap(x.rr);
+        }
+
+
+        basic_chset&
+        operator|=(basic_chset const& x)
+        {
+            typedef typename range_run<Char>::const_iterator const_iterator;
+            for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
+                rr.set(*iter);
+            return *this;
+        }
+
+        basic_chset&
+        operator&=(basic_chset const& x)
+        {
+            basic_chset inv;
+            inv.set(
+                (std::numeric_limits<Char>::min)(),
+                (std::numeric_limits<Char>::max)()
+            );
+            inv -= x;
+            *this -= inv;
+            return *this;
+        }
+
+        basic_chset&
+        operator-=(basic_chset const& x)
+        {
+            typedef typename range_run<Char>::const_iterator const_iterator;
+            for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
+                rr.clear(*iter);
+            return *this;
+        }
+
+        basic_chset&
+        operator^=(basic_chset const& x)
+        {
+            basic_chset bma = x;
+            bma -= *this;
+            *this -= x;
+            *this |= bma;
+            return *this;
+        }
+
+        private: range_run<Char> rr;
+    };
+
+#if (CHAR_BIT == 8)
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  basic_chset: specializations for 8 bit chars using std::bitset
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Char>
+    struct basic_chset_8bit
+    {
+        basic_chset_8bit() {}
+        basic_chset_8bit(basic_chset_8bit const& arg_)
+          : bset(arg_.bset) {}
+
+        bool
+        test(Char v) const
+        {
+            return bset.test((unsigned char)v);
+        }
+
+        void
+        set(Char from, Char to)
+        {
+            for (int i = from; i <= to; ++i)
+                bset.set((unsigned char)i);
+        }
+
+        void
+        set(Char c)
+        {
+            bset.set((unsigned char)c);
+        }
+
+        void
+        clear(Char from, Char to)
+        {
+            for (int i = from; i <= to; ++i)
+                bset.reset((unsigned char)i);
+        }
+
+        void
+        clear(Char c)
+        {
+            bset.reset((unsigned char)c);
+        }
+
+        void
+        clear()
+        {
+            bset.reset();
+        }
+
+        void
+        inverse()
+        {
+            bset.flip();
+        }
+
+        void
+        swap(basic_chset_8bit& x)
+        {
+            std::swap(bset, x.bset);
+        }
+
+        basic_chset_8bit&
+        operator|=(basic_chset_8bit const& x)
+        {
+            bset |= x.bset;
+            return *this;
+        }
+
+        basic_chset_8bit&
+        operator&=(basic_chset_8bit const& x)
+        {
+            bset &= x.bset;
+            return *this;
+        }
+
+        basic_chset_8bit&
+        operator-=(basic_chset_8bit const& x)
+        {
+            bset &= ~x.bset;
+            return *this;
+        }
+
+        basic_chset_8bit&
+        operator^=(basic_chset_8bit const& x)
+        {
+            bset ^= x.bset;
+            return *this;
+        }
+
+        private: std::bitset<256> bset;
+    };
+
+    /////////////////////////////////
+    template <>
+    struct basic_chset<char>
+      : basic_chset_8bit<char> {};
+
+    /////////////////////////////////
+    template <>
+    struct basic_chset<signed char>
+      : basic_chset_8bit<signed char> {};
+
+    /////////////////////////////////
+    template <>
+    struct basic_chset<unsigned char>
+      : basic_chset_8bit<unsigned char> {};
+
+#endif // #if (CHAR_BIT == 8)
+
+}}}}
+
+#endif
+
Modified: trunk/boost/spirit/home/qi/char/meta_grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/char/meta_grammar.hpp	(original)
+++ trunk/boost/spirit/home/qi/char/meta_grammar.hpp	2008-04-17 05:01:51 EDT (Thu, 17 Apr 2008)
@@ -11,8 +11,34 @@
 #include <boost/spirit/home/support/placeholders.hpp>
 #include <boost/spirit/home/support/meta_grammar.hpp>
 #include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/qi/char/detail/basic_chset.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_same.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+    template <typename Char>
+    struct char_set;
+
+    template <typename Char, typename Elements>
+    struct char_set_component;
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+    template <typename Char, typename Elements, typename Modifier>
+    struct make_component<qi::domain, qi::char_set<Char>, Elements, Modifier>
+      : mpl::identity<qi::char_set_component<Char, Elements> >
+    {
+        static qi::char_set_component<Char, Elements>
+        call(Elements const& elements)
+        {
+            return qi::char_set_component<Char, Elements>(
+                fusion::at_c<0>(elements));
+        }
+    };
+}}}
 
 namespace boost { namespace spirit { namespace qi
 {
@@ -126,6 +152,22 @@
     {
     };
 
+
+    // literals: 'x', L'x' and single char strings: "x", L"x"
+    struct single_char_literal_meta_grammar
+      : proto::or_<
+        // plain chars:
+            proto::terminal<char>
+          , proto::terminal<wchar_t>
+        // single char null terminates strings:
+          , proto::terminal<char[2]>
+          , proto::terminal<char(&)[2]>
+          , proto::terminal<wchar_t[2]>
+          , proto::terminal<wchar_t(&)[2]>
+        >
+    {
+    };
+
     // literals: 'x', L'x'
     struct char_literal_meta_grammar
       : proto::or_<
@@ -139,10 +181,73 @@
     {
     };
 
-    // char_, char_('x'), char_(f), char_('x', 'z'),
+    // literal strings: "hello" (defined in qi/string/meta_grammar.hpp)
+    struct basic_string_literal_meta_grammar;
+
+    // std::string(s) (defined in qi/string/meta_grammar.hpp)
+    struct basic_std_string_meta_grammar;
+
+    template <typename T>
+    struct extract_char; // (defined in qi/string/metagrammar.hpp)
+
+    template <typename Tag, typename T>
+    struct extract_chset_director;
+
+    template <typename T>
+    struct extract_chset_director<tag::char_, T>
+    {
+        typedef typename extract_char<T>::type char_type;
+        typedef char_set<char_type> type;
+    };
+
+    template <typename T>
+    struct extract_chset_director<tag::wchar, T>
+    {
+        typedef typename extract_char<T>::type char_type;
+        typedef char_set<char_type> type;
+    };
+
+    template <typename Char, typename Elements>
+    struct char_set_component
+    {
+        typedef qi::domain domain;
+        typedef char_set<Char> director;
+        typedef Elements elements_type;
+
+        char_set_component(Char const* definition)
+          : ptr(new detail::basic_chset<Char>())
+        {
+            Char ch = *definition++;
+            while (ch)
+            {
+                Char next = *definition++;
+                if (next == '-')
+                {
+                    next = *definition++;
+                    if (next == 0)
+                    {
+                        ptr->set(ch);
+                        ptr->set('-');
+                        break;
+                    }
+                    ptr->set(ch, next);
+                }
+                else
+                {
+                    ptr->set(ch);
+                }
+                ch = next;
+            }
+        }
+
+        boost::shared_ptr<detail::basic_chset<Char> > ptr;
+    };
+
+    // char_, char_('x'), char_("x"), char_(f), char_('x', 'z'),
     // char_(L'x'), char_(L'x', L'z'),
-    // wchar, wchar('x'), wchar('x', 'z'),
+    // wchar, wchar('x'), wchar("x"), wchar('x', 'z'),
     // wchar(L'x'), wchar(L'x', L'z')
+    // char_("a-z"), wchar("a-z")
     // [w]lit('x'), [w]lit(L'x')
     struct char_meta_grammar1
       : proto::or_<
@@ -154,13 +259,13 @@
               , qi::domain
               , mpl::identity<extract_any_char_director<mpl::_> >
             >
-            // char_('x'), wchar(L'x') --> literal_char
+            // char_('x'), wchar(L'x'), char_("x"), wchar(L"x")--> literal_char
           , meta_grammar::compose_function1_eval<
                 proto::function<
                     proto::if_<
                         is_char_tag<proto::_arg, qi::domain>()
                     >
-                  , basic_char_literal_meta_grammar
+                  , single_char_literal_meta_grammar
                 >
               , qi::domain
               , mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
@@ -176,6 +281,16 @@
               , qi::domain
               , mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
             >
+            // char_("a-z"), char_(L"a-z"), wchar(L"a-z") --> char_set
+          , meta_grammar::compose_function1_eval<
+                proto::function<
+                    proto::if_<
+                        is_char_tag<proto::_arg, qi::domain>()>
+                  , proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar>
+                >
+              , qi::domain
+              , mpl::identity<extract_chset_director<mpl::_, mpl::_> >
+            >
             // char_(F()) --> lazy_char
           , meta_grammar::function1_rule<
                 qi::domain