Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56677 - in trunk: boost/spirit/home/karma/numeric boost/spirit/home/qi/numeric boost/spirit/home/support libs/spirit/test/karma libs/spirit/test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2009-10-09 11:55:23


Author: hkaiser
Date: 2009-10-09 11:55:22 EDT (Fri, 09 Oct 2009)
New Revision: 56677
URL: http://svn.boost.org/trac/boost/changeset/56677

Log:
Spirit: finalized bool parsers, added true_ and false_ parsers and generators
Text files modified:
   trunk/boost/spirit/home/karma/numeric/bool.hpp | 46 +++++++++++++++++
   trunk/boost/spirit/home/qi/numeric/bool.hpp | 99 +++++++++++++++++++++++++++++++++++++--
   trunk/boost/spirit/home/qi/numeric/bool_policies.hpp | 29 +++++++++++
   trunk/boost/spirit/home/support/common_terminals.hpp | 2
   trunk/libs/spirit/test/karma/bool.cpp | 4 +
   trunk/libs/spirit/test/qi/bool.cpp | 23 +++++++++
   6 files changed, 194 insertions(+), 9 deletions(-)

Modified: trunk/boost/spirit/home/karma/numeric/bool.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/bool.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/bool.hpp 2009-10-09 11:55:22 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: trunk/boost/spirit/home/qi/numeric/bool.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/bool.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/bool.hpp 2009-10-09 11:55:22 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: trunk/boost/spirit/home/qi/numeric/bool_policies.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/bool_policies.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/bool_policies.hpp 2009-10-09 11:55:22 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: trunk/boost/spirit/home/support/common_terminals.hpp
==============================================================================
--- trunk/boost/spirit/home/support/common_terminals.hpp (original)
+++ trunk/boost/spirit/home/support/common_terminals.hpp 2009-10-09 11:55:22 EDT (Fri, 09 Oct 2009)
@@ -31,6 +31,8 @@
         ( eol )
         ( eoi )
         ( buffer )
+ ( true_ )
+ ( false_ )
     )
 
     // Here we are reusing proto::lit

Modified: trunk/libs/spirit/test/karma/bool.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/bool.cpp (original)
+++ trunk/libs/spirit/test/karma/bool.cpp 2009-10-09 11:55:22 EDT (Fri, 09 Oct 2009)
@@ -70,6 +70,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;
@@ -78,6 +80,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: trunk/libs/spirit/test/qi/bool.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/bool.cpp (original)
+++ trunk/libs/spirit/test/qi/bool.cpp 2009-10-09 11:55:22 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);


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