|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r57104 - in trunk/boost/spirit/home: qi/detail support
From: joel_at_[hidden]
Date: 2009-10-23 11:58:32
Author: djowel
Date: 2009-10-23 11:58:31 EDT (Fri, 23 Oct 2009)
New Revision: 57104
URL: http://svn.boost.org/trac/boost/changeset/57104
Log:
alternatives with optional attributes
Text files modified:
trunk/boost/spirit/home/qi/detail/alternative_function.hpp | 10 ++++-
trunk/boost/spirit/home/qi/detail/assign_to.hpp | 9 +++++
trunk/boost/spirit/home/support/attributes.hpp | 61 ++++++++++++++++++++++++++++++++++-----
3 files changed, 68 insertions(+), 12 deletions(-)
Modified: trunk/boost/spirit/home/qi/detail/alternative_function.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/alternative_function.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/alternative_function.hpp 2009-10-23 11:58:31 EDT (Fri, 23 Oct 2009)
@@ -42,8 +42,8 @@
template <typename Component>
bool call(Component const& component, mpl::false_) const
{
- // if Attribute is a variant, then create an attribute for
- // the Component with its expected type.
+ // if Attribute is a variant or optional, then create an
+ // attribute for the Component with its expected type.
typename traits::attribute_of<Component, Context, Iterator>::type val;
if (component.parse(first, last, context, skipper, val))
{
@@ -57,7 +57,11 @@
bool operator()(Component const& component) const
{
// return true if the parser succeeds
- return call(component, spirit::traits::not_is_variant<Attribute>());
+ return call(component,
+ mpl::and_<
+ spirit::traits::not_is_variant<Attribute>,
+ spirit::traits::not_is_optional<Attribute>
+ >());
}
Iterator& first;
Modified: trunk/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/assign_to.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/assign_to.hpp 2009-10-23 11:58:31 EDT (Fri, 23 Oct 2009)
@@ -82,6 +82,15 @@
attr = val;
}
};
+
+ template <typename Attribute>
+ struct assign_to_attribute_from_value<optional<Attribute>, unused_type>
+ {
+ static void
+ call(unused_type, optional<Attribute> const& attr)
+ {
+ }
+ };
template <typename T, typename Attribute>
inline void
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2009-10-23 11:58:31 EDT (Fri, 23 Oct 2009)
@@ -51,6 +51,16 @@
struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
: mpl::false_
{};
+
+ template <typename T>
+ struct not_is_optional
+ : mpl::true_
+ {};
+
+ template <typename T>
+ struct not_is_variant<boost::optional<T> >
+ : mpl::false_
+ {};
///////////////////////////////////////////////////////////////////////////
// attribute_of
@@ -255,7 +265,40 @@
typename mpl::find_if<Sequence, is_same<mpl::_, unused_type> >::type
, typename mpl::end<Sequence>::type>
{};
-
+
+ namespace detail
+ {
+ // default case
+ template <typename Sequence, bool no_unused
+ , int size = mpl::size<Sequence>::value>
+ struct build_collapsed_variant
+ : spirit::detail::as_variant<Sequence> {};
+
+ // 1 element case
+ template <typename Sequence, bool no_unused>
+ struct build_collapsed_variant<Sequence, no_unused, 1>
+ : mpl::front<Sequence> {};
+
+ // 2 element case, no unused
+ template <typename Sequence>
+ struct build_collapsed_variant<Sequence, true, 2>
+ : spirit::detail::as_variant<Sequence> {};
+
+ // 2 element case, with unused
+ template <typename Sequence>
+ struct build_collapsed_variant<Sequence, false, 2>
+ {
+ typedef optional<
+ typename mpl::deref<
+ typename mpl::next<
+ typename mpl::begin<Sequence>::type
+ >::type
+ >::type
+ >
+ type;
+ };
+ }
+
///////////////////////////////////////////////////////////////////////////
// build_variant
//
@@ -263,7 +306,7 @@
// that 1) all attributes in the variant are unique 2) puts the unused
// attribute, if there is any, to the front and 3) collapses single element
// variants, variant<T> to T.
- ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
template <typename Sequence>
struct build_variant
{
@@ -271,6 +314,8 @@
typedef typename
filter_unused_attributes<Sequence>::type
filtered_attributes;
+
+ typedef has_no_unused<Sequence> no_unused;
// If the original attribute list does not contain any unused
// attributes, it is used, otherwise a single unused_type is
@@ -278,7 +323,7 @@
// there is an unused_type in the list, it is the first one.
typedef typename
mpl::eval_if<
- has_no_unused<Sequence>,
+ no_unused,
mpl::identity<Sequence>,
fusion::result_of::push_front<filtered_attributes, unused_type>
>::type
@@ -293,16 +338,14 @@
mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
>
>::type
- new_sequence;
+ no_duplicates;
// If there is only one type in the list of types we strip off the
// variant. IOTW, collapse single element variants, variant<T> to T.
+ // Take note that this also collapses variant<unused_type, T> to T.
typedef typename
- mpl::eval_if<
- mpl::equal_to<mpl::size<new_sequence>, mpl::int_<1> >,
- mpl::deref<mpl::front<attribute_sequence> >,
- spirit::detail::as_variant<new_sequence>
- >::type
+ traits::detail::build_collapsed_variant<
+ no_duplicates, no_unused::value>::type
type;
};
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk