Boost logo

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