$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r56680 - in branches/release: boost/spirit boost/spirit/home/karma/numeric boost/spirit/home/qi/numeric boost/spirit/home/support libs/spirit/test libs/spirit/test/karma libs/spirit/test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2009-10-09 13:32:52
Author: hkaiser
Date: 2009-10-09 13:32:51 EDT (Fri, 09 Oct 2009)
New Revision: 56680
URL: http://svn.boost.org/trac/boost/changeset/56680
Log:
Spirit: finalized bool parsers, added true_ and false_ parsers and generators (merging from trunk)
Properties modified: 
   branches/release/boost/spirit/   (props changed)
   branches/release/libs/spirit/test/   (props changed)
Text files modified: 
   branches/release/boost/spirit/home/karma/numeric/bool.hpp       |    46 +++++++++++++++++                       
   branches/release/boost/spirit/home/qi/numeric/bool.hpp          |    99 +++++++++++++++++++++++++++++++++++++-- 
   branches/release/boost/spirit/home/qi/numeric/bool_policies.hpp |    29 +++++++++++                             
   branches/release/boost/spirit/home/support/common_terminals.hpp |     2                                         
   branches/release/libs/spirit/test/karma/bool.cpp                |     4 +                                       
   branches/release/libs/spirit/test/qi/bool.cpp                   |    23 +++++++++                               
   6 files changed, 194 insertions(+), 9 deletions(-)
Modified: branches/release/boost/spirit/home/karma/numeric/bool.hpp
==============================================================================
--- branches/release/boost/spirit/home/karma/numeric/bool.hpp	(original)
+++ branches/release/boost/spirit/home/karma/numeric/bool.hpp	2009-10-09 13:32:51 EDT (Fri, 09 Oct 2009)
@@ -58,6 +58,14 @@
       : mpl::true_ {};
 
     template <>
+    struct use_terminal<karma::domain, tag::true_>    // enables true_
+      : mpl::true_ {};
+
+    template <>
+    struct use_terminal<karma::domain, tag::false_>    // enables false_
+      : mpl::true_ {};
+
+    template <>
     struct use_terminal<karma::domain, bool>          // enables lit(true)
       : mpl::true_ {};
 
@@ -97,6 +105,10 @@
 {
     using spirit::bool_;
     using spirit::bool__type;
+    using spirit::true_;
+    using spirit::true__type;
+    using spirit::false_;
+    using spirit::false__type;
 
     using spirit::lit;    // lit(true) is equivalent to true
 
@@ -182,8 +194,8 @@
         // it fails.
         template <typename OutputIterator, typename Context, typename Delimiter
           , typename Attribute>
-        bool generate(OutputIterator& sink, Context&, Delimiter const& d
-          , Attribute const& attr) const
+        bool generate(OutputIterator& sink, Context&t
+          , Delimiter const& d, Attribute const& attr) const
         {
             if (!traits::has_optional_value(attr) || 
                 bool(n_) != bool(traits::extract_from(attr)))
@@ -244,6 +256,28 @@
                 return result_type(get_stateful_data<tag_type>::call(term));
             }
         };
+
+        template <typename Modifiers, bool b>
+        struct make_bool_literal
+        {
+            static bool const lower = 
+                has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
+            static bool const upper = 
+                has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
+
+            typedef literal_bool_generator<
+                bool
+              , typename spirit::detail::get_encoding<
+                    Modifiers, unused_type, lower || upper>::type
+              , typename detail::get_casetag<Modifiers, lower || upper>::type
+              , bool_policies<>, false
+            > result_type;
+
+            result_type operator()(unused_type, unused_type) const
+            {
+                return result_type(b);
+            }
+        };
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -251,6 +285,14 @@
     struct make_primitive<tag::bool_, Modifiers> 
       : detail::make_bool<Modifiers> {};
 
+    template <typename Modifiers>
+    struct make_primitive<tag::true_, Modifiers> 
+      : detail::make_bool_literal<Modifiers, true> {};
+
+    template <typename Modifiers>
+    struct make_primitive<tag::false_, Modifiers> 
+      : detail::make_bool_literal<Modifiers, false> {};
+
     template <typename T, typename Policies, typename Modifiers>
     struct make_primitive<
             tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
