diff options
Diffstat (limited to 'boost/spirit/home/qi/detail/assign_to.hpp')
-rw-r--r-- | boost/spirit/home/qi/detail/assign_to.hpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/boost/spirit/home/qi/detail/assign_to.hpp b/boost/spirit/home/qi/detail/assign_to.hpp index a94010ca91..38142bf1b3 100644 --- a/boost/spirit/home/qi/detail/assign_to.hpp +++ b/boost/spirit/home/qi/detail/assign_to.hpp @@ -28,11 +28,25 @@ namespace boost { namespace spirit { namespace traits // accept spirit's unused_type; all no-ops. Compiler optimization will // easily strip these away. /////////////////////////////////////////////////////////////////////////// + namespace detail + { + template <typename T> + struct is_iter_range : mpl::false_ {}; + + template <typename I> + struct is_iter_range<boost::iterator_range<I> > : mpl::true_ {}; + + template <typename C> + struct is_container_of_ranges + : is_iter_range<typename C::value_type> {}; + } + template <typename Attribute, typename Iterator, typename Enable> struct assign_to_attribute_from_iterators { + // Common case static void - call(Iterator const& first, Iterator const& last, Attribute& attr) + call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::false_) { if (traits::is_empty(attr)) attr = Attribute(first, last); @@ -41,6 +55,21 @@ namespace boost { namespace spirit { namespace traits push_back(attr, *i); } } + + // If Attribute is a container with value_type==iterator_range<T> just push the + // iterator_range into it + static void + call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::true_) + { + typename Attribute::value_type rng(first, last); + push_back(attr, rng); + } + + static void + call(Iterator const& first, Iterator const& last, Attribute& attr) + { + call(first, last, attr, detail::is_container_of_ranges<Attribute>()); + } }; template <typename Attribute, typename Iterator> |