$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;
+}