Modified: branches/release/boost/spirit/home/qi/numeric/bool.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/numeric/bool.hpp	(original)
+++ branches/release/boost/spirit/home/qi/numeric/bool.hpp	2009-10-09 13:32:51 EDT (Fri, 09 Oct 2009)
@@ -27,12 +27,24 @@
     template <>
     struct use_terminal<qi::domain, tag::bool_> // enables bool_
       : mpl::true_ {};
+
+    template <>
+    struct use_terminal<qi::domain, tag::true_> // enables true_
+      : mpl::true_ {};
+
+    template <>
+    struct use_terminal<qi::domain, tag::false_> // enables false_
+      : mpl::true_ {};
 }}
 
 namespace boost { namespace spirit { namespace qi
 {
     using spirit::bool_;
     using spirit::bool__type;
+    using spirit::true_;
+    using spirit::true__type;
+    using spirit::false_;
+    using spirit::false__type;
 
     namespace detail
     {
@@ -41,13 +53,14 @@
         {
             template <typename Iterator, typename Attribute>
             static bool parse(Iterator& first, Iterator const& last
-              , Attribute& attr, Policies const& p) 
+              , Attribute& attr, Policies const& p, bool allow_true = true
+              , bool disallow_false = false) 
             {
                 if (first == last)
                     return false;
 
-                return p.parse_true(first, last, attr) ||
-                       p.parse_false(first, last, attr);
+                return (allow_true && p.parse_true(first, last, attr)) ||
+                       (!disallow_false && p.parse_false(first, last, attr));
             }
         };
     }
@@ -85,16 +98,51 @@
         }
     };
 
+    template <
+        typename T = bool
+      , typename Policies = bool_policies<T> >
+    struct bool_parser_literal_impl
+      : primitive_parser<bool_parser_literal_impl<T, Policies> >
+    {
+        template <typename Context, typename Iterator>
+        struct attribute
+        {
+            typedef T type;
+        };
+
+        bool_parser_literal_impl(typename add_const<T>::type n)
+          : n_(n)
+        {}
+
+        template <typename Iterator, typename Context
+          , typename Skipper, typename Attribute>
+        bool parse(Iterator& first, Iterator const& last
+          , Context& /*context*/, Skipper const& skipper
+          , Attribute& attr) const
+        {
+            qi::skip_over(first, last, skipper);
+            return detail::bool_impl<T, Policies>::
+                parse(first, last, attr, Policies(), n_, n_);
+        }
+
+        template <typename Context>
+        info what(Context& /*context*/) const
+        {
+            return info("boolean");
+        }
+
+        T n_;
+    };
+
     ///////////////////////////////////////////////////////////////////////////
-    // uint_parser is the class that the user can instantiate directly
+    // bool_parser is the class that the user can instantiate directly
     ///////////////////////////////////////////////////////////////////////////
     template <
         typename T
       , typename Policies = bool_policies<T> >
     struct bool_parser
       : proto::terminal<bool_parser_impl<T, Policies> >::type
-    {
-    };
+    {};
 
     ///////////////////////////////////////////////////////////////////////////
     // Parser generators: make_xxx function (objects)
@@ -102,13 +150,50 @@
     template <typename Modifiers>
     struct make_primitive<tag::bool_, Modifiers>
     {
-        typedef bool_parser_impl<bool> result_type;
+        typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+
+        typedef typename mpl::if_<
+            no_case
+          , bool_parser_impl<bool, no_case_bool_policies<> > 
+          , bool_parser_impl<> >::type
+        result_type;
+
         result_type operator()(unused_type, unused_type) const
         {
             return result_type();
         }
     };
 
+    namespace detail
+    {
+        template <typename Modifiers, bool b>
+        struct make_literal_bool
+        {
+            typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> > no_case;
+
+            typedef typename mpl::if_<
+                no_case
+              , bool_parser_literal_impl<bool, no_case_bool_policies<> > 
+              , bool_parser_literal_impl<> >::type
+            result_type;
+
+            result_type operator()(unused_type, unused_type) const
+            {
+                return result_type(b);
+            }
+        };
+    }
+
+    template <typename Modifiers>
+    struct make_primitive<tag::false_, Modifiers>
+      : detail::make_literal_bool<Modifiers, false>
+    {};
+
+    template <typename Modifiers>
+    struct make_primitive<tag::true_, Modifiers>
+      : detail::make_literal_bool<Modifiers, true>
+    {};
+
 }}}
 
 #endif
