stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
+214
@@ -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
|
||||
Reference in New Issue
Block a user