$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r49076 - in sandbox/thread_safe_signals/trunk: boost boost/signals2 boost/signals2/detail libs/signals2/doc libs/signals2/doc/reference libs/signals2/test
From: fmhess_at_[hidden]
Date: 2008-09-30 16:28:24
Author: fmhess
Date: 2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
New Revision: 49076
URL: http://svn.boost.org/trac/boost/changeset/49076
Log:
Added signals2::optional_last_value, and made it the default
combiner for signals.  It is preferrable to last_value since it
never throws.
Added:
   sandbox/thread_safe_signals/trunk/boost/signals2/optional_last_value.hpp   (contents, props changed)
   sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/optional_last_value.xml   (contents, props changed)
Text files modified: 
   sandbox/thread_safe_signals/trunk/boost/signals2.hpp                         |     1                                         
   sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp  |     4 +-                                      
   sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp              |    17 ++------------                          
   sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp                  |     4 +-                                      
   sandbox/thread_safe_signals/trunk/libs/signals2/doc/Makefile                 |     1                                         
   sandbox/thread_safe_signals/trunk/libs/signals2/doc/faq.xml                  |    12 ++++++---                               
   sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/last_value.xml |    46 ++++++++------------------------------- 
   sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/reference.xml  |    15 ++++++------                            
   sandbox/thread_safe_signals/trunk/libs/signals2/doc/tutorial.xml             |     7 +++--                                   
   sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp       |    21 +++++++++++++++++                       
   sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_test.cpp         |     2                                         
   11 files changed, 60 insertions(+), 70 deletions(-)
Modified: sandbox/thread_safe_signals/trunk/boost/signals2.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2.hpp	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -9,4 +9,5 @@
 
 #include <boost/signals2/deconstruct_ptr.hpp>
 #include <boost/signals2/dummy_mutex.hpp>
+#include <boost/signals2/last_value.hpp>
 #include <boost/signals2/signal.hpp>
Modified: sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -18,10 +18,10 @@
 #define BOOST_WEAK_SIGNAL_CLASS_NAME BOOST_PP_CAT(weak_, BOOST_SIGNAL_CLASS_NAME)
 #define BOOST_SIGNAL_IMPL_CLASS_NAME BOOST_PP_CAT(BOOST_SIGNAL_CLASS_NAME, _impl)
 
-// typename R, typename T1, typename T2, ..., typename TN, typename Combiner = last_value<R>, ...
+// typename R, typename T1, typename T2, ..., typename TN, typename Combiner = optional_last_value<R>, ...
 #define BOOST_SIGNAL_TEMPLATE_DEFAULTED_DECL \
   BOOST_SIGNAL_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS_NUM_ARGS), \
-  typename Combiner = last_value<R>, \
+  typename Combiner = optional_last_value<R>, \
   typename Group = int, \
   typename GroupCompare = std::less<Group>, \
   typename SlotFunction = BOOST_FUNCTION_N_DECL(BOOST_SIGNALS_NUM_ARGS), \
Modified: sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -24,18 +24,7 @@
     public:
       virtual const char* what() {return "boost::no_slots_error";}
     };
-    namespace last_value_detail {
-      template<typename T>
-      T default_construct(const T *resolver)
-      {
-        throw no_slots_error();
-      }
-      template<typename T>
-      optional<T> default_construct(const optional<T> *resolver)
-      {
-        return optional<T>();
-      }
-    }
+
     template<typename T>
     struct last_value {
       typedef T result_type;
@@ -46,7 +35,7 @@
         T * resolver = 0;
         if(first == last)
         {
-          return last_value_detail::default_construct(resolver);
+          throw no_slots_error();
         }
         optional<T> value;
         while (first != last)
@@ -55,7 +44,7 @@
           ++first;
         }
         if(value) return value.get();
-        return last_value_detail::default_construct(resolver);
+        throw no_slots_error();
       }
     };
 
