stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,214 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM)
#define SPIRIT_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/variant.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Variant, typename Expected>
struct find_substitute
{
// Get the typr from the variant that can be a substitute for Expected.
// If none is found, just return Expected
typedef Variant variant_type;
typedef typename variant_type::types types;
typedef typename mpl::end<types>::type end;
typedef typename
mpl::find_if<types, is_same<mpl::_1, Expected> >::type
iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Expected> >,
mpl::identity<iter_1>
>::type
iter;
typedef typename
mpl::eval_if<
is_same<iter, end>,
mpl::identity<Expected>,
mpl::deref<iter>
>::type
type;
};
template <typename Iterator, typename Context, typename Skipper,
typename Attribute>
struct alternative_function
{
alternative_function(
Iterator& first_, Iterator const& last_, Context& context_,
Skipper const& skipper_, Attribute& attr_)
: first(first_), last(last_), context(context_), skipper(skipper_),
attr(attr_)
{
}
template <typename Component>
bool call(Component const& component, mpl::true_) const
{
// if Attribute is not a variant, then pass it as-is
return component.parse(first, last, context, skipper, attr);
}
template <typename Component>
bool call_optional_or_variant(Component const& component, mpl::true_) const
{
// If Attribute is an optional, then create an attribute for the Component
// with the type optional::value_type. If the expected attribute is unused type,
// use it instead.
typedef typename
traits::attribute_of<Component, Context, Iterator>::type
expected_type;
typename mpl::if_<
is_same<expected_type, unused_type>,
unused_type,
typename Attribute::value_type>::type
val;
if (component.parse(first, last, context, skipper, val))
{
traits::assign_to(val, attr);
return true;
}
return false;
}
template <typename Component>
bool call_variant(Component const& component, mpl::false_) const
{
// If Attribute is a variant, then search the variant types for a
// suitable substitute type.
typename
find_substitute<Attribute,
typename traits::attribute_of<Component, Context, Iterator>::type
>::type
val;
if (component.parse(first, last, context, skipper, val))
{
traits::assign_to(val, attr);
return true;
}
return false;
}
template <typename Component>
bool call_variant(Component const& component, mpl::true_) const
{
// If Attribute is a variant and the expected attribute is
// the same type (pass the variant as-is).
return component.parse(first, last, context, skipper, attr);
}
template <typename Component>
bool call_optional_or_variant(Component const& component, mpl::false_) const
{
// Attribute is a variant...
typedef typename
traits::attribute_of<Component, Context, Iterator>::type
expected;
return call_variant(component,
is_same<Attribute, expected>());
}
template <typename Component>
bool call(Component const& component, mpl::false_) const
{
return call_optional_or_variant(
component, spirit::traits::not_is_variant<Attribute, qi::domain>());
}
template <typename Component>
bool call_unused(Component const& component, mpl::true_) const
{
// return true if the parser succeeds
return call(component,
mpl::and_<
spirit::traits::not_is_variant<Attribute, qi::domain>,
spirit::traits::not_is_optional<Attribute, qi::domain>
>());
}
template <typename Component>
bool call_unused(Component const& component, mpl::false_) const
{
return component.parse(first, last, context, skipper, unused);
}
template <typename Component>
bool operator()(Component const& component) const
{
// return true if the parser succeeds
typedef typename traits::not_is_unused<
typename traits::attribute_of<Component, Context, Iterator>::type
>::type predicate;
return call_unused(component, predicate());
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
Attribute& attr;
private:
// silence MSVC warning C4512: assignment operator could not be generated
alternative_function& operator= (alternative_function const&);
};
template <typename Iterator, typename Context, typename Skipper>
struct alternative_function<Iterator, Context, Skipper, unused_type const>
{
alternative_function(
Iterator& first_, Iterator const& last_, Context& context_,
Skipper const& skipper_, unused_type)
: first(first_), last(last_), context(context_), skipper(skipper_)
{
}
template <typename Component>
bool operator()(Component const& component) const
{
// return true if the parser succeeds
return component.parse(first, last, context, skipper,
unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
alternative_function& operator= (alternative_function const&);
};
}}}}
#endif
@@ -0,0 +1,403 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM)
#define BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/construct.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/fusion/include/copy.hpp>
#include <boost/fusion/adapted/struct/detail/extension.hpp>
#include <boost/ref.hpp>
#include <boost/range/iterator_range.hpp>
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This file contains assignment utilities. The utilities provided also
// 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, mpl::false_)
{
if (traits::is_empty(attr))
attr = Attribute(first, last);
else {
for (Iterator i = first; i != last; ++i)
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>
struct assign_to_attribute_from_iterators<
reference_wrapper<Attribute>, Iterator>
{
static void
call(Iterator const& first, Iterator const& last
, reference_wrapper<Attribute> attr)
{
if (traits::is_empty(attr))
attr = Attribute(first, last);
else {
for (Iterator i = first; i != last; ++i)
push_back(attr, *i);
}
}
};
template <typename Attribute, typename Iterator>
struct assign_to_attribute_from_iterators<
boost::optional<Attribute>, Iterator>
{
static void
call(Iterator const& first, Iterator const& last
, boost::optional<Attribute>& attr)
{
Attribute val;
assign_to(first, last, val);
attr = val;
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<
iterator_range<Iterator>, Iterator>
{
static void
call(Iterator const& first, Iterator const& last
, iterator_range<Iterator>& attr)
{
attr = iterator_range<Iterator>(first, last);
}
};
template <typename Iterator, typename Attribute>
inline void
assign_to(Iterator const& first, Iterator const& last, Attribute& attr)
{
assign_to_attribute_from_iterators<Attribute, Iterator>::
call(first, last, attr);
}
template <typename Iterator>
inline void
assign_to(Iterator const&, Iterator const&, unused_type)
{
}
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attribute>
void assign_to(T const& val, Attribute& attr);
template <typename Attribute, typename T, typename Enable>
struct assign_to_attribute_from_value
{
typedef typename traits::one_element_sequence<Attribute>::type
is_one_element_sequence;
typedef typename mpl::eval_if<
is_one_element_sequence
, fusion::result_of::at_c<Attribute, 0>
, mpl::identity<Attribute&>
>::type type;
template <typename T_>
static void
call(T_ const& val, Attribute& attr, mpl::false_)
{
attr = static_cast<Attribute>(val);
}
// This handles the case where the attribute is a single element fusion
// sequence. We silently assign to the only element and treat it as the
// attribute to parse the results into.
template <typename T_>
static void
call(T_ const& val, Attribute& attr, mpl::true_)
{
typedef typename fusion::result_of::value_at_c<Attribute, 0>::type
element_type;
fusion::at_c<0>(attr) = static_cast<element_type>(val);
}
static void
call(T const& val, Attribute& attr)
{
call(val, attr, is_one_element_sequence());
}
};
template <typename Attribute>
struct assign_to_attribute_from_value<Attribute, Attribute>
{
static void
call(Attribute const& val, Attribute& attr)
{
attr = val;
}
};
template <typename Attribute, typename T>
struct assign_to_attribute_from_value<Attribute, reference_wrapper<T>
, typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
{
static void
call(reference_wrapper<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
template <typename Attribute, typename T>
struct assign_to_attribute_from_value<Attribute, boost::optional<T>
, typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
{
static void
call(boost::optional<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
template <typename Attribute, int N, bool Const, typename T>
struct assign_to_attribute_from_value<fusion::extension::adt_attribute_proxy<Attribute, N, Const>, T>
{
static void
call(T const& val, typename fusion::extension::adt_attribute_proxy<Attribute, N, Const>& attr)
{
attr = val;
}
};
namespace detail
{
template <typename A, typename B>
struct is_same_size_sequence
: mpl::bool_<fusion::result_of::size<A>::value
== fusion::result_of::size<B>::value>
{};
}
template <typename Attribute, typename T>
struct assign_to_attribute_from_value<Attribute, T,
mpl::and_<
fusion::traits::is_sequence<Attribute>,
fusion::traits::is_sequence<T>,
detail::is_same_size_sequence<Attribute, T>
>
>
{
static void
call(T const& val, Attribute& attr)
{
fusion::copy(val, attr);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename T, typename Enable>
struct assign_to_container_from_value
{
// T is not a container and not a string
template <typename T_>
static void call(T_ const& val, Attribute& attr, mpl::false_, mpl::false_)
{
traits::push_back(attr, val);
}
// T is a container (but not a string), and T is convertible to the
// value_type of the Attribute container
template <typename T_>
static void
append_to_container_not_string(T_ const& val, Attribute& attr, mpl::true_)
{
traits::push_back(attr, val);
}
// T is a container (but not a string), generic overload
template <typename T_>
static void
append_to_container_not_string(T_ const& val, Attribute& attr, mpl::false_)
{
typedef typename traits::container_iterator<T_ const>::type
iterator_type;
iterator_type end = traits::end(val);
for (iterator_type i = traits::begin(val); i != end; traits::next(i))
traits::push_back(attr, traits::deref(i));
}
// T is a container (but not a string)
template <typename T_>
static void call(T_ const& val, Attribute& attr, mpl::true_, mpl::false_)
{
typedef typename container_value<Attribute>::type value_type;
typedef typename is_convertible<T, value_type>::type is_value_type;
append_to_container_not_string(val, attr, is_value_type());
}
///////////////////////////////////////////////////////////////////////
// T is a string
template <typename Iterator>
static void append_to_string(Attribute& attr, Iterator begin, Iterator end)
{
for (Iterator i = begin; i != end; ++i)
traits::push_back(attr, *i);
}
// T is string, but not convertible to value_type of container
template <typename T_>
static void append_to_container(T_ const& val, Attribute& attr, mpl::false_)
{
typedef typename char_type_of<T_>::type char_type;
append_to_string(attr, traits::get_begin<char_type>(val)
, traits::get_end<char_type>(val));
}
// T is string, and convertible to value_type of container
template <typename T_>
static void append_to_container(T_ const& val, Attribute& attr, mpl::true_)
{
traits::push_back(attr, val);
}
template <typename T_, typename Pred>
static void call(T_ const& val, Attribute& attr, Pred, mpl::true_)
{
typedef typename container_value<Attribute>::type value_type;
typedef typename is_convertible<T, value_type>::type is_value_type;
append_to_container(val, attr, is_value_type());
}
///////////////////////////////////////////////////////////////////////
static void call(T const& val, Attribute& attr)
{
typedef typename traits::is_container<T>::type is_container;
typedef typename traits::is_string<T>::type is_string;
call(val, attr, is_container(), is_string());
}
};
template <typename Attribute>
struct assign_to_container_from_value<Attribute, Attribute>
{
static void
call(Attribute const& val, Attribute& attr)
{
attr = val;
}
};
template <typename Attribute, typename T>
struct assign_to_container_from_value<Attribute, boost::optional<T>
, typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
{
static void
call(boost::optional<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
template <typename Attribute, typename T>
struct assign_to_container_from_value<Attribute, reference_wrapper<T>
, typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
{
static void
call(reference_wrapper<T> const& val, Attribute& attr)
{
assign_to(val.get(), attr);
}
};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
// overload for non-container attributes
template <typename T, typename Attribute>
inline void
assign_to(T const& val, Attribute& attr, mpl::false_)
{
assign_to_attribute_from_value<Attribute, T>::call(val, attr);
}
// overload for containers (but not for variants or optionals
// holding containers)
template <typename T, typename Attribute>
inline void
assign_to(T const& val, Attribute& attr, mpl::true_)
{
assign_to_container_from_value<Attribute, T>::call(val, attr);
}
}
template <typename T, typename Attribute>
inline void
assign_to(T const& val, Attribute& attr)
{
typedef typename mpl::and_<
traits::is_container<Attribute>
, traits::not_is_variant<Attribute>
, traits::not_is_optional<Attribute>
>::type is_not_wrapped_container;
detail::assign_to(val, attr, is_not_wrapped_container());
}
template <typename T>
inline void
assign_to(T const&, unused_type)
{
}
}}}
#endif
@@ -0,0 +1,176 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// Copyright (c) 2001-2011 Joel de Guzman
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
#define SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
template <typename Exposed, typename Transformed>
struct default_transform_attribute
{
typedef Transformed type;
static Transformed pre(Exposed&) { return Transformed(); }
static void post(Exposed& val, Transformed const& attr)
{
traits::assign_to(attr, val);
}
// fail() will be called by Qi rule's if the rhs failed parsing
static void fail(Exposed&) {}
};
// handle case where no transformation is required as the types are the same
template <typename Attribute>
struct default_transform_attribute<Attribute, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
static void fail(Attribute&) {}
};
template <typename Exposed, typename Transformed>
struct proxy_transform_attribute
{
typedef Transformed type;
static Transformed pre(Exposed& val) { return Transformed(val); }
static void post(Exposed&, Transformed const&) { /* no-op */ }
// fail() will be called by Qi rule's if the rhs failed parsing
static void fail(Exposed&) {}
};
// handle case where no transformation is required as the types are the same
template <typename Attribute>
struct proxy_transform_attribute<Attribute, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
static void fail(Attribute&) {}
};
// main specialization for Qi
template <typename Exposed, typename Transformed, typename Enable = void>
struct transform_attribute
: mpl::if_<
mpl::and_<
mpl::not_<is_const<Exposed> >
, mpl::not_<is_reference<Exposed> >
, traits::is_proxy<Transformed> >
, proxy_transform_attribute<Exposed, Transformed>
, default_transform_attribute<Exposed, Transformed>
>::type
{};
template <typename Exposed, typename Transformed>
struct transform_attribute<boost::optional<Exposed>, Transformed
, typename disable_if<is_same<boost::optional<Exposed>, Transformed> >::type>
{
typedef Transformed& type;
static Transformed& pre(boost::optional<Exposed>& val)
{
if (!val)
val = Transformed();
return boost::get<Transformed>(val);
}
static void post(boost::optional<Exposed>&, Transformed const&) {}
static void fail(boost::optional<Exposed>& val)
{
val = none; // leave optional uninitialized if rhs failed
}
};
// reference types need special handling
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
static void fail(Attribute&) {}
};
// unused_type needs some special handling as well
template <>
struct transform_attribute<unused_type, unused_type>
{
typedef unused_type type;
static unused_type pre(unused_type) { return unused; }
static void post(unused_type, unused_type) {}
static void fail(unused_type) {}
};
template <>
struct transform_attribute<unused_type const, unused_type>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<unused_type, Attribute>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<unused_type const, Attribute>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<Attribute, unused_type>
: transform_attribute<unused_type, unused_type>
{};
template <typename Attribute>
struct transform_attribute<Attribute const, unused_type>
: transform_attribute<unused_type, unused_type>
{};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed, Transformed, qi::domain>
: qi::transform_attribute<Exposed, Transformed>
{};
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed&, Transformed, qi::domain>
: transform_attribute<Exposed, Transformed, qi::domain>
{};
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute, qi::domain>
: qi::transform_attribute<Attribute&, Attribute>
{};
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed>
void post_transform(Exposed& dest, Transformed const& attr)
{
return transform_attribute<Exposed, Transformed, qi::domain>::post(dest, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed>
void fail_transform(Exposed& dest, Transformed const&)
{
return transform_attribute<Exposed, Transformed, qi::domain>::fail(dest);
}
}}}
#endif
@@ -0,0 +1,202 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM)
#define BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/attributes_fwd.hpp>
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// We provide overloads for the assign_to_attribute_from_iterators
// customization point for all built in types
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
struct assign_to_attribute_from_iterators<char, Iterator>
{
static void
call(Iterator const& first, Iterator const&, char& attr)
{
attr = *first;
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<signed char, Iterator>
{
static void
call(Iterator const& first, Iterator const&, signed char& attr)
{
attr = *first;
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned char, Iterator>
{
static void
call(Iterator const& first, Iterator const&, unsigned char& attr)
{
attr = *first;
}
};
// wchar_t is intrinsic
template <typename Iterator>
struct assign_to_attribute_from_iterators<wchar_t, Iterator>
{
static void
call(Iterator const& first, Iterator const&, wchar_t& attr)
{
attr = *first;
}
};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
// wchar_t is intrinsic, have separate overload for unsigned short
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned short, Iterator>
{
static void
call(Iterator const& first, Iterator const&, unsigned short& attr)
{
attr = *first;
}
};
#endif
template <typename Iterator>
struct assign_to_attribute_from_iterators<bool, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, bool& attr)
{
Iterator first_ = first;
qi::parse(first_, last, bool_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<short, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, short& attr)
{
Iterator first_ = first;
qi::parse(first_, last, short_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<int, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, int& attr)
{
Iterator first_ = first;
qi::parse(first_, last, int_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned int, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, unsigned int& attr)
{
Iterator first_ = first;
qi::parse(first_, last, uint_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<long, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, long& attr)
{
Iterator first_ = first;
qi::parse(first_, last, long_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<unsigned long, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, unsigned long& attr)
{
Iterator first_ = first;
qi::parse(first_, last, ulong_type(), attr);
}
};
#ifdef BOOST_HAS_LONG_LONG
template <typename Iterator>
struct assign_to_attribute_from_iterators<long_long_type, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, long_long_type& attr)
{
Iterator first_ = first;
qi::parse(first_, last, long_long_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<ulong_long_type, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, ulong_long_type& attr)
{
Iterator first_ = first;
qi::parse(first_, last, ulong_long_type(), attr);
}
};
#endif
template <typename Iterator>
struct assign_to_attribute_from_iterators<float, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, float& attr)
{
Iterator first_ = first;
qi::parse(first_, last, float_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<double, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, double& attr)
{
Iterator first_ = first;
qi::parse(first_, last, double_type(), attr);
}
};
template <typename Iterator>
struct assign_to_attribute_from_iterators<long double, Iterator>
{
static void
call(Iterator const& first, Iterator const& last, long double& attr)
{
Iterator first_ = first;
qi::parse(first_, last, long_double_type(), attr);
}
};
}}}
#endif
@@ -0,0 +1,30 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_SPIRIT_QI_DETAIL_ENABLE_LIT_JAN_06_2011_0945PM)
#define BOOST_SPIRIT_QI_DETAIL_ENABLE_LIT_JAN_06_2011_0945PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
namespace boost { namespace spirit
{
// enables lazy lit(...) for qi
template <>
struct use_lazy_terminal<qi::domain, tag::lit, 1>
: mpl::true_ {};
}}
#endif
@@ -0,0 +1,105 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM)
#define SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
#include <boost/throw_exception.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <
typename Iterator, typename Context
, typename Skipper, typename Exception>
struct expect_function
{
typedef Iterator iterator_type;
typedef Context context_type;
expect_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
, is_first(true)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr) const
{
// if this is not the first component in the expect chain we
// need to flush any multi_pass iterator we might be acting on
if (!is_first)
spirit::traits::clear_queue(first);
// if we are testing the first component in the sequence,
// return true if the parser fails, if this is not the first
// component, throw exception if the parser fails
if (!component.parse(first, last, context, skipper, attr))
{
if (is_first)
{
is_first = false;
return true; // true means the match failed
}
boost::throw_exception(Exception(first, last, component.what(context)));
#if defined(BOOST_NO_EXCEPTIONS)
return true; // for systems not supporting exceptions
#endif
}
is_first = false;
return false;
}
template <typename Component>
bool operator()(Component const& component) const
{
// if this is not the first component in the expect chain we
// need to flush any multi_pass iterator we might be acting on
if (!is_first)
spirit::traits::clear_queue(first);
// if we are testing the first component in the sequence,
// return true if the parser fails, if this not the first
// component, throw exception if the parser fails
if (!component.parse(first, last, context, skipper, unused))
{
if (is_first)
{
is_first = false;
return true;
}
boost::throw_exception(Exception(first, last, component.what(context)));
#if defined(BOOST_NO_EXCEPTIONS)
return false; // for systems not supporting exceptions
#endif
}
is_first = false;
return false;
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
mutable bool is_first;
private:
// silence MSVC warning C4512: assignment operator could not be generated
expect_function& operator= (expect_function const&);
};
}}}}
#endif
@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_FAIL_FUNCTION_APRIL_22_2006_0159PM)
#define SPIRIT_FAIL_FUNCTION_APRIL_22_2006_0159PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Iterator, typename Context, typename Skipper>
struct fail_function
{
typedef Iterator iterator_type;
typedef Context context_type;
fail_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr) const
{
// return true if the parser fails
return !component.parse(first, last, context, skipper, attr);
}
template <typename Component>
bool operator()(Component const& component) const
{
// return true if the parser fails
return !component.parse(first, last, context, skipper, unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
fail_function& operator= (fail_function const&);
};
}}}}
#endif
@@ -0,0 +1,97 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_DETAIL_PARSE_DEC_02_2009_0411PM)
#define BOOST_SPIRIT_DETAIL_PARSE_DEC_02_2009_0411PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/skip_flag.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable = void>
struct parse_impl
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
// Did you intend to use the auto_ facilities while forgetting to
// #include <boost/spirit/include/qi_auto.hpp>?
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
};
template <typename Expr>
struct parse_impl<Expr
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
{
template <typename Iterator>
static bool call(
Iterator& first
, Iterator last
, Expr const& expr)
{
return compile<qi::domain>(expr).parse(
first, last, unused, unused, unused);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable = void>
struct phrase_parse_impl
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
// Did you intend to use the auto_ facilities while forgetting to
// #include <boost/spirit/include/qi_auto.hpp>?
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
};
template <typename Expr>
struct phrase_parse_impl<Expr
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
{
template <typename Iterator, typename Skipper>
static bool call(
Iterator& first
, Iterator last
, Expr const& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the skipper is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
typedef
typename result_of::compile<qi::domain, Skipper>::type
skipper_type;
skipper_type const skipper_ = compile<qi::domain>(skipper);
if (!compile<qi::domain>(expr).parse(
first, last, unused, skipper_, unused))
return false;
if (post_skip == skip_flag::postskip)
qi::skip_over(first, last, skipper_);
return true;
}
};
}}}}
#endif
@@ -0,0 +1,191 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM)
#define BOOST_SPIRIT_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/qi/auto/create_parser.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/and.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct parse_impl<Expr
, typename enable_if<
mpl::and_<
traits::meta_create_exists<qi::domain, Expr>
, mpl::not_<traits::matches<qi::domain, Expr> > >
>::type>
{
template <typename Iterator>
static bool call(Iterator& first, Iterator last, Expr& expr)
{
return qi::parse(first, last, create_parser<Expr>(), expr);
}
template <typename Iterator>
static bool call(Iterator& first, Iterator last, Expr const& expr)
{
return qi::parse(first, last, create_parser<Expr>()
, const_cast<Expr&>(expr));
}
};
// the following specializations are needed to explicitly disambiguate
// the two possible specializations for parse_impl<char> and
// parse_impl<wchar_t>
template <>
struct parse_impl<char>
{
template <typename Iterator>
static bool call(Iterator& first, Iterator last, char& expr)
{
return qi::parse(first, last, create_parser<char>(), expr);
}
template <typename Iterator>
static bool call(Iterator& first, Iterator last, char const&)
{
return qi::parse(first, last, create_parser<char>());
}
};
template <>
struct parse_impl<wchar_t>
{
template <typename Iterator>
static bool call(Iterator& first, Iterator last, wchar_t& expr)
{
return qi::parse(first, last, create_parser<wchar_t>(), expr);
}
template <typename Iterator>
static bool call(Iterator& first, Iterator last, wchar_t const&)
{
return qi::parse(first, last, create_parser<wchar_t>());
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct phrase_parse_impl<Expr
, typename enable_if<
mpl::and_<
traits::meta_create_exists<qi::domain, Expr>
, mpl::not_<traits::matches<qi::domain, Expr> > >
>::type>
{
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, Expr& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<Expr>()
, skipper, post_skip, expr);
}
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, Expr const& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<Expr>()
, skipper, post_skip, const_cast<Expr&>(expr));
}
};
// the following specializations are needed to explicitly disambiguate
// the two possible specializations for phrase_parse_impl<char> and
// phrase_parse_impl<wchar_t>
template <>
struct phrase_parse_impl<char>
{
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, char& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<char>()
, skipper, post_skip, expr);
}
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, char const&
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<char>()
, skipper, post_skip);
}
};
template <>
struct phrase_parse_impl<wchar_t>
{
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, wchar_t& expr
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<wchar_t>()
, skipper, post_skip, expr);
}
template <typename Iterator, typename Skipper>
static bool call(Iterator& first, Iterator last, wchar_t const&
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
{
return qi::phrase_parse(first, last, create_parser<wchar_t>()
, skipper, post_skip);
}
};
}}}}
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr>
inline bool
parse(
Iterator& first
, Iterator last
, Expr& expr)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
return detail::parse_impl<Expr>::call(first, last, expr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr& expr
, Skipper const& skipper
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function, you need to supply at least a
// forward_iterator instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
return detail::phrase_parse_impl<Expr>::call(
first, last, expr, skipper, post_skip);
}
}}}
#endif
@@ -0,0 +1,382 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_PASS_CONTAINER_JANUARY_06_2009_0802PM)
#define SPIRIT_PASS_CONTAINER_JANUARY_06_2009_0802PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/container.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
// Helper meta-function allowing to evaluate weak substitutability and
// negate the result if the predicate (Sequence) is not true
template <typename Sequence, typename Attribute, typename ValueType>
struct negate_weak_substitute_if_not
: mpl::if_<
Sequence
, typename traits::is_weak_substitute<Attribute, ValueType>::type
, typename mpl::not_<
traits::is_weak_substitute<Attribute, ValueType>
>::type>
{};
// pass_through_container: utility to check decide whether a provided
// container attribute needs to be passed through to the current component
// or of we need to split the container by passing along instances of its
// value type
// if the expected attribute of the current component is neither a Fusion
// sequence nor a container, we will pass through the provided container
// only if its value type is not compatible with the component
template <typename Container, typename ValueType, typename Attribute
, typename Sequence, typename Enable = void>
struct pass_through_container_base
: negate_weak_substitute_if_not<Sequence, Attribute, ValueType>
{};
// Specialization for fusion sequences, in this case we check whether all
// the types in the sequence are convertible to the lhs attribute.
//
// We return false if the rhs attribute itself is a fusion sequence, which
// is compatible with the LHS sequence (we want to pass through this
// attribute without it being split apart).
template <typename Container, typename ValueType, typename Attribute
, typename Sequence = mpl::true_>
struct not_compatible_element
: mpl::and_<
negate_weak_substitute_if_not<Sequence, Attribute, Container>
, negate_weak_substitute_if_not<Sequence, Attribute, ValueType> >
{};
// If the value type of the container is not a Fusion sequence, we pass
// through the container if each of the elements of the Attribute
// sequence is compatible with either the container or its value type.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence
, bool IsSequence = fusion::traits::is_sequence<ValueType>::value>
struct pass_through_container_fusion_sequence
{
typedef typename mpl::find_if<
Attribute, not_compatible_element<Container, ValueType, mpl::_1>
>::type iter;
typedef typename mpl::end<Attribute>::type end;
typedef typename is_same<iter, end>::type type;
};
// If both, the Attribute and the value type of the provided container
// are Fusion sequences, we pass the container only if the two
// sequences are not compatible.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_fusion_sequence<
Container, ValueType, Attribute, Sequence, true>
{
typedef typename mpl::find_if<
Attribute
, not_compatible_element<Container, ValueType, mpl::_1, Sequence>
>::type iter;
typedef typename mpl::end<Attribute>::type end;
typedef typename is_same<iter, end>::type type;
};
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_base<Container, ValueType, Attribute
, Sequence
, typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
: pass_through_container_fusion_sequence<
Container, ValueType, Attribute, Sequence>
{};
// Specialization for containers
//
// If the value type of the attribute of the current component is not
// a Fusion sequence, we have to pass through the provided container if
// both are compatible.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence, typename AttributeValueType
, bool IsSequence = fusion::traits::is_sequence<AttributeValueType>::value>
struct pass_through_container_container
: mpl::or_<
traits::is_weak_substitute<Attribute, Container>
, traits::is_weak_substitute<AttributeValueType, Container> >
{};
// If the value type of the exposed container attribute is a Fusion
// sequence, we use the already existing logic for those.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence, typename AttributeValueType>
struct pass_through_container_container<
Container, ValueType, Attribute, Sequence, AttributeValueType, true>
: pass_through_container_fusion_sequence<
Container, ValueType, AttributeValueType, Sequence>
{};
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_base<
Container, ValueType, Attribute, Sequence
, typename enable_if<traits::is_container<Attribute> >::type>
: detail::pass_through_container_container<
Container, ValueType, Attribute, Sequence
, typename traits::container_value<Attribute>::type>
{};
// Specialization for exposed optional attributes
//
// If the type embedded in the exposed optional is not a Fusion
// sequence we pass through the container attribute if it is compatible
// either to the optionals embedded type or to the containers value
// type.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence
, bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
struct pass_through_container_optional
: mpl::or_<
traits::is_weak_substitute<Attribute, Container>
, traits::is_weak_substitute<Attribute, ValueType> >
{};
// If the embedded type of the exposed optional attribute is a Fusion
// sequence, we use the already existing logic for those.
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container_optional<
Container, ValueType, Attribute, Sequence, true>
: pass_through_container_fusion_sequence<
Container, ValueType, Attribute, Sequence>
{};
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container
: pass_through_container_base<Container, ValueType, Attribute, Sequence>
{};
// Handle optional attributes
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container<
Container, ValueType, boost::optional<Attribute>, Sequence>
: pass_through_container_optional<
Container, ValueType, Attribute, Sequence>
{};
// If both, the containers value type and the exposed attribute type are
// 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>
struct pass_through_container<
Container, boost::optional<ValueType>, boost::optional<Attribute>
, Sequence>
: mpl::not_<traits::is_weak_substitute<Attribute, ValueType> >
{};
// Specialization for exposed variant attributes
//
// 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 || \
/***/
// make sure unused variant parameters do not affect the outcome
template <typename Container, typename ValueType, typename Sequence>
struct pass_through_container<Container, ValueType
, boost::detail::variant::void_, Sequence>
: mpl::false_
{};
template <typename Container, typename ValueType, typename Sequence
, BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct pass_through_container<Container, ValueType
, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Sequence>
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
, BOOST_SPIRIT_PASS_THROUGH_CONTAINER, _) false>
{};
#undef BOOST_SPIRIT_PASS_THROUGH_CONTAINER
#endif
}}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// forwarding customization point for domain qi::domain
template <typename Container, typename ValueType, typename Attribute
, typename Sequence>
struct pass_through_container<
Container, ValueType, Attribute, Sequence, qi::domain>
: qi::detail::pass_through_container<
Container, ValueType, Attribute, Sequence>
{};
}}}
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// This function handles the case where the attribute (Attr) given
// the sequence is an STL container. This is a wrapper around F.
// The function F does the actual parsing.
template <typename F, typename Attr, typename Sequence>
struct pass_container
{
typedef typename F::context_type context_type;
typedef typename F::iterator_type iterator_type;
pass_container(F const& f_, Attr& attr_)
: f(f_), attr(attr_) {}
// this is for the case when the current element exposes an attribute
// which is pushed back onto the container
template <typename Component>
bool dispatch_container(Component const& component, mpl::false_) const
{
// synthesized attribute needs to be default constructed
typename traits::container_value<Attr>::type val =
typename traits::container_value<Attr>::type();
iterator_type save = f.first;
bool r = f(component, val);
if (!r)
{
// push the parsed value into our attribute
r = !traits::push_back(attr, val);
if (r)
f.first = save;
}
return r;
}
// this is for the case when the current element is able to handle an
// attribute which is a container itself, this element will push its
// data directly into the attribute container
template <typename Component>
bool dispatch_container(Component const& component, mpl::true_) const
{
return f(component, attr);
}
///////////////////////////////////////////////////////////////////////
// this is for the case when the current element doesn't expect an
// attribute
template <typename Component>
bool dispatch_attribute(Component const& component, mpl::false_) const
{
return f(component, unused);
}
// the current element expects an attribute
template <typename Component>
bool dispatch_attribute(Component const& component, mpl::true_) const
{
typedef typename traits::container_value<Attr>::type value_type;
typedef typename traits::attribute_of<
Component, context_type, iterator_type>::type
rhs_attribute;
// this predicate detects, whether the attribute of the current
// element is a substitute for the value type of the container
// attribute
typedef mpl::and_<
traits::handles_container<
Component, Attr, context_type, iterator_type>
, traits::pass_through_container<
Attr, value_type, rhs_attribute, Sequence, qi::domain>
> predicate;
return dispatch_container(component, predicate());
}
// Dispatches to dispatch_main depending on the attribute type
// of the Component
template <typename Component>
bool operator()(Component const& component) const
{
// we need to dispatch depending on the type of the attribute
// of the current element (component). If this is has no attribute
// we shouldn't pass an attribute at all.
typedef typename traits::not_is_unused<
typename traits::attribute_of<
Component, context_type, iterator_type
>::type
>::type predicate;
// ensure the attribute is actually a container type
traits::make_container(attr);
return dispatch_attribute(component, predicate());
}
F f;
Attr& attr;
private:
// silence MSVC warning C4512: assignment operator could not be generated
pass_container& operator= (pass_container const&);
};
///////////////////////////////////////////////////////////////////////////
// Utility function to make a pass_container for container components
// (kleene, list, plus, repeat)
template <typename F, typename Attr>
inline pass_container<F, Attr, mpl::false_>
make_pass_container(F const& f, Attr& attr)
{
return pass_container<F, Attr, mpl::false_>(f, attr);
}
// Utility function to make a pass_container for sequences
template <typename F, typename Attr>
inline pass_container<F, Attr, mpl::true_>
make_sequence_pass_container(F const& f, Attr& attr)
{
return pass_container<F, Attr, mpl::true_>(f, attr);
}
}}}}
#endif
@@ -0,0 +1,70 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_PASS_FUNCTION_FEBRUARY_05_2007_1138AM)
#define SPIRIT_PASS_FUNCTION_FEBRUARY_05_2007_1138AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/optional.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Iterator, typename Context, typename Skipper>
struct pass_function
{
pass_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr)
{
// return true if the parser succeeds
return component.parse(first, last, context, skipper, attr);
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, boost::optional<Attribute>& attr)
{
// return true if the parser succeeds
Attribute val;
if (component.parse(first, last, context, skipper, val))
{
attr = val;
return true;
}
return false;
}
template <typename Component>
bool operator()(Component const& component)
{
// return true if the parser succeeds
return component.parse(first, last, context, skipper, unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
pass_function& operator= (pass_function const&);
};
}}}}
#endif
@@ -0,0 +1,88 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_PERMUTE_FUNCTION_MARCH_13_2007_1129AM)
#define SPIRIT_PERMUTE_FUNCTION_MARCH_13_2007_1129AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/optional.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Iterator, typename Context, typename Skipper>
struct permute_function
{
permute_function(
Iterator& first_, Iterator const& last_
, Context& context_, Skipper const& skipper_)
: first(first_)
, last(last_)
, context(context_)
, skipper(skipper_)
{
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, Attribute& attr)
{
// return true if the parser succeeds and the slot is not yet taken
if (!*taken && component.parse(first, last, context, skipper, attr))
{
*taken = true;
++taken;
return true;
}
++taken;
return false;
}
template <typename Component, typename Attribute>
bool operator()(Component const& component, boost::optional<Attribute>& attr)
{
// return true if the parser succeeds and the slot is not yet taken
Attribute val;
if (!*taken && component.parse(first, last, context, skipper, val))
{
attr = val;
*taken = true;
++taken;
return true;
}
++taken;
return false;
}
template <typename Component>
bool operator()(Component const& component)
{
// return true if the parser succeeds and the slot is not yet taken
if (!*taken && component.parse(first, last, context, skipper, unused))
{
*taken = true;
++taken;
return true;
}
++taken;
return false;
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
bool* taken;
private:
// silence MSVC warning C4512: assignment operator could not be generated
permute_function& operator= (permute_function const&);
};
}}}}
#endif
@@ -0,0 +1,89 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_STRING_PARSE_APR_18_2006_1125PM)
#define BOOST_SPIRIT_STRING_PARSE_APR_18_2006_1125PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/detail/assign_to.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* str
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
Char ch = *str;
for (; !!ch; ++i)
{
if (i == last || (ch != *i))
return false;
ch = *++str;
}
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& str
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
typename String::const_iterator stri = str.begin();
typename String::const_iterator str_last = str.end();
for (; stri != str_last; ++stri, ++i)
if (i == last || (*stri != *i))
return false;
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* uc_i, Char const* lc_i
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& ucstr, String const& lcstr
, Iterator& first, Iterator const& last, Attribute& attr)
{
typename String::const_iterator uc_i = ucstr.begin();
typename String::const_iterator uc_last = ucstr.end();
typename String::const_iterator lc_i = lcstr.begin();
Iterator i = first;
for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
spirit::traits::assign_to(first, i, attr);
first = i;
return true;
}
}}}}
#endif
@@ -0,0 +1,63 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_SPIRIT_QI_UNUSED_SKIPPER_JUL_25_2009_0921AM)
#define BOOST_SPIRIT_QI_UNUSED_SKIPPER_JUL_25_2009_0921AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Skipper>
struct unused_skipper : unused_type
{
unused_skipper(Skipper const& skipper_)
: skipper(skipper_) {}
Skipper const& skipper;
private:
// silence MSVC warning C4512: assignment operator could not be generated
unused_skipper& operator= (unused_skipper const&);
};
template <typename Skipper>
struct is_unused_skipper
: mpl::false_ {};
template <typename Skipper>
struct is_unused_skipper<unused_skipper<Skipper> >
: mpl::true_ {};
template <>
struct is_unused_skipper<unused_type>
: mpl::true_ {};
// If a surrounding lexeme[] directive was specified, the current
// skipper is of the type unused_skipper. In this case we
// re-activate the skipper which was active before the skip[]
// directive.
template <typename Skipper>
inline Skipper const&
get_skipper(unused_skipper<Skipper> const& u)
{
return u.skipper;
}
// If no surrounding lexeme[] directive was specified we keep what we got.
template <typename Skipper>
inline Skipper const&
get_skipper(Skipper const& u)
{
return u;
}
}}}}
#endif