Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r68852 - in trunk: boost/spirit/home/karma/detail boost/spirit/home/qi/detail libs/spirit/test/karma libs/spirit/test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2011-02-13 15:43:53


Author: hkaiser
Date: 2011-02-13 15:43:52 EST (Sun, 13 Feb 2011)
New Revision: 68852
URL: http://svn.boost.org/trac/boost/changeset/68852

Log:
Spirit: fixing a kleene/sequence attribute issue
Text files modified:
   trunk/boost/spirit/home/karma/detail/pass_container.hpp | 8 ++-
   trunk/boost/spirit/home/qi/detail/pass_container.hpp | 14 ++++-
   trunk/libs/spirit/test/karma/sequence1.cpp | 3
   trunk/libs/spirit/test/karma/sequence2.cpp | 1
   trunk/libs/spirit/test/qi/sequence.cpp | 88 +++++++++++++++++++++++++++------------
   5 files changed, 76 insertions(+), 38 deletions(-)

Modified: trunk/boost/spirit/home/karma/detail/pass_container.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/pass_container.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/pass_container.hpp 2011-02-13 15:43:52 EST (Sun, 13 Feb 2011)
@@ -19,11 +19,11 @@
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
 #include <boost/mpl/or.hpp>
 #include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repeat.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
 #include <boost/range/iterator_range.hpp>
