Boost logo

Boost-Commit :

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&lt;<classname>optional</classname>&lt;T&gt;&nbsp;&gt; (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&lt;T&gt;</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&lt;T&gt;</template-arg>
- </specialization>
-
- <purpose>Evaluate an InputIterator sequence.</purpose>
-
- <typedef name="result_type">
- <type>optional&lt;T&gt;</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&lt;T&gt;</code> containing the result of the last successful iterator dereference,
- or an uninitalized <code>optional&lt;T&gt;</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>&lt;T&gt;</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>(&amp;sum);
 sig.<methodname>connect</methodname>(&amp;difference);
 
-std::cout &lt;&lt; sig(5, 3) &lt;&lt; std::endl;
+std::cout &lt;&lt; *sig(5, 3) &lt;&lt; std::endl;
 </programlisting>
 </entry>
 <entry>
@@ -445,7 +445,7 @@
 sig.<methodname>connect</methodname>(&amp;sum);
 sig.<methodname>connect</methodname>(&amp;difference);
 
-std::cout &lt;&lt; sig(5, 3) &lt;&lt; std::endl;
+std::cout &lt;&lt; *sig(5, 3) &lt;&lt; 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));
 


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