summaryrefslogtreecommitdiff
path: root/boost/spirit/home/karma/detail/pass_container.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/karma/detail/pass_container.hpp')
-rw-r--r--boost/spirit/home/karma/detail/pass_container.hpp62
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