Added: sandbox/thread_safe_signals/trunk/boost/signals2/optional_last_value.hpp
==============================================================================
--- (empty file)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/optional_last_value.hpp	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -0,0 +1,61 @@
+// optional_last_value function object (documented as part of Boost.Signals2)
+
+// Copyright Frank Mori Hess 2007-2008.
+// Copyright Douglas Gregor 2001-2003.
+// Distributed under the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP
+#define BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP
+
+#include <boost/optional.hpp>
+
+namespace boost {
+  namespace signals2 {
+    template<typename T>
+      class optional_last_value
+    {
+    public:
+      typedef optional<T> result_type;
+
+      template<typename InputIterator>
+        optional<T> operator()(InputIterator first, InputIterator last) const
+      {
+        optional<T> value;
+        while (first != last)
+        {
+          value = *first;
+          ++first;
+        }
+        return value;
+      }
+    };
+
+    template<>
+      class optional_last_value<void>
+    {
+#ifdef BOOST_NO_VOID_RETURNS
+      struct unusable {};
+    public:
+      typedef unusable result_type;
+#else
+    public:
+      typedef void result_type;
+#endif // BOOST_NO_VOID_RETURNS
+      template<typename InputIterator>
+        result_type operator()(InputIterator first, InputIterator last) const
+      {
+        while (first != last)
+        {
+          *first;
+          ++first;
+        }
+        return result_type();
+      }
+    };
+  } // namespace signals2
+} // namespace boost
+#endif // BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP
Modified: sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp	(original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/signal.hpp	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -19,7 +19,7 @@
 #include <boost/assert.hpp>
 #include <boost/config.hpp>
 #include <boost/function.hpp>
-#include <boost/signals2/last_value.hpp>
+#include <boost/signals2/optional_last_value.hpp>
 #include <boost/preprocessor/arithmetic.hpp>
 #include <boost/preprocessor/cat.hpp>
 #include <boost/preprocessor/iteration.hpp>
@@ -46,7 +46,7 @@
   namespace signals2
   {
     template<typename Signature,
-      typename Combiner = last_value<typename boost::function_traits<Signature>::result_type>,
+      typename Combiner = optional_last_value<typename boost::function_traits<Signature>::result_type>,
       typename Group = int,
       typename GroupCompare = std::less<Group>,
       typename SlotFunction = function<Signature>,
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/doc/Makefile
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/doc/Makefile	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/doc/Makefile	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -16,6 +16,7 @@
         reference/dummy_mutex.xml \
         reference/last_value.xml \
         reference/mutex.xml \
+	reference/optional_last_value.xml \
         reference/postconstructible.xml \
         reference/predestructible.xml \
         reference/reference.xml \
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/doc/faq.xml
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/doc/faq.xml	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/doc/faq.xml	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -57,10 +57,14 @@
           </listitem>
           <listitem>
             <para>
-              The <classname>last_value</classname> combiner throws an exception instead of producing undefined
-              behavior when used with no slots connected (except for its specializations which do not require any
-              slots to be connected).  An additional specialization
-              last_value<<classname>optional</classname><T> > (which does not throw) has been added.
+              The <classname>optional_last_value</classname> has replaced <classname>last_value</classname>
+              as the default combiner for signals.
+            </para>
+            <para>
+              The <classname>last_value</classname> combiner is still provided, and it
+              throws an exception instead of requiring at least one slot to be connected
+              on signal invocation (except for its void specialization which does not require any
+              slots to be connected).
             </para>
           </listitem>
           <listitem>
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/last_value.xml
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/last_value.xml	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/last_value.xml	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -12,6 +12,15 @@
         <purpose>Evaluate an <conceptname>InputIterator</conceptname> sequence and return the
         last value in the sequence.</purpose>
 
+        <description>
+          <para>
+            The <code>last_value</code> class was the default <code>Combiner</code> template parameter
+            type for signals in the original Signals library.
+            Signals2 uses <classname>optional_last_value</classname> as the default, which
+            does not throw.
+          </para>
+        </description>
+
         <typedef name="result_type"><type>T</type></typedef>
 
         <method-group name="invocation">
@@ -31,7 +40,7 @@
               </para></effects>
             <returns><para>The result of the last successful iterator dereference.</para></returns>
             <throws><para><classname>no_slots_error</classname> if no iterators were successfully dereferenced,
-            unless the template type of <code>last_value</code> is <code>void</code> or <code>optional<T></code>.</para></throws>
+            unless the template type of <code>last_value</code> is <code>void</code>.</para></throws>
           </method>
         </method-group>
       </class>
@@ -67,41 +76,6 @@
         </method-group>
       </class-specialization>
 
-      <class-specialization name="last_value">
-        <template>
-          <template-type-parameter name="T"/>
-        </template>
-        <specialization>
-          <template-arg>optional<T></template-arg>
-        </specialization>
-
-        <purpose>Evaluate an InputIterator sequence.</purpose>
-
-        <typedef name="result_type">
-          <type>optional<T></type>
-        </typedef>
-
-        <method-group name="invocation">
-          <method name="operator()" cv="const">
-            <template>
-              <template-type-parameter name="InputIterator"/>
-            </template>
-            <type>result_type</type>
-            <parameter name="first">
-              <paramtype>InputIterator</paramtype>
-            </parameter>
-            <parameter name="last">
-              <paramtype>InputIterator</paramtype>
-            </parameter>
-
-            <effects><para>Attempts to dereference every iterator in the sequence <computeroutput>[first, last)</computeroutput>.
-              </para></effects>
-            <returns><para>An <code>optional<T></code> containing the result of the last successful iterator dereference,
-            or an uninitalized <code>optional<T></code> if no iterators were successfully dereferenced.</para></returns>
-          </method>
-        </method-group>
-      </class-specialization>
-
       <class name="no_slots_error">
         <inherit access="public"><classname>std::exception</classname></inherit>
         <purpose>Indicates a combiner was unable to synthesize a return value.</purpose>
Added: sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/optional_last_value.xml
==============================================================================
--- (empty file)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/optional_last_value.xml	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE header PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
+  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+<header name="boost/signals2/optional_last_value.hpp" last-revision="$Date: 2007-03-06 16:51:55 -0500 (Tue, 06 Mar 2007) $">
+  <namespace name="boost">
+    <namespace name="signals2">
+      <class name="optional_last_value">
+        <template>
+          <template-type-parameter name="T"/>
+        </template>
+
+        <purpose>Evaluate an <conceptname>InputIterator</conceptname> sequence and return
+          a boost::optional which contains the last value in the sequence, or an
+          empty boost::optional if the sequence was empty.</purpose>
+
+        <typedef name="result_type"><type><classname>boost::optional</classname><T></type></typedef>
+
+        <method-group name="invocation">
+          <method name="operator()" cv="const">
+            <template>
+              <template-type-parameter name="InputIterator"/>
+            </template>
+            <type>result_type</type>
+            <parameter name="first">
+              <paramtype>InputIterator</paramtype>
+            </parameter>
+            <parameter name="last">
+              <paramtype>InputIterator</paramtype>
+            </parameter>
+
+            <effects><para>Attempts to dereference every iterator in the sequence <computeroutput>[first, last)</computeroutput>.
+              </para></effects>
+            <returns>
+              <para>
+                The result of the last successful iterator dereference, wrapped in a <classname>boost::optional</classname>.
+                The returned <code>optional</code> will be empty if no iterators were dereferenced.
+              </para>
+            </returns>
+            <throws><para>Does not throw.</para></throws>
+          </method>
+        </method-group>
+      </class>
+
+      <class-specialization name="optional_last_value">
+        <template/>
+        <specialization>
+          <template-arg>void</template-arg>
+        </specialization>
+
+        <purpose>Evaluate an InputIterator sequence.</purpose>
+
+        <typedef name="result_type">
+          <type><emphasis>unspecified</emphasis></type>
+        </typedef>
+
+        <method-group name="invocation">
+          <method name="operator()" cv="const">
+            <template>
+              <template-type-parameter name="InputIterator"/>
+            </template>
+            <type>result_type</type>
+            <parameter name="first">
+              <paramtype>InputIterator</paramtype>
+            </parameter>
+            <parameter name="last">
+              <paramtype>InputIterator</paramtype>
+            </parameter>
+
+            <effects><para>Attempts to dereference every iterator in the sequence <computeroutput>[first, last)</computeroutput>.
+              </para></effects>
+          </method>
+        </method-group>
+      </class-specialization>
+    </namespace>
+  </namespace>
+</header>
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/reference.xml
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/reference.xml	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/doc/reference/reference.xml	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -10,16 +10,17 @@
     </para>
   </header>
 
-  <xi:include href="signal_header.xml"/>
-  <xi:include href="signal_base.xml"/>
-  <xi:include href="slot.xml"/>
-  <xi:include href="slot_base.xml"/>
   <xi:include href="connection.xml"/>
-  <xi:include href="shared_connection_block.xml"/>
+  <xi:include href="deconstruct_ptr.xml"/>
+  <xi:include href="dummy_mutex.xml"/>
   <xi:include href="last_value.xml"/>
   <xi:include href="mutex.xml"/>
-  <xi:include href="dummy_mutex.xml"/>
-  <xi:include href="deconstruct_ptr.xml"/>
+  <xi:include href="optional_last_value.xml"/>
   <xi:include href="postconstructible.xml"/>
   <xi:include href="predestructible.xml"/>
+  <xi:include href="shared_connection_block.xml"/>
+  <xi:include href="signal_header.xml"/>
+  <xi:include href="signal_base.xml"/>
+  <xi:include href="slot.xml"/>
+  <xi:include href="slot_base.xml"/>
 </library-reference>
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/doc/tutorial.xml
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/doc/tutorial.xml	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/doc/tutorial.xml	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -428,7 +428,7 @@
 sig.<methodname>connect</methodname>(&sum);
 sig.<methodname>connect</methodname>(&difference);
 
-std::cout << sig(5, 3) << std::endl;
+std::cout << *sig(5, 3) << std::endl;
 </programlisting>
 </entry>
 <entry>
@@ -445,7 +445,7 @@
 sig.<methodname>connect</methodname>(&sum);
 sig.<methodname>connect</methodname>(&difference);
 
-std::cout << sig(5, 3) << std::endl;
+std::cout << *sig(5, 3) << std::endl;
 </programlisting>
 </entry>
             </row>
@@ -457,7 +457,8 @@
 default behavior of a signal that has a return type
 (<code>float</code>, the first template argument given to the
 <code><classname>boost::signals2::signal</classname></code> class template) is to call all slots and
-then return the result returned by the last slot called. This
+then return a <classname>boost::optional</classname> containing
+the result returned by the last slot called. This
 behavior is admittedly silly for this example, because slots have
 no side effects and the result is the last slot connected.</para>
 <para>A more interesting signal result would be the maximum of the
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -149,7 +149,7 @@
 
   {
     signal_type s2;
-    s1.connect(signal_type::slot_type(s2));
+    s1.connect(s2);
     s2.connect(std::bind1st(std::multiplies<int>(), 2));
     s2.connect(std::bind1st(std::multiplies<int>(), -3));
 
@@ -188,6 +188,24 @@
   BOOST_CHECK(ec.count == 1);
 }
 
+static void test_default_combiner()
+{
+  boost::signals2::signal0<int> sig;
+  boost::optional<int> result;
+  result = sig();
+  BOOST_CHECK(!result);
+
+  sig.connect(make_int(0, 0));
+  result = sig();
+  BOOST_CHECK(result);
+  BOOST_CHECK(*result == 0);
+
+  sig.connect(make_int(1, 1));
+  result = sig();
+  BOOST_CHECK(result);
+  BOOST_CHECK(*result == 1);
+}
+
 int
 test_main(int, char* [])
 {
@@ -195,5 +213,6 @@
   test_one_arg();
   test_signal_signal_connect();
   test_ref();
+  test_default_combiner();
   return 0;
 }
Modified: sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_test.cpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_test.cpp	(original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_test.cpp	2008-09-30 16:28:23 EDT (Tue, 30 Sep 2008)
@@ -147,7 +147,7 @@
 
   {
     signal_type s2;
-    s1.connect(signal_type::slot_type(s2));
+    s1.connect(s2);
     s2.connect(std::bind1st(std::multiplies<int>(), 2));
     s2.connect(std::bind1st(std::multiplies<int>(), -3));