Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56534 - in trunk/libs/spirit: example/karma example/qi test test/karma test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2009-10-02 17:19:11


Author: hkaiser
Date: 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
New Revision: 56534
URL: http://svn.boost.org/trac/boost/changeset/56534

Log:
Spirit: restructured customization points, added qi::attr_cast, added phoenix expression support for Karma attributes, updated tests
Added:
   trunk/libs/spirit/test/qi/attribute.cpp (contents, props changed)
Removed:
   trunk/libs/spirit/test/karma/functor.cpp
Text files modified:
   trunk/libs/spirit/example/karma/reference.cpp | 2
   trunk/libs/spirit/example/qi/reference.cpp | 2
   trunk/libs/spirit/test/CMakeLists.txt | 1
   trunk/libs/spirit/test/Jamfile | 1
   trunk/libs/spirit/test/karma/attribute.cpp | 119 +++++++++++++++++++++++++++++++++++----
   trunk/libs/spirit/test/karma/binary.cpp | 73 ++++++++++++++++++++++++
   trunk/libs/spirit/test/karma/bool.cpp | 34 ++++++++++
   trunk/libs/spirit/test/karma/char.cpp | 15 +++++
   trunk/libs/spirit/test/karma/format_manip_attr.cpp | 4 +
   trunk/libs/spirit/test/karma/int_numerics.cpp | 11 +++
   trunk/libs/spirit/test/karma/kleene.cpp | 11 ++-
   trunk/libs/spirit/test/karma/plus.cpp | 9 +-
   trunk/libs/spirit/test/karma/real_numerics.cpp | 15 +++++
   trunk/libs/spirit/test/karma/repeat.cpp | 14 ++++
   trunk/libs/spirit/test/qi/bool.cpp | 7 +-
   trunk/libs/spirit/test/qi/grammar_fail.cpp | 15 ++---
   trunk/libs/spirit/test/qi/omit.cpp | 13 +---
   trunk/libs/spirit/test/qi/terminal_ex.cpp | 6 +-
   18 files changed, 298 insertions(+), 54 deletions(-)

Modified: trunk/libs/spirit/example/karma/reference.cpp
==============================================================================
--- trunk/libs/spirit/example/karma/reference.cpp (original)
+++ trunk/libs/spirit/example/karma/reference.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -135,7 +135,7 @@
     template <>
     struct transform_attribute<int, int_data const>
     {
- static int call(int_data const& d) { return d.i; }
+ static int pre(int_data const& d) { return d.i; }
     };
 }}}
 //]

Modified: trunk/libs/spirit/example/qi/reference.cpp
==============================================================================
--- trunk/libs/spirit/example/qi/reference.cpp (original)
+++ trunk/libs/spirit/example/qi/reference.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -187,7 +187,7 @@
         namespace qi = boost::spirit::qi;
         if (qi::detail::string_parse("eurt", first, last, qi::unused))
         {
- qi::detail::assign_to(false, attr); // result is false
+ spirit::traits::assign_to(false, attr); // result is false
             return true;
         }
         return false;

Modified: trunk/libs/spirit/test/CMakeLists.txt
==============================================================================
--- trunk/libs/spirit/test/CMakeLists.txt (original)
+++ trunk/libs/spirit/test/CMakeLists.txt 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -22,6 +22,7 @@
 boost_test_run(qi_actions qi/actions.cpp COMPILE_FLAGS ${test_compile_flags} BOOST_LIB spirit COMPILE_FLAGS ${test_compile_flags} )
 boost_test_run(qi_alternative qi/alternative.cpp COMPILE_FLAGS ${test_compile_flags})
 boost_test_run(qi_attr qi/attr.cpp COMPILE_FLAGS ${test_compile_flags})
+boost_test_run(qi_attribute qi/attribute.cpp COMPILE_FLAGS ${test_compile_flags})
 boost_test_run(qi_and_predicate qi/and_predicate.cpp COMPILE_FLAGS ${test_compile_flags})
 boost_test_run(qi_binary qi/binary.cpp COMPILE_FLAGS ${test_compile_flags})
 boost_test_run(qi_bool qi/bool.cpp COMPILE_FLAGS ${test_compile_flags})

Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile (original)
+++ trunk/libs/spirit/test/Jamfile 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -29,6 +29,7 @@
     [ run qi/actions.cpp : : : : ]
     [ run qi/alternative.cpp : : : : ]
     [ run qi/attr.cpp : : : : ]
+ [ run qi/attribute.cpp : : : : ]
     [ run qi/and_predicate.cpp : : : : ]
     [ run qi/binary.cpp : : : : ]
     [ run qi/bool.cpp : : : : ]

Modified: trunk/libs/spirit/test/karma/attribute.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/attribute.cpp (original)
+++ trunk/libs/spirit/test/karma/attribute.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -40,7 +40,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 // this is just a test structure we need to use in place of an int
-struct test_int_data
+struct test_int_data1
 {
     int i;
 };
