Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58824 - in trunk: boost/spirit/home/qi/detail boost/spirit/home/support libs/spirit/test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2010-01-08 22:51:22


Author: hkaiser
Date: 2010-01-08 22:51:21 EST (Fri, 08 Jan 2010)
New Revision: 58824
URL: http://svn.boost.org/trac/boost/changeset/58824

Log:
Spirit: fixing attribute handling in sequences
Text files modified:
   trunk/boost/spirit/home/qi/detail/assign_to.hpp | 28 ++++++++++++++++++++++++++--
   trunk/boost/spirit/home/support/attributes_fwd.hpp | 3 +++
   trunk/boost/spirit/home/support/container.hpp | 22 ++++++++++++++++++++++
   trunk/libs/spirit/test/qi/lit.cpp | 2 ++
   trunk/libs/spirit/test/qi/sequence.cpp | 13 ++++++++++---
   5 files changed, 63 insertions(+), 5 deletions(-)

Modified: trunk/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/assign_to.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/assign_to.hpp 2010-01-08 22:51:21 EST (Fri, 08 Jan 2010)
@@ -16,8 +16,10 @@
 #include <boost/spirit/home/qi/detail/construct.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/attributes_fwd.hpp>
+#include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/phoenix/core/actor.hpp>
 #include <boost/ref.hpp>
+#include <boost/range/iterator_range.hpp>
 
 namespace boost { namespace spirit { namespace traits
 {
@@ -32,7 +34,12 @@
         static void
         call(Iterator const& first, Iterator const& last, Attribute& attr)
         {
- attr = Attribute(first, last);
+ if (is_empty(attr))
+ attr = Attribute(first, last);
+ else {
+ for (Iterator i = first; i != last; ++i)
+ push_back(attr, *i);
+ }
         }
     };
 
@@ -44,7 +51,24 @@
         call(Iterator const& first, Iterator const& last
           , reference_wrapper<Attribute> attr)
         {
- attr = Attribute(first, last);
+ if (is_empty(attr))
+ attr = Attribute(first, last);
+ else {
+ for (Iterator i = first; i != last; ++i)
+ push_back(attr, *i);
+ }
+ }
+ };
+
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<
+ iterator_range<Iterator>, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last
+ , iterator_range<Iterator>& attr)
+ {
+ attr = iterator_range<Iterator>(first, last);
         }
     };
 

Modified: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes_fwd.hpp (original)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp 2010-01-08 22:51:21 EST (Fri, 08 Jan 2010)
@@ -70,6 +70,9 @@
     template <typename Container, typename T, typename Enable = void>
     struct push_back_container;
 
+ template <typename Container, typename Enable = void>
+ struct is_empty_container;
+
     ///////////////////////////////////////////////////////////////////////
     // Determine the iterator type of the given container type
     ///////////////////////////////////////////////////////////////////////

Modified: trunk/boost/spirit/home/support/container.hpp
==============================================================================
--- trunk/boost/spirit/home/support/container.hpp (original)
+++ trunk/boost/spirit/home/support/container.hpp 2010-01-08 22:51:21 EST (Fri, 08 Jan 2010)
@@ -327,6 +327,28 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Container, typename Enable/* = void*/>
+ struct is_empty_container
+ {
+ static bool call(Container const& c)
+ {
+ return c.empty();
+ }
+ };
+
+ template <typename Container>
+ bool is_empty(Container const& c)
+ {
+ return is_empty_container<Container>::call(c);
+ }
+
+ template <typename T>
+ bool is_empty(unused_type)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable/* = void*/>
     struct begin_container
     {
         static typename container_iterator<Container>::type call(Container& c)

Modified: trunk/libs/spirit/test/qi/lit.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/lit.cpp (original)
+++ trunk/libs/spirit/test/qi/lit.cpp 2010-01-08 22:51:21 EST (Fri, 08 Jan 2010)
@@ -84,8 +84,10 @@
         std::string s;
         BOOST_TEST((test_attr("kimpo", string("kimpo"), s)));
         BOOST_TEST(s == "kimpo");
+ s.clear();
         BOOST_TEST((test_attr(L"kimpo", string(L"kimpo"), s)));
         BOOST_TEST(s == "kimpo");
+ s.clear();
         BOOST_TEST((test_attr("x", string("x"), s)));
         BOOST_TEST(s == "x");
     }

Modified: trunk/libs/spirit/test/qi/sequence.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/sequence.cpp (original)
+++ trunk/libs/spirit/test/qi/sequence.cpp 2010-01-08 22:51:21 EST (Fri, 08 Jan 2010)
@@ -145,14 +145,21 @@
         BOOST_TEST(v[0] == 'a');
         BOOST_TEST(v[1] == 'b');
         BOOST_TEST(v[2] == 'c');
+ }
+
+ { // alternative forms of attributes. Allow sequences to take in
+ // stl containers.
 
+ std::string s;
+ BOOST_TEST(test_attr("foobar", string("foo") >> string("bar"), s));
+ BOOST_TEST(s == "foobar");
     }
 
- // alternative forms of attributes. Allow sequences to take in
- // stl containers of stl containers.
+// // 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-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