|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r56217 - in trunk/boost/spirit/home: karma/binary karma/char karma/detail karma/numeric karma/stream karma/string support
From: hartmut.kaiser_at_[hidden]
Date: 2009-09-15 12:59:16
Author: hkaiser
Date: 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
New Revision: 56217
URL: http://svn.boost.org/trac/boost/changeset/56217
Log:
Spirit: all generators now accept a boost::optional holding the attribute and will fail if this is not initialized.
Text files modified:
trunk/boost/spirit/home/karma/binary/binary.hpp | 7 ++++-
trunk/boost/spirit/home/karma/char/char_generator.hpp | 5 +++
trunk/boost/spirit/home/karma/detail/alternative_function.hpp | 38 ++++++++++++++++++------------
trunk/boost/spirit/home/karma/numeric/int.hpp | 50 ++++++++++++++++++++++++++-------------
trunk/boost/spirit/home/karma/numeric/real.hpp | 10 ++++++-
trunk/boost/spirit/home/karma/numeric/uint.hpp | 18 +++++++++----
trunk/boost/spirit/home/karma/stream/stream.hpp | 10 ++++++-
trunk/boost/spirit/home/karma/string/lit.hpp | 12 ++++++++
trunk/boost/spirit/home/support/container.hpp | 35 ++++++++++++++++++++++++++++
9 files changed, 139 insertions(+), 46 deletions(-)
Modified: trunk/boost/spirit/home/karma/binary/binary.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/binary/binary.hpp (original)
+++ trunk/boost/spirit/home/karma/binary/binary.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -181,13 +181,16 @@
static bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr)
{
+ if (!traits::has_optional_value(attr))
+ return false;
+
// Even if the endian types are not pod's (at least not in the
// definition of C++03) it seems to be safe to assume they are.
// This allows us to treat them as a sequence of consecutive bytes.
boost::integer::endian<
endian, typename karma::detail::integer<bits>::type, bits
> p;
- p = attr;
+ p = traits::optional_value(attr);
unsigned char const* bytes =
reinterpret_cast<unsigned char const*>(&p);
@@ -239,7 +242,7 @@
typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context&, Delimiter const& d
- , Attribute const& attr) const
+ , Attribute const&) const
{
// Even if the endian types are not pod's (at least not in the
// definition of C++03) it seems to be safe to assume they are
Modified: trunk/boost/spirit/home/karma/char/char_generator.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/char/char_generator.hpp (original)
+++ trunk/boost/spirit/home/karma/char/char_generator.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -69,8 +69,11 @@
bool generate(OutputIterator& sink, Context& context, Delimiter const& d
, Attribute const& attr) const
{
+ if (!traits::has_optional_value(attr))
+ return false;
+
Char ch = Char();
- if (!this->derived().test(attr, ch, context))
+ if (!this->derived().test(traits::optional_value(attr), ch, context))
return false;
return karma::detail::generate_to(sink, ch, char_encoding(), tag()) &&
Modified: trunk/boost/spirit/home/karma/detail/alternative_function.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/alternative_function.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/alternative_function.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -32,10 +32,18 @@
// 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> {};
+
+ template <typename Expected, typename Attribute>
+ struct attribute_is_compatible<Expected, boost::optional<Attribute> >
+ : is_convertible<Attribute, Expected> {};
+
template <typename Expected, typename Attribute, typename IsNotVariant>
struct compute_compatible_component_variant
: mpl::or_<
- is_convertible<Attribute, Expected>
+ attribute_is_compatible<Expected, Attribute>
, is_same<hold_any, Expected> > {};
template <typename Expected, typename Attribute>
@@ -79,14 +87,14 @@
// this gets instantiated if the Attribute type is _not_ compatible with
// the generator
- template <typename Component, typename Attribute, typename Expected,
- typename Enable = void>
+ template <typename Component, typename Attribute, typename Expected
+ , typename Enable = void>
struct alternative_generate
{
template <typename OutputIterator, typename Context, typename Delimiter>
static bool
- call(Component const&, OutputIterator&, Context&, Delimiter const&,
- Attribute const&)
+ call(Component const&, OutputIterator&, Context&, Delimiter const&
+ , Attribute const&)
{
return false;
}
@@ -97,8 +105,8 @@
{
template <typename OutputIterator, typename Context, typename Delimiter>
static bool
- call(Component const& component, OutputIterator& sink,
- Context& ctx, Delimiter const& d, unused_type)
+ call(Component const& component, OutputIterator& sink, Context& ctx
+ , Delimiter const& d, unused_type)
{
// return true if any of the generators succeed
return component.generate(sink, ctx, d, unused);
@@ -126,8 +134,8 @@
{
template <typename OutputIterator, typename Context, typename Delimiter>
static bool
- call(Component const& component, OutputIterator& sink,
- Context& ctx, Delimiter const& d, Attribute const& attr)
+ call(Component const& component, OutputIterator& sink
+ , Context& ctx, Delimiter const& d, Attribute const& attr)
{
return call(component, sink, ctx, d, attr
, spirit::traits::not_is_variant<Attribute>());
@@ -135,16 +143,16 @@
template <typename OutputIterator, typename Context, typename Delimiter>
static bool
- call(Component const& component, OutputIterator& sink,
- Context& ctx, Delimiter const& d, Attribute const& attr, mpl::true_)
+ call(Component const& component, OutputIterator& sink
+ , Context& ctx, Delimiter const& d, Attribute const& attr, mpl::true_)
{
return component.generate(sink, ctx, d, attr);
}
template <typename OutputIterator, typename Context, typename Delimiter>
static bool
- call(Component const& component, OutputIterator& sink,
- Context& ctx, Delimiter const& d, Attribute const& attr, mpl::false_)
+ call(Component const& component, OutputIterator& sink
+ , Context& ctx, Delimiter const& d, Attribute const& attr, mpl::false_)
{
typedef
compute_compatible_component<Expected, Attribute>
@@ -175,8 +183,8 @@
typename Attribute>
struct alternative_generate_functor
{
- alternative_generate_functor(OutputIterator& sink_, Context& ctx_,
- Delimiter const& d, Attribute const& attr_)
+ alternative_generate_functor(OutputIterator& sink_, Context& ctx_
+ , Delimiter const& d, Attribute const& attr_)
: sink(sink_), ctx(ctx_), delim(d), attr(attr_) {}
template <typename Component>
Modified: trunk/boost/spirit/home/karma/numeric/int.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/int.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/int.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -179,6 +179,17 @@
: primitive_generator<any_int_generator<T, CharEncoding, Tag, Radix
, force_sign> >
{
+ private:
+ template <typename OutputIterator, typename Attribute>
+ static bool insert_int(OutputIterator& sink, Attribute const& attr)
+ {
+ return sign_inserter::call(sink, detail::is_zero(attr)
+ , detail::is_negative(attr), force_sign) &&
+ int_inserter<Radix, CharEncoding, Tag>::call(sink
+ , detail::absolute_value(attr));
+ }
+
+ public:
template <typename Context, typename Unused>
struct attribute
{
@@ -200,11 +211,11 @@
generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr)
{
- return sign_inserter::call(sink, detail::is_zero(attr)
- , detail::is_negative(attr), force_sign) &&
- int_inserter<Radix, CharEncoding, Tag>::call(sink
- , detail::absolute_value(attr)) &&
- karma::delimit_out(sink, d); // always do post-delimiting
+ if (!traits::has_optional_value(attr))
+ return false; // fail if it's an uninitialized optional
+
+ return insert_int(sink, traits::optional_value(attr)) &&
+ delimit_out(sink, d); // always do post-delimiting
}
// this int has no Attribute attached, it needs to have been
@@ -235,6 +246,17 @@
: primitive_generator<literal_int_generator<T, CharEncoding, Tag, Radix
, force_sign, no_attribute> >
{
+ private:
+ template <typename OutputIterator, typename Attribute>
+ static bool insert_int(OutputIterator& sink, Attribute const& attr)
+ {
+ return sign_inserter::call(sink, detail::is_zero(attr)
+ , detail::is_negative(attr), force_sign) &&
+ int_inserter<Radix, CharEncoding, Tag>::call(sink
+ , detail::absolute_value(attr));
+ }
+
+ public:
template <typename Context, typename Unused>
struct attribute
: mpl::if_c<no_attribute, unused_type, T>
@@ -259,14 +281,12 @@
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr) const
{
- if (n_ != attr)
+ if (!traits::has_optional_value(attr) ||
+ n_ != traits::optional_value(attr))
+ {
return false;
-
- return sign_inserter::call(sink, detail::is_zero(n_)
- , detail::is_negative(n_), force_sign) &&
- int_inserter<Radix, CharEncoding, Tag>::call(sink
- , detail::absolute_value(n_)) &&
- karma::delimit_out(sink, d); // always do post-delimiting
+ }
+ return insert_int(sink, n_) && delimit_out(sink, d);
}
// A int_(1) without any associated attribute just emits its
@@ -275,11 +295,7 @@
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, unused_type) const
{
- return sign_inserter::call(sink, detail::is_zero(n_)
- , detail::is_negative(n_), force_sign) &&
- int_inserter<Radix, CharEncoding, Tag>::call(sink
- , detail::absolute_value(n_)) &&
- karma::delimit_out(sink, d); // always do post-delimiting
+ return insert_int(sink, n_) && delimit_out(sink, d);
}
template <typename Context>
Modified: trunk/boost/spirit/home/karma/numeric/real.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/real.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/real.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -173,8 +173,11 @@
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr) const
{
+ if (!traits::has_optional_value(attr))
+ return false; // fail if it's an uninitialized optional
+
typedef real_inserter<T, Policies, CharEncoding, Tag> inserter_type;
- return inserter_type::call(sink, attr, p_) &&
+ return inserter_type::call(sink, traits::optional_value(attr), p_) &&
karma::delimit_out(sink, d); // always do post-delimiting
}
@@ -227,8 +230,11 @@
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr) const
{
- if (n_ != attr)
+ if (!traits::has_optional_value(attr) ||
+ n_ != traits::optional_value(attr))
+ {
return false;
+ }
typedef real_inserter<T, Policies, CharEncoding, Tag> inserter_type;
return inserter_type::call(sink, n_, p_) &&
Modified: trunk/boost/spirit/home/karma/numeric/uint.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/uint.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/uint.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -241,8 +241,12 @@
generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr)
{
- return int_inserter<Radix, CharEncoding, Tag>::call(sink, attr) &&
- karma::delimit_out(sink, d); // always do post-delimiting
+ if (!traits::has_optional_value(attr))
+ return false; // fail if it's an uninitialized optional
+
+ return int_inserter<Radix, CharEncoding, Tag>::
+ call(sink, traits::optional_value(attr)) &&
+ delimit_out(sink, d); // always do post-delimiting
}
// this int has no Attribute attached, it needs to have been
@@ -297,11 +301,13 @@
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr) const
{
- if (n_ != attr)
+ if (!traits::has_optional_value(attr) ||
+ n_ != traits::optional_value(attr))
+ {
return false;
-
+ }
return int_inserter<Radix, CharEncoding, Tag>::call(sink, n_) &&
- karma::delimit_out(sink, d); // always do post-delimiting
+ delimit_out(sink, d); // always do post-delimiting
}
// A uint(1U) without any associated attribute just emits its
@@ -311,7 +317,7 @@
, unused_type) const
{
return int_inserter<Radix, CharEncoding, Tag>::call(sink, n_) &&
- karma::delimit_out(sink, d); // always do post-delimiting
+ delimit_out(sink, d); // always do post-delimiting
}
template <typename Context>
Modified: trunk/boost/spirit/home/karma/stream/stream.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/stream/stream.hpp (original)
+++ trunk/boost/spirit/home/karma/stream/stream.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -126,9 +126,12 @@
OutputIterator, Char, CharEncoding, Tag
> sink_device;
+ if (!traits::has_optional_value(attr))
+ return false;
+
// use existing operator<<()
boost::iostreams::stream<sink_device> ostr(sink);
- ostr << attr << std::flush;
+ ostr << traits::optional_value(attr) << std::flush;
if (ostr.good())
return karma::delimit_out(sink, d); // always do post-delimiting
@@ -153,10 +156,13 @@
output_iterator, Char, CharEncoding, Tag
> sink_device;
+ if (!traits::has_optional_value(attr))
+ return false;
+
// use existing operator<<()
boost::iostreams::stream<sink_device> ostr(sink);
ostr.imbue(sink.get_ostream().getloc());
- ostr << attr << std::flush;
+ ostr << traits::optional_value(attr) << std::flush;
if (ostr.good())
return karma::delimit_out(sink, d); // always do post-delimiting
Modified: trunk/boost/spirit/home/karma/string/lit.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/string/lit.hpp (original)
+++ trunk/boost/spirit/home/karma/string/lit.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -91,8 +91,12 @@
generate(OutputIterator& sink, Context& /*ctx*/, Delimiter const& d,
Attribute const& attr)
{
+ if (!traits::has_optional_value(attr))
+ return false;
+
return
- karma::detail::string_generate(sink, attr, char_encoding(), Tag()) &&
+ karma::detail::string_generate(sink
+ , traits::optional_value(attr), char_encoding(), Tag()) &&
karma::delimit_out(sink, d); // always do post-delimiting
}
@@ -148,6 +152,9 @@
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr) const
{
+ if (!traits::has_optional_value(attr))
+ return false;
+
// fail if attribute isn't matched my immediate literal
using spirit::traits::get_c_string;
if (!detail::string_compare(get_c_string(attr), get_c_string(str_)
@@ -207,6 +214,9 @@
bool generate(OutputIterator& sink, Context&, Delimiter const& d
, Attribute const& attr) const
{
+ if (!traits::has_optional_value(attr))
+ return false;
+
// fail if attribute isn't matched my immediate literal
using spirit::traits::get_c_string;
if (!detail::string_compare(get_c_string(attr), get_c_string(str_)))
Modified: trunk/boost/spirit/home/support/container.hpp
==============================================================================
--- trunk/boost/spirit/home/support/container.hpp (original)
+++ trunk/boost/spirit/home/support/container.hpp 2009-09-15 12:59:15 EDT (Tue, 15 Sep 2009)
@@ -183,6 +183,41 @@
}
///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ T const& optional_value(T const& v)
+ {
+ return v;
+ }
+
+ template <typename T>
+ T const& optional_value(boost::optional<T> const& v)
+ {
+ return boost::get<T>(v);
+ }
+
+ inline unused_type optional_value(unused_type)
+ {
+ return unused;
+ }
+
+ template <typename T>
+ bool has_optional_value(T const&)
+ {
+ return true;
+ }
+
+ template <typename T>
+ bool has_optional_value(boost::optional<T> const& v)
+ {
+ return v;
+ }
+
+ inline bool has_optional_value(unused_type)
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
template <typename Container, typename T>
inline void push_back(Container& c, T const& val)
{
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