diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/spirit/example/qi/boost_array.cpp | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/spirit/example/qi/boost_array.cpp')
-rw-r--r-- | src/boost/libs/spirit/example/qi/boost_array.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/example/qi/boost_array.cpp b/src/boost/libs/spirit/example/qi/boost_array.cpp new file mode 100644 index 00000000..66485b97 --- /dev/null +++ b/src/boost/libs/spirit/example/qi/boost_array.cpp @@ -0,0 +1,119 @@ +// 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 <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 + 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 <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 is_container<client::detail::adapt_array<boost::array<T, N> > > + : boost::mpl::true_ + {}; + + 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 bool call(client::detail::adapt_array<boost::array<T, N> >& c + , T const& val) + { + return 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_; + + 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; +} |