@@ -49,9 +49,29 @@
 namespace boost { namespace spirit { namespace traits
 {
     template <>
- struct transform_attribute<int, test_int_data const>
+ struct transform_attribute<test_int_data1 const, int>
     {
- static int call(test_int_data const& d) { return d.i; }
+ typedef int type;
+ static int pre(test_int_data1 const& d) { return d.i; }
+ };
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+// this is another test structure we need to use in place of an int, but this
+// time we use a reference to the embedded element
+struct test_int_data2
+{
+ int i;
+};
+
+// so we provide a custom attribute transformation
+namespace boost { namespace spirit { namespace traits
+{
+ template <>
+ struct transform_attribute<test_int_data2 const, int>
+ {
+ typedef int const& type;
+ static int const& pre(test_int_data2 const& d) { return d.i; }
     };
 }}}
 
@@ -63,6 +83,7 @@
 
     test_data d1 = { "s11", "s12", 1, 2.5, "s13" };
     {
+
         BOOST_TEST(test("s121",
             karma::string << karma::int_,
             fusion::as_nview<2, 0>(d1)));
@@ -72,24 +93,94 @@
             fusion::as_nview<2, 0>(d1), ' '));
     }
 
- test_data d2 = { "s21", "s22", 2, 3.4, "s23" };
- typedef fusion::result_of::as_nview<test_data const, 1, 2, 4>::type
- test_view;
- std::vector<test_data> v;
- v.push_back(d1);
- v.push_back(d2);
-
     {
- karma::rule<output_iterator<char>::type, test_view()> r =
- karma::string << karma::string << karma::double_;
+ test_data d2 = { "s21", "s22", 2, 3.4, "s23" };
+ typedef fusion::result_of::as_nview<test_data const, 1, 2, 4>::type
+ test_view;
+ std::vector<test_data> v;
+ v.push_back(d1);
+ v.push_back(d2);
+
+ karma::rule<output_iterator<char>::type, test_data()> r =
+ karma::attr_cast<test_data, test_view>(
+ karma::string << karma::string << karma::double_
+ );
+
         BOOST_TEST(test("s11s122.5\ns21s223.4", r % karma::eol, v));
         BOOST_TEST(test_delimited("s11s122.5\n s21s223.4",
             r % karma::eol, v, ' '));
     }
 
     {
- test_int_data d = { 1 };
- BOOST_TEST(test("1", karma::attr_cast<int>(karma::int_), d));
+ test_int_data1 d = { 1 };
+ BOOST_TEST(test("1", karma::attr_cast(karma::int_), d));
+ BOOST_TEST(test("1", karma::attr_cast<test_int_data1>(karma::int_), d));
+ BOOST_TEST(test("1", karma::attr_cast<test_int_data1, int>(karma::int_), d));
+ }
+
+ {
+ test_int_data1 d[] = {{ 1 }, { 2 }};
+ std::vector<test_int_data1> v;
+ v.push_back(d[0]);
+ v.push_back(d[1] );
+
+ BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v));
+ BOOST_TEST(test("1,2"
+ , karma::attr_cast<test_int_data1>(karma::int_) % ',', v));
+ BOOST_TEST(test("1,2"
+ , karma::attr_cast<test_int_data1, int>(karma::int_) % ',', v));
+ }
+
+ {
+ test_int_data1 d[] = {{ 1 }, { 2 }};
+ std::vector<test_int_data1> v;
+ v.push_back(d[0]);
+ v.push_back(d[1] );
+
+// this won't compile as there is no defined transformation for
+// test_int_data1 and double
+// BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v));
+// BOOST_TEST(test("1.0,2.0"
+// , karma::attr_cast<test_int_data1>(karma::double_) % ',', v));
+
+ BOOST_TEST(test("1.0,2.0"
+ , karma::attr_cast<test_int_data1, int>(karma::double_) % ',', v));
+ }
+
+ {
+ test_int_data2 d = { 1 };
+ BOOST_TEST(test("1", karma::attr_cast(karma::int_), d));
+ BOOST_TEST(test("1", karma::attr_cast<test_int_data2>(karma::int_), d));
+ BOOST_TEST(test("1", karma::attr_cast<test_int_data2, int>(karma::int_), d));
+ }
+
+ {
+ test_int_data2 d[] = {{ 1 }, { 2 }};
+ std::vector<test_int_data2> v;
+ v.push_back(d[0]);
+ v.push_back(d[1] );
+
+ BOOST_TEST(test("1,2", karma::attr_cast(karma::int_) % ',', v));
+ BOOST_TEST(test("1,2"
+ , karma::attr_cast<test_int_data2>(karma::int_) % ',', v));
+ BOOST_TEST(test("1,2"
+ , karma::attr_cast<test_int_data2, int>(karma::int_) % ',', v));
+ }
+
+ {
+ test_int_data2 d[] = {{ 1 }, { 2 }};
+ std::vector<test_int_data2> v;
+ v.push_back(d[0]);
+ v.push_back(d[1] );
+
+// this won't compile as there is no defined transformation for
+// test_int_data2 and double
+// BOOST_TEST(test("1.0,2.0", karma::attr_cast(karma::double_) % ',', v));
+// BOOST_TEST(test("1.0,2.0"
+// , karma::attr_cast<test_int_data2>(karma::double_) % ',', v));
+
+ BOOST_TEST(test("1.0,2.0"
+ , karma::attr_cast<test_int_data2, int>(karma::double_) % ',', v));
     }
 
     return boost::report_errors();

