// Copyright (c) 2009 Erik Bryan // Copyright (c) 2007-2010 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 #include #include #include 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 struct adapt_array; template struct adapt_array > { typedef boost::array array_type; adapt_array(array_type& arr) : arr_(arr), current_(0) {} // expose a push_back function compatible with std containers bool push_back(typename array_type::value_type const& val) { // if the array is full, we need to bail out // returning false will fail the parse if (current_ >= N) return false; arr_[current_++] = val; return true; } array_type& arr_; std::size_t current_; }; } namespace result_of { template struct adapt_array; template struct adapt_array > { typedef detail::adapt_array > type; }; } template inline detail::adapt_array > adapt_array(boost::array& arr) { return detail::adapt_array >(arr); } } /////////////////////////////////////////////////////////////////////////////// // specialize Spirit's container specific customization points for our adaptor namespace boost { namespace spirit { namespace traits { template struct is_container > > : boost::mpl::true_ {}; template struct container_value > > { typedef T type; // value type of container }; template struct push_back_container< client::detail::adapt_array >, T> { static bool call(client::detail::adapt_array >& c , T const& val) { return c.push_back(val); } }; }}} int main() { typedef std::string::const_iterator iterator_type; typedef boost::array array_type; typedef client::result_of::adapt_array::type adapted_type; array_type arr; std::string str = "1 2"; iterator_type iter = str.begin(); iterator_type end = str.end(); qi::rule r = *qi::int_; adapted_type attr = client::adapt_array(arr); bool result = qi::phrase_parse(iter, end, r, ascii::space, attr); if (result) std::cout << "Parsed: " << arr[0] << ", " << arr[1] << std::endl; return 0; }