|
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