Boost logo

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