Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58270 - trunk/libs/spirit/example/qi
From: hartmut.kaiser_at_[hidden]
Date: 2009-12-10 12:15:39


Author: hkaiser
Date: 2009-12-10 12:15:39 EST (Thu, 10 Dec 2009)
New Revision: 58270
URL: http://svn.boost.org/trac/boost/changeset/58270

Log:
Spirit: added new Qi example
Added:
   trunk/libs/spirit/example/qi/boost_array.cpp (contents, props changed)
Text files modified:
   trunk/libs/spirit/example/qi/Jamfile | 1 +
   1 files changed, 1 insertions(+), 0 deletions(-)

Modified: trunk/libs/spirit/example/qi/Jamfile
==============================================================================
--- trunk/libs/spirit/example/qi/Jamfile (original)
+++ trunk/libs/spirit/example/qi/Jamfile 2009-12-10 12:15:39 EST (Thu, 10 Dec 2009)
@@ -31,6 +31,7 @@
 exe key_value_sequence_empty_value : key_value_sequence_empty_value.cpp ;
 
 exe iter_pos_parser : iter_pos_parser.cpp ;
+exe boost_array : boost_array.cpp ;
 
 exe calculator1 : calc1.cpp ;
 exe calculator2 : calc2.cpp ;

Added: trunk/libs/spirit/example/qi/boost_array.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/qi/boost_array.cpp 2009-12-10 12:15:39 EST (Thu, 10 Dec 2009)
@@ -0,0 +1,113 @@
+// Copyright (c) 2009 Erik Bryan
+// Copyright (c) 2007-2009 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <string>
+#include <vector>
+
+#include <boost/array.hpp>
+
+#include <boost/spirit/include/qi.hpp>
+
+namespace qi = boost::spirit::qi;
+namespace ascii = boost::spirit::ascii;
+
+///////////////////////////////////////////////////////////////////////////////
+// create a wrapper holding the boost::array and a current insertion point
+namespace client
+{
+ namespace detail
+ {
+ template <typename T>
+ struct adapt_array;
+
+ template <typename T, std::size_t N>
+ struct adapt_array<boost::array<T, N> >
+ {
+ typedef boost::array<T, N> array_type;
+
+ adapt_array(array_type& arr)
+ : arr_(arr), current_(0) {}
+
+ // expose a push_back function compatible with std containers
+ void push_back(typename array_type::value_type const& val)
+ {
+ // if the array is full, we need to bail out
+ // there is currently no other way of making the parsing fail
+ if (current_ >= N)
+ boost::throw_exception(std::runtime_error("too bad..."));
+ else
+ arr_[current_++] = val;
+ }
+
+ array_type& arr_;
+ std::size_t current_;
+ };
+ }
+
+ namespace result_of
+ {
+ template <typename T>
+ struct adapt_array;
+
+ template <typename T, std::size_t N>
+ struct adapt_array<boost::array<T, N> >
+ {
+ typedef detail::adapt_array<boost::array<T, N> > type;
+ };
+ }
+
+ template <typename T, std::size_t N>
+ inline detail::adapt_array<boost::array<T, N> >
+ adapt_array(boost::array<T, N>& arr)
+ {
+ return detail::adapt_array<boost::array<T, N> >(arr);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// specialize Spirit's container specific customization points for our adaptor
+namespace boost { namespace spirit { namespace traits
+{
+ template <typename T, std::size_t N>
+ struct container_value<client::detail::adapt_array<boost::array<T, N> > >
+ {
+ typedef T type; // value type of container
+ };
+
+ template <typename T, std::size_t N>
+ struct push_back_container<
+ client::detail::adapt_array<boost::array<T, N> >, T>
+ {
+ static void call(client::detail::adapt_array<boost::array<T, N> >& c
+ , T const& val)
+ {
+ c.push_back(val);
+ }
+ };
+}}}
+
+int main()
+{
+ typedef std::string::const_iterator iterator_type;
+ typedef boost::array<int, 2> array_type;
+ typedef client::result_of::adapt_array<array_type>::type adapted_type;
+
+ array_type arr;
+
+ std::string str = "1 2";
+ iterator_type iter = str.begin();
+ iterator_type end = str.end();
+
+ qi::rule<iterator_type, adapted_type(), ascii::space_type> r = *qi::int_;
+
+ bool result = qi::phrase_parse(iter, end, r, ascii::space
+ , client::adapt_array(arr));
+
+ if (result)
+ std::cout << "Parsed: " << arr[0] << ", " << arr[1] << std::endl;
+
+ return 0;
+}


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