Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67380 - in trunk: boost/spirit/home/karma/char boost/spirit/home/karma/string boost/spirit/home/lex boost/spirit/home/lex/qi boost/spirit/home/qi/char boost/spirit/home/qi/string boost/spirit/home/support boost/spirit/home/support/utree libs/spirit/test libs/spirit/test/karma libs/spirit/test/qi
From: admin_at_[hidden]
Date: 2010-12-21 02:17:49


Author: wash
Date: 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
New Revision: 67380
URL: http://svn.boost.org/trac/boost/changeset/67380

Log:
Retooled the get_c_string customization point in Spirit (reimplemented it as
a static member of a template struct) to fix parameterized use of karma::string
with utree (e.g., string("foo")). Broke the Spirit test-suite into five test-suites
in the test Jamfile for testing individual Spirit modules (this doesn't change
what tests are run if you just invoke 'bjam' in libs/spirit/test, nor does it change
where in the build directory the tests are placed). Added some more utree tests.

Text files modified:
   trunk/boost/spirit/home/karma/char/char.hpp | 3 +
   trunk/boost/spirit/home/karma/string/lit.hpp | 8 +++-
   trunk/boost/spirit/home/lex/argument.hpp | 11 +++++
   trunk/boost/spirit/home/lex/qi/state_switcher.hpp | 7 ++-
   trunk/boost/spirit/home/qi/char/char.hpp | 5 +-
   trunk/boost/spirit/home/qi/string/lit.hpp | 5 +-
   trunk/boost/spirit/home/support/string_traits.hpp | 70 ++++++++++++++++++++++++++++++++++++----
   trunk/boost/spirit/home/support/utree/utree.hpp | 1
   trunk/boost/spirit/home/support/utree/utree_traits.hpp | 64 +++++++++++++++++++++++++++++++++++-
   trunk/libs/spirit/test/Jamfile | 21 +++++++++++
   trunk/libs/spirit/test/karma/utree.cpp | 27 +++++++++++++++
   trunk/libs/spirit/test/qi/utree.cpp | 14 ++++++++
   12 files changed, 215 insertions(+), 21 deletions(-)

Modified: trunk/boost/spirit/home/karma/char/char.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/char/char.hpp (original)
+++ trunk/boost/spirit/home/karma/char/char.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -1,4 +1,5 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
+// Copyright (c) 2010 Bryce Lelbach
 //
 // 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)
@@ -261,7 +262,7 @@
             typedef spirit::char_class::convert<char_encoding> convert_type;
 
             char_type const* definition =
- (char_type const*)traits::get_c_string(str);
+ (char_type const*)traits::get_c_string<String>::call(str);
             char_type ch = convert_type::to(Tag(), *definition++);
             while (ch)
             {

Modified: trunk/boost/spirit/home/karma/string/lit.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/string/lit.hpp (original)
+++ trunk/boost/spirit/home/karma/string/lit.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -1,4 +1,5 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
+// Copyright (c) 2010 Bryce Lelbach
 //
 // 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)
@@ -160,10 +161,13 @@
             // fail if attribute isn't matched by immediate literal
             typedef typename attribute<Context>::type attribute_type;
 
+ typedef typename spirit::result_of::extract_from<attribute_type, Attribute>::type
+ extracted_string_type;
+
             using spirit::traits::get_c_string;
             if (!detail::string_compare(
- get_c_string(traits::extract_from<attribute_type>(attr, context))
- , get_c_string(str_), char_encoding(), Tag()))
+ get_c_string<extracted_string_type>::call(traits::extract_from<attribute_type>(attr, context))
+ , get_c_string<string_type>::call(str_), char_encoding(), Tag()))
             {
                 return false;
             }

Modified: trunk/boost/spirit/home/lex/argument.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/argument.hpp (original)
+++ trunk/boost/spirit/home/lex/argument.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -1,5 +1,6 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
 // Copyright (c) 2001-2010 Joel de Guzman
+// Copyright (c) 2010 Bryce Lelbach
 //
 // 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)
@@ -91,8 +92,16 @@
         template <typename Env>
         void eval(Env const& env) const
         {
+ typedef typename
+ remove_const<
+ typename mpl::at_c<typename Env::args_type, 4>::type
+ >::type
+ context_type;
+
+ typedef typename context_type::state_name_type string;
+
             fusion::at_c<4>(env.args()).set_state_name(
- traits::get_c_string(actor_.eval(env)));
+ traits::get_c_string<string>::call(actor_.eval(env)));
         }
 
         state_setter(Actor const& actor)