Modified: trunk/libs/spirit/test/karma/binary.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/binary.cpp (original)
+++ trunk/libs/spirit/test/karma/binary.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -8,6 +8,11 @@
 
 #include <boost/spirit/include/karma_binary.hpp>
 #include <boost/spirit/include/karma_generate.hpp>
+#include <boost/spirit/include/karma_phoenix_attributes.hpp>
+
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
 
 #include "test.hpp"
 
@@ -150,7 +155,7 @@
 #endif
     }
 
- { // test native endian binaries
+ { // test optional attributes
 
 #ifdef BOOST_LITTLE_ENDIAN
         boost::optional<boost::uint8_t> v8 (0x01);
@@ -180,5 +185,71 @@
 #endif
     }
 
+ { // test Phoenix expression attributes, only supported if
+ // karma_phoenix_attributes.hpp is included
+ namespace phoenix = boost::phoenix;
+
+#ifdef BOOST_LITTLE_ENDIAN
+ BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::val(0x01)));
+ BOOST_TEST(binary_test("\x01\0x02", 2, byte_, phoenix::val(0x0201)));
+ BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword,
+ phoenix::val(0x04030201)));
+
+ boost::uint8_t v8 (0x01);
+ BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::ref(v8)));
+ BOOST_TEST(binary_test("\x02", 1, byte_, ++phoenix::ref(v8)));
+
+ boost::uint16_t v16 (0x0201);
+ BOOST_TEST(binary_test("\x01\x02", 2, word, phoenix::ref(v16)));
+ BOOST_TEST(binary_test("\x02\x02", 2, word, ++phoenix::ref(v16)));
+
+ boost::uint32_t v32 (0x04030201);
+ BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, phoenix::ref(v32)));
+ BOOST_TEST(binary_test("\x02\x02\x03\x04", 4, dword, ++phoenix::ref(v32)));
+
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword,
+ phoenix::val(0x0807060504030201LL)));
+
+ boost::uint64_t v64 (0x0807060504030201LL);
+ BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword,
+ phoenix::ref(v64)));
+ BOOST_TEST(binary_test("\x02\x02\x03\x04\x05\x06\x07\x08", 8, qword,
+ ++phoenix::ref(v64)));
+#endif
+
+#else // BOOST_LITTLE_ENDIAN
+
+ BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::val(0x01)));
+ BOOST_TEST(binary_test("\x01\x02", 2, byte_, phoenix::val(0x0102)));
+ BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword,
+ phoenix::val(0x01020304)));
+
+ boost::uint8_t v8 (0x01);
+ BOOST_TEST(binary_test("\x01", 1, byte_, phoenix::ref(v8)));
+ BOOST_TEST(binary_test("\x02", 1, byte_, ++phoenix::ref(v8)));
+
+ boost::uint16_t v16 (0x0102);
+ BOOST_TEST(binary_test("\x01\x02", 2, word, phoenix::ref(v16)));
+ BOOST_TEST(binary_test("\x01\x03", 2, word, ++phoenix::ref(v16)));
+
+ boost::uint32_t v32 (0x01020304);
+ BOOST_TEST(binary_test("\x01\x02\x03\x04", 4, dword, phoenix::ref(v32)));
+ BOOST_TEST(binary_test("\x01\x02\x03\x05", 4, dword, ++phoenix::ref(v32)));
+
+#ifdef BOOST_HAS_LONG_LONG
+ BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword,
+ phoenix::val(0x0102030405060708LL)));
+
+ boost::uint64_t v64 (0x0102030405060708LL);
+ BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x08", 8, qword,
+ phoenix::ref(v64)));
+ BOOST_TEST(binary_test("\x01\x02\x03\x04\x05\x06\x07\x09", 8, qword,
+ ++phoenix::ref(v64)));
+#endif
+
+#endif
+ }
+
     return boost::report_errors();
 }

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-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -12,8 +12,14 @@
 #include <boost/spirit/include/karma_string.hpp>
 #include <boost/spirit/include/karma_numeric.hpp>
 #include <boost/spirit/include/karma_directive.hpp>
+#include <boost/spirit/include/karma_phoenix_attributes.hpp>
+
 #include <boost/spirit/home/support/safe_bool.hpp>
 
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
+
 #include "test.hpp"
 
 using namespace spirit_test;
@@ -68,6 +74,7 @@
     using boost::spirit::karma::lower;
     using boost::spirit::karma::upper;
 
