|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61002 - in trunk/boost/spirit/home: qi/numeric support
From: joel_at_[hidden]
Date: 2010-04-02 12:00:04
Author: djowel
Date: 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
New Revision: 61002
URL: http://svn.boost.org/trac/boost/changeset/61002
Log:
- better attribute handling
- introduced is_proxy
Text files modified:
trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp | 38 ++++++++++++++---
trunk/boost/spirit/home/qi/numeric/real.hpp | 21 ++++++++-
trunk/boost/spirit/home/support/attributes.hpp | 88 +++++++++++++++++++++++++--------------
trunk/boost/spirit/home/support/attributes_fwd.hpp | 10 +++
4 files changed, 114 insertions(+), 43 deletions(-)
Modified: trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -51,10 +51,8 @@
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
not_supported_radix, ());
- template <typename Iterator, typename Attribute>
- static bool call(
- Iterator& first, Iterator const& last,
- Attribute& attr)
+ template <typename Iterator>
+ static bool call(Iterator& first, Iterator const& last, T& attr)
{
if (first == last)
return false;
@@ -70,13 +68,26 @@
Iterator save = first;
if (!extract_type::parse(first, last,
- detail::cast_unsigned<Attribute>::call(attr)))
+ detail::cast_unsigned<T>::call(attr)))
{
first = save;
return false;
}
return true;
}
+
+ template <typename Iterator, typename Attribute>
+ static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::assign_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
};
///////////////////////////////////////////////////////////////////////////
@@ -90,8 +101,8 @@
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
not_supported_radix, ());
- template <typename Iterator, typename Attribute>
- static bool call(Iterator& first, Iterator const& last, Attribute& attr)
+ template <typename Iterator>
+ static bool call(Iterator& first, Iterator const& last, T& attr)
{
if (first == last)
return false;
@@ -118,6 +129,19 @@
}
return true;
}
+
+ template <typename Iterator, typename Attribute>
+ static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::assign_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
};
}}}
Modified: trunk/boost/spirit/home/qi/numeric/real.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/real.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/real.hpp 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -62,17 +62,32 @@
typedef T type;
};
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
+ template <typename Iterator, typename Context, typename Skipper>
bool parse(Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
- , Attribute& attr) const
+ , T& attr) const
{
qi::skip_over(first, last, skipper);
return detail::real_impl<T, RealPolicies>::
parse(first, last, attr, RealPolicies());
}
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr_) const
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (parse(first, last, context, skipper, attr))
+ {
+ traits::assign_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+
template <typename Context>
info what(Context& /*context*/) const
{
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -25,6 +25,8 @@
#include <boost/fusion/include/pop_front.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/for_each.hpp>
+#include <boost/fusion/include/is_view.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
#include <boost/foreach.hpp>
#include <boost/utility/value_init.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -52,6 +54,19 @@
// components.
///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable/* = void*/>
+ struct is_proxy : mpl::false_ {};
+
+ template <typename T>
+ struct is_proxy<T,
+ typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>,
+ fusion::traits::is_view<T>
+ >
+ >::type>
+ : mpl::true_ {};
+
template <typename T>
struct not_is_variant
: mpl::true_
@@ -80,25 +95,25 @@
{};
///////////////////////////////////////////////////////////////////////////
- // The compute_compatible_component_variant
+ // The compute_compatible_component_variant
///////////////////////////////////////////////////////////////////////////
namespace detail
{
- // A component is compatible to a given Attribute type if the
+ // A component is compatible to a given Attribute type if the
// Attribute is the same as the expected type of the component
template <typename Expected, typename Attribute>
- struct attribute_is_compatible
- : is_convertible<Attribute, Expected>
+ struct attribute_is_compatible
+ : is_convertible<Attribute, Expected>
{};
template <typename Expected, typename Attribute>
struct attribute_is_compatible<Expected, boost::optional<Attribute> >
- : is_convertible<Attribute, Expected>
+ : is_convertible<Attribute, Expected>
{};
template <typename Container>
struct is_hold_any_container
- : is_same<hold_any, typename traits::container_value<Container>::type>
+ : is_same<hold_any, typename traits::container_value<Container>::type>
{};
}
@@ -106,11 +121,11 @@
struct compute_compatible_component_variant
: mpl::or_<
traits::detail::attribute_is_compatible<Expected, Attribute>
- , is_same<hold_any, Expected>
+ , is_same<hold_any, Expected>
, mpl::eval_if<
is_container<Expected>
, traits::detail::is_hold_any_container<Expected>
- , mpl::false_> >
+ , mpl::false_> >
{};
template <typename Expected, typename Variant>
@@ -120,8 +135,8 @@
typedef typename variant_type::types types;
typedef typename mpl::end<types>::type end;
- typedef typename
- mpl::find_if<types, is_same<Expected, mpl::_1> >::type
+ typedef typename
+ mpl::find_if<types, is_same<Expected, mpl::_1> >::type
iter;
typedef typename mpl::distance<
@@ -133,8 +148,8 @@
enum { value = type::value };
// return the type in the variant the attribute is compatible with
- typedef typename
- mpl::eval_if<type, mpl::deref<iter>, mpl::identity<unused_type> >::type
+ typedef typename
+ mpl::eval_if<type, mpl::deref<iter>, mpl::identity<unused_type> >::type
compatible_type;
};
@@ -488,39 +503,50 @@
// attributes. This template can be used as a customization point, where
// the user is able specify specific transformation rules for any attribute
// type.
- //
- // The default attribute transformation (where the exposed attribute type is
- // different from the required transformed attribute type) relies on the
- // convertibility 'exposed type' --> 'transformed type', which has to exist
- // in order to successfully execute the pre transform step.
///////////////////////////////////////////////////////////////////////////
- template <typename Exposed, typename Transformed, typename Enable/* = void*/>
- struct transform_attribute
+ template <typename Exposed, typename Transformed>
+ struct default_transform_attribute
{
typedef Transformed type;
- static Transformed pre(Exposed& val) { return Transformed(val); }
+ static Transformed pre(Exposed& val) { return Transformed(); }
- // By default do post transformation only if types are convertible,
- // otherwise we assume no post transform is required (i.e. the user
- // utilizes nview et.al.).
- static void post(Exposed&, Transformed const&, mpl::false_)
- {
- }
- static void post(Exposed& val, Transformed const& attr, mpl::true_)
+ static void post(Exposed& val, Transformed const& attr)
{
assign_to(attr, val);
}
- static void post(Exposed& val, Transformed const& attr)
- {
- post(val, attr, is_convertible<Transformed, Exposed>());
- }
+ // fail() will be called by Qi rule's if the rhs failed parsing
+ static void fail(Exposed&) {}
+ };
+
+ template <typename Exposed, typename Transformed>
+ struct proxy_transform_attribute
+ {
+ typedef Transformed type;
+
+ static Transformed pre(Exposed& val) { return Transformed(val); }
+ static void post(Exposed& val, Transformed const& attr) { /* no-op */ }
// fail() will be called by Qi rule's if the rhs failed parsing
static void fail(Exposed&) {}
};
+ template <typename Exposed, typename Transformed, typename Enable/* = void*/>
+ struct transform_attribute
+ : default_transform_attribute<Exposed, Transformed> {};
+
+ template <typename Exposed, typename Transformed>
+ struct transform_attribute<Exposed, Transformed,
+ typename enable_if<
+ mpl::and_<
+ mpl::not_<is_const<Exposed> >,
+ mpl::not_<is_reference<Exposed> >,
+ is_proxy<Transformed>
+ >
+ >::type>
+ : proxy_transform_attribute<Exposed, Transformed> {};
+
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed const, Transformed>
{
Modified: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes_fwd.hpp (original)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -15,6 +15,12 @@
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a proxy
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct is_proxy;
+
+ ///////////////////////////////////////////////////////////////////////////
// Retrieve the attribute type to use from the given type
//
// This is needed to extract the correct attribute type from proxy classes
@@ -39,7 +45,7 @@
///////////////////////////////////////////////////////////////////////////
// Sometimes the user needs to transform the attribute types for certain
- // attributes. This template can be used as a customization point, where
+ // attributes. This template can be used as a customization point, where
// the user is able specify specific transformation rules for any attribute
// type.
///////////////////////////////////////////////////////////////////////////
@@ -111,7 +117,7 @@
template <typename Exposed, typename Transformed>
struct pre_transform;
- template <typename T>
+ template <typename T>
struct optional_value;
template <typename Container>
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