$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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)
     {