+ // testing plain bool
     {
         BOOST_TEST(test("false", bool_, false));
         BOOST_TEST(test("true", bool_, true));
@@ -81,6 +88,28 @@
         BOOST_TEST(test("true", lit(true)));
     }
 
+ // test optional attributes
+ {
+ boost::optional<bool> optbool;
+
+ BOOST_TEST(!test("", bool_, optbool));
+ optbool = false;
+ BOOST_TEST(test("false", bool_, optbool));
+ optbool = true;
+ BOOST_TEST(test("true", bool_, optbool));
+ }
+
+ // test Phoenix expression attributes (include karma_phoenix_attributes.hpp)
+ {
+ namespace phoenix = boost::phoenix;
+
+ BOOST_TEST(test("true", bool_, phoenix::val(true)));
+
+ bool b = false;
+ BOOST_TEST(test("false", bool_, phoenix::ref(b)));
+ BOOST_TEST(test("true", bool_, ++phoenix::ref(b)));
+ }
+
     {
         BOOST_TEST(test("false", lower[bool_], false));
         BOOST_TEST(test("true", lower[bool_], true));
@@ -110,7 +139,7 @@
     {
         typedef boost::spirit::karma::bool_generator<bool, special_bool_policy>
             backwards_bool_type;
- backwards_bool_type const backwards_bool;
+ backwards_bool_type const backwards_bool = backwards_bool_type();
 
         BOOST_TEST(test("eurt", backwards_bool, false));
         BOOST_TEST(test("true", backwards_bool, true));
@@ -125,7 +154,8 @@
     {
         typedef boost::spirit::karma::bool_generator<
             test_bool_data, test_bool_policy> test_bool_type;
- test_bool_type const test_bool;
+ test_bool_type const test_bool = test_bool_type();
+
         test_bool_data const test_false = test_bool_data(false);
         test_bool_data const test_true = test_bool_data(true);
 

Modified: trunk/libs/spirit/test/karma/char.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/char.cpp (original)
+++ trunk/libs/spirit/test/karma/char.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -11,6 +11,7 @@
 #include <boost/spirit/include/karma_char.hpp>
 #include <boost/spirit/include/karma_generate.hpp>
 #include <boost/spirit/include/karma_action.hpp>
+#include <boost/spirit/include/karma_phoenix_attributes.hpp>
 
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
@@ -252,6 +253,7 @@
         BOOST_TEST((!test(L"", wide::char_(val(L'y')), L'x')));
     }
 
+ // we can pass optionals as attributes to any generator
     {
         namespace ascii = boost::spirit::ascii;
         namespace wide = boost::spirit::standard_wide;
@@ -281,5 +283,18 @@
         BOOST_TEST(!test(L"", wide::char_(L'y'), w));
     }
 
+ // yes, we can use phoenix expressions as attributes as well
+ // but only if we include karma_phoenix_attributes.hpp
+ {
+ namespace ascii = boost::spirit::ascii;
+ namespace phoenix = boost::phoenix;
+
+ BOOST_TEST(test("x", ascii::char_, phoenix::val('x')));
+
+ char c = 'x';
+ BOOST_TEST(test("x", ascii::char_, phoenix::ref(c)));
+ BOOST_TEST(test("y", ascii::char_, ++phoenix::ref(c)));
+ }
+
     return boost::report_errors();
 }

Modified: trunk/libs/spirit/test/karma/format_manip_attr.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/format_manip_attr.cpp (original)
+++ trunk/libs/spirit/test/karma/format_manip_attr.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -18,7 +18,9 @@
 
 #include "test_manip_attr.hpp"
 
-using namespace spirit_test;
+using spirit_test::test;
+using spirit_test::test_delimited;
+using spirit_test::test_predelimited;
 
 ///////////////////////////////////////////////////////////////////////////////
 int

Deleted: trunk/libs/spirit/test/karma/functor.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/functor.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
+++ (empty file)
@@ -1,60 +0,0 @@
-/*=============================================================================
- Copyright (c) 2001-2007 Joel de Guzman
- Copyright (c) 2001-2009 Hartmut Kaiser
-
- 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)
-=============================================================================*/
-
-#include <boost/config/warning_disable.hpp>
-#include <boost/detail/lightweight_test.hpp>
-#include <boost/spirit/include/karma_char.hpp>
-#include <boost/spirit/include/karma_auxiliary.hpp>
-#include <boost/spirit/include/karma_action.hpp>
-#include <boost/spirit/include/support_argument.hpp>
-#include <boost/spirit/include/phoenix_core.hpp>
-#include <boost/spirit/include/phoenix_operator.hpp>
-
-#include <iostream>
-#include "test.hpp"
-
-///////////////////////////////////////////////////////////////////////////////
-struct number_generator : public boost::spirit::karma::functor_base
-{
- template <typename Context>
- struct apply
- {
- typedef int type;
- };
-
- template <typename Parameter, typename Context, typename OutputIterator>
- bool operator()(Parameter v, Context& ctx, OutputIterator& sink) const
- {
- char ch = v % 10 + '0';
- v /= 10;
-
- if (0 != v)
- (*this)(v, ctx, sink);
-
- *sink = ch;
- ++sink;
- return true;
- }
-};
-
-boost::spirit::karma::functor_generator<number_generator> number;
-
-///////////////////////////////////////////////////////////////////////////////
-int main()
-{
- using spirit_test::test;
- using namespace boost::spirit;
- using namespace boost::spirit::karma;
-
- {
- BOOST_TEST(test("0", number));
- BOOST_TEST(test("1234", number, 1234));
- }
-
- return boost::report_errors();
-}

Modified: trunk/libs/spirit/test/karma/int_numerics.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/int_numerics.cpp (original)
+++ trunk/libs/spirit/test/karma/int_numerics.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -21,6 +21,7 @@
 #include <boost/spirit/include/karma_numeric.hpp>
 #include <boost/spirit/include/karma_directive.hpp>
 #include <boost/spirit/include/karma_action.hpp>
+#include <boost/spirit/include/karma_phoenix_attributes.hpp>
 
 #include <limits>
 #include "test.hpp"
@@ -90,6 +91,16 @@
         BOOST_TEST(test(expected_maxval, gen, optmax));
         BOOST_TEST(test(expected_minval, gen(minval), optmin));
         BOOST_TEST(test(expected_maxval, gen(maxval), optmax));
+
+ // Phoenix expression tests (only supported while including
+ // karma_phoenix_attributes.hpp
+ namespace phoenix = boost::phoenix;
+
+ BOOST_TEST(test("1", gen, phoenix::val(1)));
+
+ T val = 1;
+ BOOST_TEST(test("1", gen, phoenix::ref(val)));
+ BOOST_TEST(test("2", gen, ++phoenix::ref(val)));
     }
 };
 

