diff options
Diffstat (limited to 'boost/spirit/home/karma/detail/pass_container.hpp')
-rw-r--r-- | boost/spirit/home/karma/detail/pass_container.hpp | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/boost/spirit/home/karma/detail/pass_container.hpp b/boost/spirit/home/karma/detail/pass_container.hpp index 07f2dad3c1..41c253d4b0 100644 --- a/boost/spirit/home/karma/detail/pass_container.hpp +++ b/boost/spirit/home/karma/detail/pass_container.hpp @@ -188,7 +188,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail {}; // If both, the containers value type and the exposed attribute type are - // optionals we are allowed to pass through the the container only if the + // optionals we are allowed to pass through the container only if the // embedded types of those optionals are not compatible. template <typename Container, typename ValueType, typename Attribute , typename Sequence> @@ -203,6 +203,25 @@ namespace boost { namespace spirit { namespace karma { namespace detail // We pass through the container attribute if at least one of the embedded // types in the variant requires to pass through the attribute +#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES) + template <typename Container, typename ValueType, typename Sequence + , typename T> + struct pass_through_container<Container, ValueType, boost::variant<T> + , Sequence> + : pass_through_container<Container, ValueType, T, Sequence> + {}; + + template <typename Container, typename ValueType, typename Sequence + , typename T0, typename ...TN> + struct pass_through_container<Container, ValueType + , boost::variant<T0, TN...>, Sequence> + : mpl::bool_<pass_through_container< + Container, ValueType, T0, Sequence + >::type::value || pass_through_container< + Container, ValueType, boost::variant<TN...>, Sequence + >::type::value> + {}; +#else #define BOOST_SPIRIT_PASS_THROUGH_CONTAINER(z, N, _) \ pass_through_container<Container, ValueType, \ BOOST_PP_CAT(T, N), Sequence>::type::value || \ @@ -224,6 +243,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail {}; #undef BOOST_SPIRIT_PASS_THROUGH_CONTAINER +#endif }}}} /////////////////////////////////////////////////////////////////////////////// @@ -242,27 +262,51 @@ namespace boost { namespace spirit { namespace traits namespace boost { namespace spirit { namespace karma { namespace detail { + template <typename Iterator> + struct pass_container_base + { + pass_container_base(Iterator begin, Iterator end) + : iter(begin), end(end) + {} + + mutable Iterator iter; + mutable Iterator end; + }; + + template <typename Iterator> + struct pass_container_base<Iterator&> + { + pass_container_base(Iterator& begin, Iterator& end) + : iter(begin), end(end) + {} + + Iterator& iter; + Iterator& end; + }; + /////////////////////////////////////////////////////////////////////////// // This function handles the case where the attribute (Attr) given // to the sequence is an STL container. This is a wrapper around F. // The function F does the actual generating. template <typename F, typename Attr, typename Iterator, typename Sequence> - struct pass_container + struct pass_container : pass_container_base<Iterator> { + typedef pass_container_base<Iterator> base_type; typedef typename F::context_type context_type; pass_container(F const& f, Iterator begin, Iterator end) - : f(f), iter(begin), end(end) + : base_type(begin, end) + , f(f) {} bool is_at_end() const { - return traits::compare(iter, end); + return traits::compare(this->iter, this->end); } void next() { - traits::next(iter); + traits::next(this->iter); } // this is for the case when the current element expects an attribute @@ -271,10 +315,10 @@ namespace boost { namespace spirit { namespace karma { namespace detail bool dispatch_container(Component const& component, mpl::false_) const { // get the next value to generate from container - if (!is_at_end() && !f(component, traits::deref(iter))) + if (!is_at_end() && !f(component, traits::deref(this->iter))) { // needs to return false as long as everything is ok - traits::next(iter); + traits::next(this->iter); return false; } @@ -288,7 +332,7 @@ namespace boost { namespace spirit { namespace karma { namespace detail template <typename Component> bool dispatch_container(Component const& component, mpl::true_) const { - return f(component, make_iterator_range(iter, end)); + return f(component, make_iterator_range(this->iter, this->end)); } /////////////////////////////////////////////////////////////////////// @@ -338,8 +382,6 @@ namespace boost { namespace spirit { namespace karma { namespace detail } F f; - mutable Iterator iter; - mutable Iterator end; private: // silence MSVC warning C4512: assignment operator could not be generated |