Modified: branches/release/boost/spirit/home/qi/numeric/bool_policies.hpp
==============================================================================
--- branches/release/boost/spirit/home/qi/numeric/bool_policies.hpp	(original)
+++ branches/release/boost/spirit/home/qi/numeric/bool_policies.hpp	2009-10-09 13:32:51 EDT (Fri, 09 Oct 2009)
@@ -47,6 +47,35 @@
         }
     };
 
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T = bool>
+    struct no_case_bool_policies
+    {
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_true(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            if (detail::string_parse("true", "TRUE", first, last, unused))
+            {
+                spirit::traits::assign_to(T(true), attr);    // result is true
+                return true;
+            }
+            return false;
+        }
+
+        template <typename Iterator, typename Attribute>
+        static bool
+        parse_false(Iterator& first, Iterator const& last, Attribute& attr)
+        {
+            if (detail::string_parse("false", "FALSE", first, last, unused))
+            {
+                spirit::traits::assign_to(T(false), attr);   // result is false
+                return true;
+            }
+            return false;
+        }
+    };
+
 }}}
 
 #endif
Modified: branches/release/boost/spirit/home/support/common_terminals.hpp
==============================================================================
--- branches/release/boost/spirit/home/support/common_terminals.hpp	(original)
+++ branches/release/boost/spirit/home/support/common_terminals.hpp	2009-10-09 13:32:51 EDT (Fri, 09 Oct 2009)
@@ -31,6 +31,8 @@
         ( eol )
         ( eoi )
         ( buffer )
+        ( true_ )
+        ( false_ )
     )
 
     // Here we are reusing proto::lit
Modified: branches/release/libs/spirit/test/karma/bool.cpp
==============================================================================
--- branches/release/libs/spirit/test/karma/bool.cpp	(original)
+++ branches/release/libs/spirit/test/karma/bool.cpp	2009-10-09 13:32:51 EDT (Fri, 09 Oct 2009)
@@ -69,6 +69,8 @@
 int main()
 {
     using boost::spirit::karma::bool_;
+    using boost::spirit::karma::false_;
+    using boost::spirit::karma::true_;
     using boost::spirit::karma::lit;
     using boost::spirit::karma::lower;
     using boost::spirit::karma::upper;
@@ -77,6 +79,8 @@
     {
         BOOST_TEST(test("false", bool_, false));
         BOOST_TEST(test("true", bool_, true));
+        BOOST_TEST(test("false", false_, false));
+        BOOST_TEST(test("true", true_, true));
         BOOST_TEST(test("false", bool_(false)));
         BOOST_TEST(test("true", bool_(true)));
         BOOST_TEST(test("false", bool_(false), false));
Modified: branches/release/libs/spirit/test/qi/bool.cpp
==============================================================================
--- branches/release/libs/spirit/test/qi/bool.cpp	(original)
+++ branches/release/libs/spirit/test/qi/bool.cpp	2009-10-09 13:32:51 EDT (Fri, 09 Oct 2009)
@@ -7,7 +7,9 @@
 #include <boost/detail/lightweight_test.hpp>
 
 #include <boost/spirit/include/support_argument.hpp>
+#include <boost/spirit/include/qi_char.hpp>
 #include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_directive.hpp>
 #include <boost/cstdint.hpp>
 #include "test.hpp"
 
@@ -51,6 +53,27 @@
     }
 
     {
+        using boost::spirit::qi::true_;
+        using boost::spirit::qi::false_;
+
+        BOOST_TEST(test("true", true_));
+        BOOST_TEST(!test("true", false_));
+        BOOST_TEST(test("false", false_));
+        BOOST_TEST(!test("false", true_));
+    }
+
+    {
+        using boost::spirit::qi::true_;
+        using boost::spirit::qi::false_;
+        using boost::spirit::qi::no_case;
+
+        BOOST_TEST(test("True", no_case[bool_]));
+        BOOST_TEST(test("False", no_case[bool_]));
+        BOOST_TEST(test("True", no_case[true_]));
+        BOOST_TEST(test("False", no_case[false_]));
+    }
+
+    {
         bool b = false;
         BOOST_TEST(test_attr("true", bool_, b) && b);
         BOOST_TEST(test_attr("false", bool_, b) && !b);