[libsigc++2] Accumulators: Allow return types that are different to the signal's.



commit 5d6c8e1cf5825c58828056d78a4505158a6dc734
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Dec 29 13:25:56 2009 +0100

    Accumulators: Allow return types that are different to the signal's.
    
    * sigc++/macros/signal.h.m4: signal_emit*: Correct the slot_iterator_buf_type
    and slot_reverse_iterator_buf_type typedefs to allow accumulators with
    return types that are different to the signal's return type.
    * tests/Makefile.am: Reenable test_accumulated, so we can test the fix.
    It should be manually disabled if building on AIX (if the AIX problem cannot
    be fixed properly).
    * tests/test_accumulated.cc: Add an accumulator with a return type that is
    different to the signal's return type. In this case it's a vector listing
    all results.
    Bug #586436.

 ChangeLog                 |   15 +++++++++++++++
 sigc++/macros/signal.h.m4 |    4 ++--
 tests/Makefile.am         |    8 +++-----
 tests/test_accumulated.cc |   41 +++++++++++++++++++++++++++++++++++++++--
 4 files changed, 59 insertions(+), 9 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7861141..570061e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-12-29  Krzysztof KosiÅ?ski  <tweenk pl gmail com>
+
+  Accumulators: Allow return types that are different to the signal's.
+	
+	* sigc++/macros/signal.h.m4: signal_emit*: Correct the slot_iterator_buf_type 
+	and slot_reverse_iterator_buf_type typedefs to allow accumulators with 
+	return types that are different to the signal's return type.
+	* tests/Makefile.am: Reenable test_accumulated, so we can test the fix.
+	It should be manually disabled if building on AIX (if the AIX problem cannot 
+	be fixed properly).
+	* tests/test_accumulated.cc: Add an accumulator with a return type that is 
+	different to the signal's return type. In this case it's a vector listing 
+	all results.
+	Bug #586436.
+
 2009-12-27  Daniel Elstner  <daniel kitta gmail com>
 
 	Disable collaboration graphs in documentation
diff --git a/sigc++/macros/signal.h.m4 b/sigc++/macros/signal.h.m4
index cc03a9e..6c72b29 100644
--- a/sigc++/macros/signal.h.m4
+++ b/sigc++/macros/signal.h.m4
@@ -31,8 +31,8 @@ struct signal_emit$1
   typedef signal_emit$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)> self_type;
   typedef typename T_accumulator::result_type result_type;
   typedef slot<LIST(T_return, LOOP(T_arg%1, $1))> slot_type;
-  typedef internal::slot_iterator_buf<self_type> slot_iterator_buf_type;
-  typedef internal::slot_reverse_iterator_buf<self_type> slot_reverse_iterator_buf_type;
+  typedef internal::slot_iterator_buf<self_type, T_return> slot_iterator_buf_type;
+  typedef internal::slot_reverse_iterator_buf<self_type, T_return> slot_reverse_iterator_buf_type;
   typedef signal_impl::const_iterator_type iterator_type;
 
 ifelse($1,0,,[dnl
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9ae85c5..c26d471 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -21,6 +21,7 @@ LDADD       = $(top_builddir)/sigc++/libsigc-$(SIGCXX_API_VERSION).la
 
 check_PROGRAMS =			\
 	test_accum_iter			\
+	test_accumulated		\
 	test_bind			\
 	test_bind_ref			\
 	test_bind_return		\
@@ -47,6 +48,7 @@ check_PROGRAMS =			\
 TESTS = $(check_PROGRAMS)
 
 test_accum_iter_SOURCES			= test_accum_iter.cc
+test_accumulated_SOURCES = test_accumulated.cc
 test_bind_SOURCES			= test_bind.cc
 test_bind_ref_SOURCES			= test_bind_ref.cc
 test_bind_return_SOURCES		= test_bind_return.cc
@@ -72,9 +74,5 @@ test_trackable_SOURCES			= test_trackable.cc
 
 # Disabled: test_lambda - The Tru64 compiler can't build this when not using
 #  -std strict_ansi -model ansi, so let's not worry about it.
-# Disabled: test_accumulated - The AIX xlC compiler can't build this. It says 
-#  xlC_r  -I. -I. -I.. -I.. -I..    -AA -c -o test_accumulated.o test_accumulated.cc
-#  "../sigc++/signal.h", line 534.39: 1540-1110 (S) The referenced type
-#  "sigc::internal::signal_emit1" contains a circular reference back to ""
 
-dist_noinst_DATA = test_accumulated.cc test_lambda.cc
+dist_noinst_DATA = test_lambda.cc
diff --git a/tests/test_accumulated.cc b/tests/test_accumulated.cc
index 24e5f2c..e20ead6 100644
--- a/tests/test_accumulated.cc
+++ b/tests/test_accumulated.cc
@@ -8,6 +8,7 @@
 #include <sigc++/functors/ptr_fun.h>
 #include <sigc++/functors/mem_fun.h>
 #include <iostream>
+#include <vector>
 
 SIGC_USING_STD(cout)
 SIGC_USING_STD(endl)
@@ -26,6 +27,20 @@ struct arithmetic_mean_accumulator
     }
 };
 
+template<class Ret>
+struct vector_accumulator
+{
+  typedef std::vector<Ret> result_type;
+  template<typename T_iterator>
+  result_type operator()(T_iterator first, T_iterator last) const
+    {
+      result_type vec;
+      for (; first != last; ++first)
+        vec.push_back(*first);
+      return vec;
+    }
+};
+
 int foo(int i)    { std::cout << "foo: " << 3*i+1 << std::endl; return 3*i+1;}
 int bar(double i) { std::cout << "bar: " << 5*int(i)-3 << std::endl; return 5*int(i)-3;}
 
@@ -37,14 +52,36 @@ struct A : public sigc::trackable
 int main()
 {
    sigc::signal<int,int>::accumulated<arithmetic_mean_accumulator> sig;
+   sigc::signal<int,int>::accumulated<vector_accumulator<int> > sig_vec;
 
    std::cout << "Result (empty slot list): " << sig(0) << std::endl;
+   std::cout << "Vector result (empty slot list): "
+             << (sig_vec(0).empty() ? "empty" : "not empty") << std::endl;
 
    A a;
    sig.connect(sigc::ptr_fun1(&foo));
    sig.connect(sigc::mem_fun1(&a, &A::foo));
    sig.connect(sigc::ptr_fun1(&bar));
+   
+   sig_vec.connect(sigc::ptr_fun1(&foo));
+   sig_vec.connect(sigc::mem_fun1(&a, &A::foo));
+   sig_vec.connect(sigc::ptr_fun1(&bar));
 
-   std::cout << "Result (i=1): " << sig(1) << std::endl;
-   std::cout << "Result (i=11): " << sig(11) << std::endl;
+   std::cout << "Mean accumulator: Result (i=1): " << sig(1) << std::endl;
+   std::cout << "Mean accumulator: Plain Result (i=11): " << sig(11) << std::endl;
+   
+   std::vector<int> res1 = sig_vec(1);
+   std::vector<int> res3 = sig_vec(3);
+   
+   std::cout << "Vector accumulator: Result (i=1): ";
+   for (std::vector<int>::iterator i = res1.begin(); i != res1.end(); ++i)
+     std::cout << *i << " ";
+   std::cout << std::endl;
+   
+   std::cout << "Vector accumulator: Result (i=3): ";
+   for (std::vector<int>::iterator i = res3.begin(); i != res3.end(); ++i)
+     std::cout << *i << " ";
+   std::cout << std::endl;
+   
+   return 0;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]