Modified: trunk/boost/spirit/home/lex/qi/state_switcher.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/qi/state_switcher.hpp (original)
+++ trunk/boost/spirit/home/lex/qi/state_switcher.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -1,4 +1,5 @@
 // Copyright (c) 2001-2010 Hartmut Kaiser
+// Copyright (c) 2010 Bryce Lelbach
 //
 // 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)
@@ -135,7 +136,7 @@
             template <typename State>
             reset_state_on_exit(Iterator& it_, State state_)
               : it(it_)
- , state(detail::set_lexer_state(it_, traits::get_c_string(state_)))
+ , state(detail::set_lexer_state(it_, traits::get_c_string<State>::call(state_)))
             {}
 
             ~reset_state_on_exit()
@@ -183,7 +184,7 @@
         template <typename String>
         state_switcher_context(
                 state_switcher_context<Subject, String> const& rhs)
- : subject(rhs.subject), state(traits::get_c_string(rhs.state)) {}
+ : subject(rhs.subject), state(traits::get_c_string<String>::call(rhs.state)) {}
 
         template <typename Iterator, typename Context
           , typename Skipper, typename Attribute>
@@ -225,7 +226,7 @@
         template <typename Terminal>
         result_type operator()(Terminal const& term, unused_type) const
         {
- return result_type(traits::get_c_string(fusion::at_c<0>(term.args)));
+ return result_type(traits::get_c_string<const_string>::call(fusion::at_c<0>(term.args)));
         }
     };
 

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 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -1,5 +1,6 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2010 Bryce Lelbach
 
     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)
@@ -276,7 +277,7 @@
             ), cannot_convert_string, (String));
 
             in_type const* definition =
- (in_type const*)traits::get_c_string(str);
+ (in_type const*)traits::get_c_string<String>::call(str);
             in_type ch = *definition++;
             while (ch)
             {
@@ -336,7 +337,7 @@
             ), cannot_convert_string, (String));
 
             char_type const* definition =
- (char_type const*)traits::get_c_string(str);
+ (char_type const*)traits::get_c_string<String>::call(str);
             char_type ch = *definition++;
             while (ch)
             {

Modified: trunk/boost/spirit/home/qi/string/lit.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/string/lit.hpp (original)
+++ trunk/boost/spirit/home/qi/string/lit.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -1,5 +1,6 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2010 Bryce Lelbach
 
     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)
@@ -197,7 +198,7 @@
         {
             typename spirit::detail::get_encoding<Modifiers,
                 spirit::char_encoding::standard>::type encoding;
- return result_type(traits::get_c_string(str), encoding);
+ return result_type(traits::get_c_string<String>::call(str), encoding);
         }
     };
 
@@ -233,7 +234,7 @@
         template <typename String>
         result_type op(String const& str, mpl::true_) const
         {
- return result_type(traits::get_c_string(str), encoding());
+ return result_type(traits::get_c_string<String>::call(str), encoding());
         }
     };
 