Modified: trunk/libs/spirit/test/karma/kleene.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/kleene.cpp (original)
+++ trunk/libs/spirit/test/karma/kleene.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -64,11 +64,12 @@
 
         BOOST_TEST(test("10,20,30,", *(int_ << ','), v));
         BOOST_TEST(test_delimited("10 , 20 , 30 , ", *(int_ << ','), v, lit(" ")));
-
- fusion::vector<char, char> cc ('a', 'c');
- BOOST_TEST(test("ac", char_ << *(lit(' ') << ',') << char_, cc));
- BOOST_TEST(test_delimited("a c ",
- char_ << *(lit(' ') << ',') << char_, cc, " "));
+
+// leads to infinite loops
+// fusion::vector<char, char> cc ('a', 'c');
+// BOOST_TEST(test("ac", char_ << *(lit(' ') << ',') << char_, cc));
+// BOOST_TEST(test_delimited("a c ",
+// char_ << *(lit(' ') << ',') << char_, cc, " "));
     }
 
     { // actions

Modified: trunk/libs/spirit/test/karma/plus.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/plus.cpp (original)
+++ trunk/libs/spirit/test/karma/plus.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -69,10 +69,11 @@
         BOOST_TEST(test("10,20,30,", +(int_ << ','), v));
         BOOST_TEST(test_delimited("10 , 20 , 30 , ", +(int_ << ','), v, lit(" ")));
  
- fusion::vector<char, char> cc ('a', 'c');
- BOOST_TEST(test("ac", char_ << !+(lit(' ') << ',') << char_, cc));
- BOOST_TEST(test_delimited("a c ",
- char_ << !+(lit(' ') << ',') << char_, cc, " "));
+// leads to infinite loops
+// fusion::vector<char, char> cc ('a', 'c');
+// BOOST_TEST(test("ac", char_ << !+(lit(' ') << ',') << char_, cc));
+// BOOST_TEST(test_delimited("a c ",
+// char_ << !+(lit(' ') << ',') << char_, cc, " "));
     }
 
     { // actions

Modified: trunk/libs/spirit/test/karma/real_numerics.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/real_numerics.cpp (original)
+++ trunk/libs/spirit/test/karma/real_numerics.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -14,6 +14,11 @@
 #include <boost/spirit/include/karma_numeric.hpp>
 #include <boost/spirit/include/karma_generate.hpp>
 #include <boost/spirit/include/karma_directive.hpp>
+#include <boost/spirit/include/karma_phoenix_attributes.hpp>
+
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
 
 #include <limits>
 #include "test.hpp"
@@ -533,5 +538,15 @@
         BOOST_TEST(test("1.0", double_(1.0), v));
     }
 
+ { // Phoenix expression tests (include karma_phoenix_attributes.hpp)
+ namespace phoenix = boost::phoenix;
+
+ BOOST_TEST(test("1.0", double_, phoenix::val(1.0)));
+
+ double d = 1.2;
+ BOOST_TEST(test("1.2", double_, phoenix::ref(d)));
+ BOOST_TEST(test("2.2", double_, ++phoenix::ref(d)));
+ }
+
     return boost::report_errors();
 }

