|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r73457 - trunk/boost/spirit/home/support
From: joel_at_[hidden]
Date: 2011-07-30 21:10:12
Author: djowel
Date: 2011-07-30 21:10:11 EDT (Sat, 30 Jul 2011)
New Revision: 73457
URL: http://svn.boost.org/trac/boost/changeset/73457
Log:
Added support for extended variants
Text files modified:
trunk/boost/spirit/home/support/attributes.hpp | 89 +++++++++++++++++++++++++++++++++------
1 files changed, 75 insertions(+), 14 deletions(-)
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2011-07-30 21:10:11 EDT (Sat, 30 Jul 2011)
@@ -50,6 +50,54 @@
#include <ios>
///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+ template <
+ BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ BOOST_VARIANT_LIMIT_TYPES,
+ typename T, boost::detail::variant::void_)
+ // We should not be depending on detail::variant::void_
+ // but I'm not sure if this can fixed. Any other way is
+ // clumsy at best.
+ >
+ struct adapted_variant
+ {
+ // tell spirit that this is an adapted variant
+ struct adapted_variant_tag;
+
+ typedef boost::variant<
+ BOOST_VARIANT_ENUM_PARAMS(T)>
+ variant_type;
+ typedef typename variant_type::types types;
+
+ typedef adapted_variant<BOOST_VARIANT_ENUM_PARAMS(T)> base_type;
+
+ adapted_variant() : var() {}
+
+ template <typename T>
+ adapted_variant(T const& var)
+ : var(var) {}
+
+ template <typename F>
+ typename F::result_type apply_visitor(F v) const
+ {
+ var.apply_visitor(v);
+ }
+
+ variant_type const& get() const
+ {
+ return var;
+ }
+
+ variant_type& get()
+ {
+ return var;
+ }
+
+ variant_type var;
+ };
+}}
+
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
@@ -96,7 +144,7 @@
}
template <typename T, typename Expected, typename Enable /*= void*/>
- struct is_substitute
+ struct is_substitute
: detail::is_substitute_impl<T, Expected> {};
template <typename T, typename Expected>
@@ -118,7 +166,7 @@
struct is_weak_substitute_impl : is_convertible<T, Expected> {};
// // An exposed attribute is a weak substitute for a supplied container
-// // attribute if it is a weak substitute for its value_type. This is
+// // attribute if it is a weak substitute for its value_type. This is
// // true as all character parsers exposing compatible with a container
// // attribute having the corresponding character type as its value_type.
// template <typename T, typename Expected>
@@ -134,11 +182,11 @@
// , is_string<Expected>
// , is_weak_substitute_for_value_type<T, Expected> >
// >::type>
-// : mpl::true_
+// : mpl::true_
// {};
// An exposed container attribute is a weak substitute for a supplied
- // container attribute if and only if their value_types are weak
+ // container attribute if and only if their value_types are weak
// substitutes.
template <typename T, typename Expected>
struct value_type_is_weak_substitute
@@ -157,7 +205,7 @@
>::type>
: mpl::true_ {};
- // Two fusion sequences are weak substitutes if and only if their
+ // Two fusion sequences are weak substitutes if and only if their
// elements are pairwise weak substitutes.
template <typename T, typename Expected>
struct is_weak_substitute_impl<T, Expected,
@@ -178,15 +226,15 @@
typename enable_if<
mpl::and_<
mpl::not_<fusion::traits::is_sequence<T> >
- , fusion::traits::is_sequence<Expected> >
+ , fusion::traits::is_sequence<Expected> >
>::type>
: mpl::false_ {};
}
- // main template forwards to detail namespace, this helps older compilers
+ // main template forwards to detail namespace, this helps older compilers
// to disambiguate things
template <typename T, typename Expected, typename Enable /*= void*/>
- struct is_weak_substitute
+ struct is_weak_substitute
: detail::is_weak_substitute_impl<T, Expected> {};
template <typename T, typename Expected>
@@ -223,7 +271,7 @@
template <typename T>
struct is_weak_substitute<T, T
, typename enable_if<
- mpl::and_<not_is_optional<T>, not_is_variant<T> >
+ mpl::and_<not_is_optional<T>, not_is_variant<T> >
>::type>
: mpl::true_ {};
@@ -241,9 +289,22 @@
>::type>
: mpl::true_ {};
+ namespace detail
+ {
+ // By declaring a nested struct in your class/struct, you tell
+ // spirit that it is regarded as a variant type. The minimum
+ // required interface for such a variant is that it has constructors
+ // for various types supported by your variant and a typedef 'types'
+ // which is an mpl sequence of the contained types.
+ //
+ // This is an intrusive interface. For a non-intrusive interface,
+ // use the not_is_variant trait.
+ BOOST_MPL_HAS_XXX_TRAIT_DEF(adapted_variant_tag)
+ }
+
template <typename T, typename Domain, typename Enable/* = void*/>
struct not_is_variant
- : mpl::true_
+ : mpl::not_<detail::has_adapted_variant_tag<T> >
{};
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Domain>
@@ -460,7 +521,7 @@
fusion::traits::is_sequence<Attribute>
, mpl::not_<traits::is_container<Attribute> >
>
- >::type>
+ >::type>
{
typedef typename fusion::result_of::size<Attribute>::value_type type;
@@ -477,7 +538,7 @@
traits::is_container<Attribute>
, mpl::not_<traits::is_iterator_range<Attribute> >
>
- >::type>
+ >::type>
{
typedef typename Attribute::size_type type;
@@ -489,7 +550,7 @@
}
template <typename Attribute, typename Enable/* = void*/>
- struct attribute_size
+ struct attribute_size
: detail::attribute_size_impl<Attribute>
{};
@@ -500,7 +561,7 @@
static type call(optional<Attribute> const& val)
{
- if (!val)
+ if (!val)
return 0;
return val.get();
}
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