-#include <boost/iterator/iterator_facade.hpp>
 
 namespace boost { namespace spirit { namespace karma { namespace detail
 {
@@ -203,7 +203,9 @@
                 Component, context_type>::type lhs_attribute;
 
             typedef mpl::and_<
- has_same_elements<rhs, lhs_attribute>
+ mpl::or_<
+ has_same_elements<rhs, lhs_attribute>
+ , has_same_elements<Attr, lhs_attribute> >
               , traits::handles_container<Component, Attr, context_type>
> predicate;
 

Modified: trunk/boost/spirit/home/qi/detail/pass_container.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/pass_container.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/pass_container.hpp 2011-02-13 15:43:52 EST (Sun, 13 Feb 2011)
@@ -18,6 +18,10 @@
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
 
 namespace boost { namespace spirit { namespace qi { namespace detail
 {
@@ -165,7 +169,7 @@
 
         // This handles the case where the attribute of the component is
         // an STL container *and* its value_type is convertible to the
- // target attribute's (Attr) value_type.
+ // target's attribute (Attr) value_type.
         template <typename Component>
         bool dispatch_main(Component const& component, mpl::true_) const
         {
@@ -183,13 +187,15 @@
             rhs_attribute;
 
             typedef mpl::and_<
- has_same_elements<lhs, rhs_attribute>
+ mpl::or_<
+ has_same_elements<lhs, rhs_attribute>
+ , has_same_elements<Attr, rhs_attribute> >
               , traits::handles_container<Component, Attr, context_type
                                         , iterator_type>
> predicate;
 
-// // ensure the attribute is actually a container type
-// traits::make_container(attr);
+ // ensure the attribute is actually a container type
+ traits::make_container(attr);
 
             return dispatch_main(component, predicate());
         }

Modified: trunk/libs/spirit/test/karma/sequence1.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/sequence1.cpp (original)
+++ trunk/libs/spirit/test/karma/sequence1.cpp 2011-02-13 15:43:52 EST (Sun, 13 Feb 2011)
@@ -132,7 +132,7 @@
         BOOST_TEST(test_delimited("a b c ",
             char_ << 'b' << char_, p, char(' ')));
     }
-
+
     {
         // literal generators do not need an attribute, not even at the end
         fusion::vector<char, char> p('a', 'c');
@@ -141,7 +141,6 @@
             char_ << char_ << 'b', p, char(' ')));
     }
 
-
     return boost::report_errors();
 }
 

Modified: trunk/libs/spirit/test/karma/sequence2.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/sequence2.cpp (original)
+++ trunk/libs/spirit/test/karma/sequence2.cpp 2011-02-13 15:43:52 EST (Sun, 13 Feb 2011)
@@ -55,7 +55,6 @@
     using namespace boost::spirit::ascii;
     namespace fusion = boost::fusion;
 
-
     {
         std::list<int> v;
         v.push_back(1);

Modified: trunk/libs/spirit/test/qi/sequence.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/sequence.cpp (original)
+++ trunk/libs/spirit/test/qi/sequence.cpp 2011-02-13 15:43:52 EST (Sun, 13 Feb 2011)
@@ -221,40 +221,72 @@
         std::string s;
         BOOST_TEST(test_attr("foobar", string("foo") >> string("bar"), s));
         BOOST_TEST(s == "foobar");
+
+ s.clear();
+
+ using boost::spirit::qi::hold;
+
+ rule<char const*, std::string()> word = +char_("abc");
+ BOOST_TEST(test_attr("ab.bc.ca", *hold[word >> string(".")] >> word, s));
+ BOOST_TEST(s == "ab.bc.ca");
+ }
+
+ // alternative forms of attributes. Allow sequences to take in
+ // stl containers of stl containers.
+ {
+ // this use case seem1 to verify wrong behavior, but it is correct,
+ // think about it!
+
+ std::vector<std::string> v;
+ BOOST_TEST(test_attr("abc1,abc2",
+ *~char_(',') >> *(',' >> *~char_(',')), v));
+ BOOST_TEST(v.size() == 8 &&
+ v[0] == "a" && v[1] == "b" && v[2] == "c" && v[3] == "1" &&
+ v[4] == "a" && v[5] == "b" && v[6] == "c" && v[7] == "2");
     }
 
-// // alternative forms of attributes. Allow sequences to take in
-// // stl containers of stl containers.
-// {
-// // this use case still does not compile, needs some additional work
-//
-// std::vector<std::string> v;
-// BOOST_TEST(test_attr("abc1,abc2,abc3",
-// *~char_(',') >> *(',' >> *~char_(',')), v));
-// BOOST_TEST(v.size() == 3);
-// BOOST_TEST(v[0] == "abc1");
-// BOOST_TEST(v[1] == "abc2");
-// BOOST_TEST(v[2] == "abc3");
-// }
-
-// {
-// std::vector<std::string> v;
-// rule<char const*, std::string()> e = *~char_(',');
-// rule<char const*, std::vector<std::string>()> l = e >> *(',' >> e);
-//
-// BOOST_TEST(test_attr("abc1,abc2,abc3", l, v));
-// BOOST_TEST(v.size() == 3);
-// BOOST_TEST(v[0] == "abc1");
-// BOOST_TEST(v[1] == "abc2");
-// BOOST_TEST(v[2] == "abc3");
-// }
+ {
+ std::vector<std::string> v;
+ rule<char const*, std::string()> e = *~char_(',');
+ rule<char const*, std::vector<std::string>()> l = e >> *(',' >> e);
+
+ BOOST_TEST(test_attr("abc1,abc2,abc3", l, v));
+ BOOST_TEST(v.size() == 3);
+ BOOST_TEST(v[0] == "abc1");
+ BOOST_TEST(v[1] == "abc2");
+ BOOST_TEST(v[2] == "abc3");
+ }
+
+ // do the same with a plain string object
+ {
+ std::string s;
+ BOOST_TEST(test_attr("abc1,abc2",
+ *~char_(',') >> *(',' >> *~char_(',')), s));
+ BOOST_TEST(s == "abc1abc2");
+ }
+
+ {
+ std::string s;
+ rule<char const*, std::string()> e = *~char_(',');
+ rule<char const*, std::string()> l = e >> *(',' >> e);
+
+ BOOST_TEST(test_attr("abc1,abc2,abc3", l, s));
+ BOOST_TEST(s == "abc1abc2abc3");
+ }
 
     {
         std::vector<char> v;
         BOOST_TEST(test_attr("ab", char_ >> -char_, v));
- BOOST_TEST(v.size() == 2);
- BOOST_TEST(v[0] == 'a');
- BOOST_TEST(v[1] == 'b');
+ BOOST_TEST(v.size() == 2 && v[0] == 'a' && v[1] == 'b');
+
+// this is still failing
+// v.clear();
+// BOOST_TEST(test_attr("a", char_ >> -char_, v));
+// BOOST_TEST(v.size() == 1 && v[0] == 'a');
+
+ v.clear();
+ BOOST_TEST(test_attr("a", char_, v));
+ BOOST_TEST(v.size() == 1 && v[0] == 'a');
     }
 
     { // test action


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