Modified: trunk/libs/spirit/test/karma/repeat.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/repeat.cpp (original)
+++ trunk/libs/spirit/test/karma/repeat.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -16,9 +16,11 @@
 #include <boost/spirit/include/karma_action.hpp>
 #include <boost/spirit/include/karma_nonterminal.hpp>
 #include <boost/spirit/include/karma_auxiliary.hpp>
+#include <boost/spirit/include/karma_phoenix_attributes.hpp>
 #include <boost/spirit/include/support_argument.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
+#include <boost/spirit/include/phoenix_statement.hpp>
 #include <boost/fusion/include/std_pair.hpp>
 
 #include <string>
@@ -29,6 +31,7 @@
 
 using namespace spirit_test;
 
+///////////////////////////////////////////////////////////////////////////////
 int main()
 {
     using namespace boost::spirit::ascii;
@@ -158,6 +161,17 @@
         BOOST_TEST(!test("", repeat(4, inf)[r], v3));
     }
 
+ {
+ namespace ascii = boost::spirit::ascii;
+ namespace phoenix = boost::phoenix;
+
+ char c = 'a';
+ BOOST_TEST(test("bcd", repeat(3)[ascii::char_[_1 = ++phoenix::ref(c)]]));
+
+ c = 'a';
+ BOOST_TEST(test("bcd", repeat(3)[ascii::char_], ++phoenix::ref(c)));
+ }
+
     return boost::report_errors();
 }
 