Modified: trunk/boost/spirit/home/support/string_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/string_traits.hpp (original)
+++ trunk/boost/spirit/home/support/string_traits.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -1,5 +1,6 @@
 /*=============================================================================
     Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2010 Bryce Lelbach
 
     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)
@@ -122,19 +123,74 @@
     ///////////////////////////////////////////////////////////////////////////
     // Get the C string from a string
     ///////////////////////////////////////////////////////////////////////////
+ template <typename String>
+ struct get_c_string;
+
+ template <typename String>
+ struct get_c_string
+ {
+ typedef typename char_type_of<String>::type char_type;
+
+ template <typename T>
+ static T const* call (T* str)
+ {
+ return (T const*)str;
+ }
+
+ template <typename T>
+ static T const* call (T const* str)
+ {
+ return str;
+ }
+ };
+
+ // Forwarder that strips const
     template <typename T>
- inline T* get_c_string(T* str) { return str; }
+ struct get_c_string<T const>
+ {
+ static typename get_c_string<T>::char_type const* call (T const str)
+ {
+ return get_c_string<T>::call(str);
+ }
+ };
 
+ // Forwarder that strips references
     template <typename T>
- inline T const* get_c_string(T const* str) { return str; }
+ struct get_c_string<T&>
+ {
+ static typename get_c_string<T>::char_type const* call (T& str)
+ {
+ return get_c_string<T>::call(str);
+ }
+ };
 
- template <typename T, typename Traits, typename Allocator>
- inline T const* get_c_string(std::basic_string<T, Traits, Allocator>& str)
- { return str.c_str(); }
+ // Forwarder that strips const references
+ template <typename T>
+ struct get_c_string<T const&>
+ {
+ static typename get_c_string<T>::char_type const* call (T const& str)
+ {
+ return get_c_string<T>::call(str);
+ }
+ };
 
     template <typename T, typename Traits, typename Allocator>
- inline T const* get_c_string(std::basic_string<T, Traits, Allocator> const& str)
- { return str.c_str(); }
+ struct get_c_string<std::basic_string<T, Traits, Allocator> >
+ {
+ typedef T char_type;
+
+ typedef std::basic_string<T, Traits, Allocator> string;
+
+ static T const* call (string& str)
+ {
+ return str.c_str();
+ }
+
+ static T const* call (string const& str)
+ {
+ return str.c_str();
+ }
+ };
 
     ///////////////////////////////////////////////////////////////////////////
     // Get the begin/end iterators from a string

Modified: trunk/boost/spirit/home/support/utree/utree.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -15,6 +15,7 @@
 #include <ostream>
 #include <typeinfo>
 
+#include <boost/throw_exception.hpp>
 #include <boost/assert.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/iterator/iterator_facade.hpp>

Modified: trunk/boost/spirit/home/support/utree/utree_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree_traits.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree_traits.hpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -21,6 +21,7 @@
 #include <boost/variant.hpp>
 #include <boost/range/iterator_range.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/mpl/identity.hpp>
 #include <boost/utility/enable_if.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -37,6 +38,65 @@
 namespace boost { namespace spirit { namespace traits
 {
     ///////////////////////////////////////////////////////////////////////////
+ // this specialization lets Spirit.Karma know that typed basic_strings
+ // are strings
+ template <typename Base, utree_type::info I>
+ struct is_string<spirit::basic_string<Base, I> > : mpl::true_ { };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // these specializations extract the character type of a utree typed string
+ template <typename T, utree_type::info I>
+ struct char_type_of<spirit::basic_string<iterator_range<T>, I> >
+ : char_type_of<T> {};
+
+ template <typename T, typename Traits, typename Allocator,
+ utree_type::info I>
+ struct char_type_of<
+ spirit::basic_string<std::basic_string<T, Traits, Allocator>, I>
+ > : mpl::identity<T> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // these specializations extract a c string from a utree typed string
+ template <typename String>
+ struct get_c_string;
+
+ template <typename T, utree_type::info I>
+ struct get_c_string<spirit::basic_string<iterator_range<T const*>, I> >
+ {
+ typedef T char_type;
+
+ typedef spirit::basic_string<iterator_range<T const*>, I> string;
+
+ static T const* call (string& s)
+ {
+ return s.begin();
+ }
+
+ static T const* call (string const& s)
+ {
+ return s.begin();
+ }
+ };
+
+ template <typename T, typename Traits, typename Allocator, utree_type::info I>
+ struct get_c_string<spirit::basic_string<std::basic_string<T, Traits, Allocator>, I> >
+ {
+ typedef T char_type;
+
+ typedef spirit::basic_string<std::basic_string<T, Traits, Allocator>, I> string;
+
+ static T const* call (string& s)
+ {
+ return s.c_str();
+ }
+
+ static T const* call (string const& s)
+ {
+ return s.c_str();
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // this specialization tells Spirit.Qi to allow assignment to an utree from
     // a variant
     namespace detail
@@ -531,7 +591,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- utf8_symbol_range_type r = boost::get<utf8_string_range_type>(t);
+ utf8_string_range_type r = boost::get<utf8_string_range_type>(t);
             return std::basic_string<char, Traits, Alloc>(r.begin(), r.end());
         }
     };
@@ -630,7 +690,7 @@
 
         static type pre(utree const& t)
         {
- utf8_symbol_range_type r = boost::get<utf8_string_range_type>(t);
+ utf8_string_range_type r = boost::get<utf8_string_range_type>(t);
             return std::basic_string<char, Traits, Alloc>(r.begin(), r.end());
         }
     };

Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile (original)
+++ trunk/libs/spirit/test/Jamfile 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -23,7 +23,7 @@
 import testing ;
 
 {
- test-suite spirit_v2 :
+ test-suite spirit_v2/qi :
 
     # run Qi tests
     [ run qi/actions.cpp : : : : ]
@@ -73,6 +73,10 @@
     [ run qi/tst.cpp : : : : ]
     [ run qi/uint.cpp : : : : ]
     [ run qi/utree.cpp : : : : ]
+
+ ;
+
+ test-suite spirit_v2/karma :
 
     # run Karma tests
     [ run karma/actions.cpp : : : : karma_actions ]
@@ -125,6 +129,10 @@
     [ compile-fail karma/grammar_fail.cpp : : karma_grammar_fail ]
     [ compile-fail karma/rule_fail.cpp : : karma_rule_fail ]
 
+ ;
+
+ test-suite spirit_v2/lex :
+
     # run Lex tests
     [ run lex/lexertl1.cpp : : : : ]
     [ run lex/lexertl2.cpp : : : : ]
@@ -139,6 +147,10 @@
     [ run lex/semantic_actions.cpp : : : : ]
     [ run lex/auto_switch_lexerstate.cpp : : : : ]
     [ run lex/id_type_enum.cpp : : : : ]
+
+ ;
+
+ test-suite spirit_v2/lex_regressions :
 
     # run Lex regression tests
     [ run lex/regression001.cpp : : : : lex_regression001 ]
@@ -154,6 +166,10 @@
     [ run lex/regression008.cpp : : : : lex_regression008 ]
     [ run lex/regression009.cpp : : : : lex_regression009 ]
     [ run lex/regression010.cpp : : : : lex_regression010 ]
+
+ ;
+
+ test-suite spirit_v2/support :
 
     # support tests
     [ compile support/multi_pass_regression001.cpp : : support_multi_pass_regression001 ]
@@ -161,6 +177,9 @@
     [ compile support/multi_pass_regression003.cpp : : support_multi_pass_regression003 ]
     [ run support/utree_test.cpp : : : : support_utree_test ]
 
+ ;
+
+ test-suite spirit_v2/regressions :
 
     # regression tests
     [ compile qi/attr_with_action.cpp : : qi_attr_with_action ]

Modified: trunk/libs/spirit/test/karma/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/utree.cpp (original)
+++ trunk/libs/spirit/test/karma/utree.cpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -23,6 +23,8 @@
     using boost::spirit::utree;
     using boost::spirit::utree_type;
     using boost::spirit::utf8_string_range_type;
+ using boost::spirit::utf8_string_type;
+ using boost::spirit::utf8_symbol_type;
 
     using boost::spirit::karma::char_;
     using boost::spirit::karma::bool_;
@@ -50,6 +52,9 @@
 
         ut = "abc";
         BOOST_TEST(test("abc", string, ut));
+
+ ut = utf8_symbol_type("xyz");
+ BOOST_TEST(test("xyz", string, ut));
     }
 
     // sequences
@@ -177,6 +182,28 @@
         BOOST_TEST(test("ab1.2", as_string[*~digit] << double_, ut));
         BOOST_TEST(test("a,b1.2", as_string[~digit % ','] << double_, ut));
     }
+
+ // typed basic_string rules
+ {
+ utree ut("buzz");
+
+ rule<output_iterator, utf8_string_type()> r1 = string;
+ rule<output_iterator, utf8_symbol_type()> r2 = string;
+
+ BOOST_TEST(test("buzz", r1, ut));
+
+ ut = utf8_symbol_type("bar");
+ BOOST_TEST(test("bar", r2, ut));
+ }
+
+ // parameterized karma::string
+ {
+ utree ut("foo");
+
+ rule<output_iterator, utf8_string_type()> r1 = string("foo");
+ BOOST_TEST(test("foo", string("foo"), ut));
+ BOOST_TEST(test("foo", r1, ut));
+ }
 
     {
         using boost::spirit::karma::verbatim;

Modified: trunk/libs/spirit/test/qi/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/utree.cpp (original)
+++ trunk/libs/spirit/test/qi/utree.cpp 2010-12-21 02:17:40 EST (Tue, 21 Dec 2010)
@@ -27,6 +27,8 @@
     using boost::spirit::utree;
     using boost::spirit::utree_type;
     using boost::spirit::utf8_string_range_type;
+ using boost::spirit::utf8_symbol_type;
+ using boost::spirit::utf8_string_type;
 
     using boost::spirit::qi::char_;
     using boost::spirit::qi::int_;
@@ -47,6 +49,18 @@
         ut.clear();
         BOOST_TEST(test_attr("123.45", double_, ut) &&
             ut.which() == utree_type::double_type && check(ut, "123.45"));
+ ut.clear();
+
+ rule<char const*, utf8_string_type()> r1 = lexeme[*char_];
+
+ BOOST_TEST(test_attr("foo", r1, ut) &&
+ ut.which() == utree_type::string_type && check(ut, "\"foo\""));
+ ut.clear();
+
+ rule<char const*, utf8_symbol_type()> r2 = lexeme[*char_];
+
+ BOOST_TEST(test_attr("xyz", r2, ut) &&
+ ut.which() == utree_type::symbol_type && check(ut, "xyz"));
     }
 
     // sequences


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