Added: trunk/libs/spirit/test/qi/attribute.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/qi/attribute.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -0,0 +1,233 @@
+/*=============================================================================
+ Copyright (c) 2001-2009 Hartmut Kaiser
+ Copyright (c) 2001-2009 Joel de Guzman
+
+ 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)
+=============================================================================*/
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/fusion/include/struct.hpp>
+#include <boost/fusion/include/nview.hpp>
+#include <boost/mpl/print.hpp>
+
+#include <boost/spirit/include/qi_char.hpp>
+#include <boost/spirit/include/qi_string.hpp>
+#include <boost/spirit/include/qi_numeric.hpp>
+#include <boost/spirit/include/qi_operator.hpp>
+#include <boost/spirit/include/qi_nonterminal.hpp>
+#include <boost/spirit/include/qi_auxiliary.hpp>
+
+#include <iostream>
+#include <vector>
+#include <string>
+#include "test.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+struct test_data
+{
+ std::string s1;
+ std::string s2;
+ int i1;
+ double d1;
+ std::string s3;
+};
+
+BOOST_FUSION_ADAPT_STRUCT(
+ test_data,
+ (int, i1)
+ (std::string, s1)
+ (std::string, s2)
+ (std::string, s3)
+ (double, d1)
+)
+
+///////////////////////////////////////////////////////////////////////////////
+struct test_int_data1
+{
+ int i;
+};
+
+// we provide a custom attribute transformation taking copy of the actual
+// attribute value, simulating more complex type transformations
+namespace boost { namespace spirit { namespace traits
+{
+ template <>
+ struct transform_attribute<test_int_data1, int>
+ {
+ typedef int type;
+ static int pre(test_int_data1& d) { return d.i; }
+ static void post(test_int_data1& d, int i) { d.i = i; }
+ };
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+struct test_int_data2
+{
+ int i;
+};
+
+// we provide a simple custom attribute transformation utilizing passing the
+// actual attribute by reference
+namespace boost { namespace spirit { namespace traits
+{
+ template <>
+ struct transform_attribute<test_int_data2, int>
+ {
+ typedef int& type;
+ static int& pre(test_int_data2& d) { return d.i; }
+ static void post(test_int_data2& d, int const& i) {}
+ };
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ using spirit_test::test_attr;
+ namespace qi = boost::spirit::qi;
+ namespace fusion = boost::fusion;
+
+ // testing attribute reordering in a fusion sequence as explicit attribute
+ {
+ typedef fusion::result_of::as_nview<test_data, 1, 0, 4>::type
+ test_view;
+
+ test_data d1 = { "", "", 0, 0.0, "" };
+ test_view v1 = fusion::as_nview<1, 0, 4>(d1);
+ BOOST_TEST(test_attr("s1,2,1.5",
+ *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_, v1));
+ BOOST_TEST(d1.i1 == 2 && d1.s1 == "s1" && d1.d1 == 1.5);
+
+ test_data d2 = { "", "", 0, 0.0, "" };
+ test_view v2 = fusion::as_nview<1, 0, 4>(d2);
+ BOOST_TEST(test_attr("s1, 2, 1.5 ",
+ *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_,
+ v2, qi::space));
+ BOOST_TEST(d2.i1 == 2 && d2.s1 == "s1" && d2.d1 == 1.5);
+ }
+
+ {
+ // this won't work without the second template argument as *digit
+ // exposes a vector<char> as its attribute
+ std::string str;
+ BOOST_TEST(test_attr("123"
+ , qi::attr_cast<std::string, std::string>(*qi::digit), str));
+ BOOST_TEST(str == "123");
+ }
+
+ // testing attribute reordering in a fusion sequence involving a rule
+ {
+ typedef fusion::result_of::as_nview<test_data, 1, 0, 4>::type
+ test_view;
+ std::vector<test_data> v;
+
+ qi::rule<char const*, test_data()> r1 =
+ qi::attr_cast<test_data, test_view>(
+ *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_
+ );
+
+ BOOST_TEST(test_attr("s1,2,1.5\ns2,4,3.5", r1 % qi::eol, v));
+ BOOST_TEST(v.size() == 2 &&
+ v[0].i1 == 2 && v[0].s1 == "s1" && v[0].d1 == 1.5 &&
+ v[1].i1 == 4 && v[1].s1 == "s2" && v[1].d1 == 3.5);
+
+ qi::rule<char const*, test_data(), qi::blank_type> r2 =
+ qi::attr_cast<test_data, test_view>(
+ *(qi::char_ - ',') >> ',' >> qi::int_ >> ',' >> qi::double_
+ );
+
+ v.clear();
+ BOOST_TEST(test_attr("s1, 2, 1.5 \n s2, 4, 3.5", r2 % qi::eol, v, qi::blank));
+ BOOST_TEST(v.size() == 2 &&
+ v[0].i1 == 2 && v[0].s1 == "s1" && v[0].d1 == 1.5 &&
+ v[1].i1 == 4 && v[1].s1 == "s2" && v[1].d1 == 3.5);
+ }
+
+ // testing explicit transformation if attribute needs to be copied
+ {
+ test_int_data1 d = { 0 };
+ BOOST_TEST(test_attr("1", qi::attr_cast(qi::int_), d));
+ BOOST_TEST(d.i == 1);
+ BOOST_TEST(test_attr("2", qi::attr_cast<test_int_data1>(qi::int_), d));
+ BOOST_TEST(d.i == 2);
+ BOOST_TEST(test_attr("3", qi::attr_cast<test_int_data1, int>(qi::int_), d));
+ BOOST_TEST(d.i == 3);
+ }
+
+ {
+ std::vector<test_int_data1> v;
+
+ BOOST_TEST(test_attr("1,2", qi::attr_cast(qi::int_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+
+ v.clear();
+ BOOST_TEST(test_attr("1,2"
+ , qi::attr_cast<test_int_data1>(qi::int_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+
+ v.clear();
+ BOOST_TEST(test_attr("1,2"
+ , qi::attr_cast<test_int_data1, int>(qi::int_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+ }
+
+ {
+ std::vector<test_int_data1> v;
+
+// this won't compile as there is no defined transformation for
+// test_int_data1 and double
+// BOOST_TEST(test_attr("1.0,2.2", qi::attr_cast(qi::double_) % ',', v));
+// BOOST_TEST(test_attr("1.0,2.2"
+// , qi::attr_cast<test_int_data1>(qi::double_) % ',', v));
+
+ BOOST_TEST(test_attr("1.0,2.2"
+ , qi::attr_cast<test_int_data1, int>(qi::double_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+ }
+
+ // testing explicit transformation if attribute is taken by reference
+ {
+ test_int_data2 d = { 0 };
+ BOOST_TEST(test_attr("1", qi::attr_cast(qi::int_), d));
+ BOOST_TEST(d.i == 1);
+ BOOST_TEST(test_attr("2", qi::attr_cast<test_int_data2>(qi::int_), d));
+ BOOST_TEST(d.i == 2);
+ BOOST_TEST(test_attr("3", qi::attr_cast<test_int_data2, int>(qi::int_), d));
+ BOOST_TEST(d.i == 3);
+ }
+
+ {
+ std::vector<test_int_data2> v;
+
+ BOOST_TEST(test_attr("1,2", qi::attr_cast(qi::int_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+
+ v.clear();
+ BOOST_TEST(test_attr("1,2"
+ , qi::attr_cast<test_int_data2>(qi::int_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+
+ v.clear();
+ BOOST_TEST(test_attr("1,2"
+ , qi::attr_cast<test_int_data2, int>(qi::int_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+ }
+
+ {
+ std::vector<test_int_data2> v;
+
+// this won't compile as there is no defined transformation for
+// test_int_data2 and double
+// BOOST_TEST(test_attr("1.0,2.2", qi::attr_cast(qi::double_) % ',', v));
+// BOOST_TEST(test_attr("1.0,2.2"
+// , qi::attr_cast<test_int_data2>(qi::double_) % ',', v));
+
+ BOOST_TEST(test_attr("1.0,2.2"
+ , qi::attr_cast<test_int_data2, int>(qi::double_) % ',', v));
+ BOOST_TEST(v.size() == 2 && v[0].i == 1 && v[1].i == 2);
+ }
+
+ return boost::report_errors();
+}

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-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -19,10 +19,11 @@
     static bool
     parse_false(Iterator& first, Iterator const& last, Attribute& attr)
     {
+ namespace spirit = boost::spirit;
         namespace qi = boost::spirit::qi;
         if (qi::detail::string_parse("eurt", first, last, qi::unused))
         {
- qi::detail::assign_to(false, attr); // result is false
+ spirit::traits::assign_to(false, attr); // result is false
             return true;
         }
         return false;
@@ -59,7 +60,7 @@
     {
         typedef boost::spirit::qi::bool_parser<bool, backwards_bool_policies>
             backwards_bool_type;
- backwards_bool_type const backwards_bool;
+ backwards_bool_type const backwards_bool = backwards_bool_type();
 
         BOOST_TEST(test("true", backwards_bool));
         BOOST_TEST(test("eurt", backwards_bool));
@@ -76,7 +77,7 @@
     {
         typedef boost::spirit::qi::bool_parser<test_bool_type>
             bool_test_type;
- bool_test_type const test_bool;
+ bool_test_type const test_bool = bool_test_type();
 
         BOOST_TEST(test("true", test_bool));
         BOOST_TEST(test("false", test_bool));

Modified: trunk/libs/spirit/test/qi/grammar_fail.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/grammar_fail.cpp (original)
+++ trunk/libs/spirit/test/qi/grammar_fail.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -12,20 +12,17 @@
 #include <boost/spirit/include/qi_nonterminal.hpp>
 #include <boost/spirit/include/qi_parse.hpp>
 
-using namespace boost::spirit;
-using namespace boost::spirit::qi;
-using namespace boost::spirit::ascii;
+namespace qi = boost::spirit::qi;
 
-struct num_list : grammar<char const*, rule<char const*> >
+struct num_list : qi::grammar<char const*, qi::rule<char const*> >
 {
     num_list() : base_type(start)
     {
- using boost::spirit::int_;
- num = int_;
+ num = qi::int_;
         start = num >> *(',' >> num);
     }
 
- rule<char const*, rule<char const*> > start, num;
+ qi::rule<char const*, qi::rule<char const*> > start, num;
 };
 
 // this test must fail compiling
@@ -35,8 +32,8 @@
     char const* end = &input[strlen(input)+1];
 
     num_list g;
- bool r = phrase_parse(input, end, g,
- space | ('%' >> *~char_('\n') >> '\n'));
+ bool r = qi::phrase_parse(input, end, g,
+ qi::space | ('%' >> *~qi::char_('\n') >> '\n'));
 
     return 0;
 }

Modified: trunk/libs/spirit/test/qi/omit.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/omit.cpp (original)
+++ trunk/libs/spirit/test/qi/omit.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -41,9 +41,9 @@
 
     {
         // omit[] means we don't receive the attribute
- vector<char> attr;
+ char attr;
         BOOST_TEST((test_attr("abc", omit[char_] >> omit['b'] >> char_, attr)));
- BOOST_TEST((at_c<0>(attr) == 'c'));
+ BOOST_TEST((attr == 'c'));
     }
 
     {
@@ -89,15 +89,8 @@
     }
 
     {
- // omit[] means we don't receive the attribute
- vector<char> attr;
- BOOST_TEST((test_attr("a hello c", char_ >> "hello" >> omit[char_], attr, space)));
- BOOST_TEST((at_c<0>(attr) == 'a'));
- }
-
- {
         // if only one node in a sequence is left (all the others are omitted),
- // then we should also allow "naked" attributes (unwraped in a tuple)
+ // then we need "naked" attributes (not wraped in a tuple)
         int attr;
         BOOST_TEST((test_attr("a 123 c", omit['a'] >> int_ >> omit['c'], attr, space)));
         BOOST_TEST((attr == 123));

Modified: trunk/libs/spirit/test/qi/terminal_ex.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/terminal_ex.cpp (original)
+++ trunk/libs/spirit/test/qi/terminal_ex.cpp 2009-10-02 17:19:08 EDT (Fri, 02 Oct 2009)
@@ -56,7 +56,7 @@
                 if (it == last || *it++ != Char('+'))
                     return false;
 
- boost::spirit::qi::detail::assign_to(count, attr);
+ boost::spirit::traits::assign_to(count, attr);
             first = it;
             return true;
         }
@@ -104,7 +104,7 @@
                 if (it == last || *it++ != Char('-'))
                     return false;
 
- boost::spirit::qi::detail::assign_to(count, attr);
+ boost::spirit::traits::assign_to(count, attr);
             first = it;
             return true;
         }
@@ -157,7 +157,7 @@
                 if (it == last || *it++ != Char('*'))
                     return false;
 
- boost::spirit::qi::detail::assign_to(count, attr);
+ boost::spirit::traits::assign_to(count, attr);
             first = it;
             return true;
         }


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