diff options
author | Martin Schulze <mschulze@cvs.gnome.org> | 2004-05-30 13:11:26 +0000 |
---|---|---|
committer | Martin Schulze <mschulze@src.gnome.org> | 2004-05-30 13:11:26 +0000 |
commit | 13bfa6e9967e780c08c448660e89501794685242 (patch) | |
tree | f19b9c0a61bf03b19412b19036d474e9469ce422 | |
parent | 8ced25f2cf1e7405e672849feb90cd20bc2c66fa (diff) | |
download | sigc++-13bfa6e9967e780c08c448660e89501794685242.tar.gz |
Bump version number to 2.0.3. Add ChangeLog summary for version 2.0.3. Fixlibsigc++-2.0.3
2004-05-30 Martin Schulze <mschulze@cvs.gnome.org>
* configure.ac: Bump version number to 2.0.3.
* NEWS: Add ChangeLog summary for version 2.0.3.
* sigc++/macros/signal.h.m4: Fix segfault on emission of unconnected sig
nal.
* tests/test_signal.cc, tests/test_accumulated.cc: Emit unconnected sign
al.
* sigc++/macros/object_slot.h.m4: Suppress compiler warning at
dynamic_cast<>-test (tested by Christof Petig/Timothy M. Shead).
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | sigc++/macros/object_slot.h.m4 | 2 | ||||
-rw-r--r-- | sigc++/macros/signal.h.m4 | 39 | ||||
-rw-r--r-- | tests/test_accumulated.cc | 4 | ||||
-rw-r--r-- | tests/test_signal.cc | 6 |
7 files changed, 53 insertions, 16 deletions
@@ -1,3 +1,12 @@ +2004-05-30 Martin Schulze <mschulze@cvs.gnome.org> + + * configure.ac: Bump version number to 2.0.3. + * NEWS: Add ChangeLog summary for version 2.0.3. + * sigc++/macros/signal.h.m4: Fix segfault on emission of unconnected signal. + * tests/test_signal.cc, tests/test_accumulated.cc: Emit unconnected signal. + * sigc++/macros/object_slot.h.m4: Suppress compiler warning at + dynamic_cast<>-test (tested by Christof Petig/Timothy M. Shead). + 2004-05-22 Martin Schulze <mschulze@cvs.gnome.org> * configure.ac: Bump version number to 2.0.2. @@ -17,6 +17,13 @@ This version of libsigc++ needs GNU g++ 3.2 or higher to compile. *** ChangeLog summary: +2.0.3: + +* Fix segfault on emission of unconnected signal. +* Test emission of unconnected signals in the test case. +* Suppress compiler warning at dynamic_cast<>-test for good. + (Help from Christof Petig and Timothy M. Shead.) + 2.0.2: * Suppress compiler warning in compatibility module at diff --git a/configure.ac b/configure.ac index 99b2897..727abbd 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ dnl This version stuff is just for the packaging section of the tool. dnl thus make format_package-0.0.1.tar.gz FP_MAJOR_VERSION=2 FP_MINOR_VERSION=0 -FP_MICRO_VERSION=2 +FP_MICRO_VERSION=3 FP_VERSION=$FP_MAJOR_VERSION.$FP_MINOR_VERSION.$FP_MICRO_VERSION dnl For automake. diff --git a/sigc++/macros/object_slot.h.m4 b/sigc++/macros/object_slot.h.m4 index a1bf73f..435444c 100644 --- a/sigc++/macros/object_slot.h.m4 +++ b/sigc++/macros/object_slot.h.m4 @@ -32,7 +32,7 @@ define([SLOT_MEM_FUN],[dnl template <LIST(class T_return, LOOP(class T_arg%1, $1), class T_obj1, class T_obj2)> inline Slot$1<LIST(T_return, LOOP(T_arg%1, $1))> slot($3 T_obj1& _A_obj, T_return (T_obj2::*_A_func)(LOOP(T_arg%1,$1)) $4) -{ dynamic_cast<$3 Object&>(_A_obj); +{ (void)dynamic_cast<$3 Object&>(_A_obj); // trigger compiler error if T_obj1 does not derive from SigC::Object return ::sigc::bound_mem_functor$1<LIST(T_return, T_obj2, LOOP(T_arg%1, $1))>(_A_obj, _A_func); } ]) diff --git a/sigc++/macros/signal.h.m4 b/sigc++/macros/signal.h.m4 index d44f249..7146f42 100644 --- a/sigc++/macros/signal.h.m4 +++ b/sigc++/macros/signal.h.m4 @@ -65,12 +65,16 @@ FOR(1, $1,[ */ static result_type emit(LIST(signal_impl* impl, LOOP(typename type_trait<T_arg%1>::take _A_a%1, $1))) { + T_accumulator accumulator; + + if (!impl) + return accumulator(slot_iterator_buf_type(), slot_iterator_buf_type()); + signal_exec exec(impl); self_type self ifelse($1,0,,[(LOOP(_A_a%1, $1))]); - T_accumulator accumulator; - return accumulator(slot_iterator_buf_type(impl->slots_.begin(), self), - slot_iterator_buf_type(impl->slots_.end(), self)); + return accumulator(slot_iterator_buf_type(impl->slots_.begin(), &self), + slot_iterator_buf_type(impl->slots_.end(), &self)); } dnl FOR(1, $1,[ @@ -102,7 +106,7 @@ FOR(1, $1,[ */ static result_type emit(LIST(signal_impl* impl, LOOP(typename type_trait<T_arg%1>::take _A_a%1, $1))) { - if (impl->slots_.empty()) return T_return(); + if (!impl || impl->slots_.empty()) return T_return(); iterator_type it = impl->slots_.begin(); for (; it != impl->slots_.end(); ++it) if (!it->empty() && !it->blocked()) break; @@ -145,7 +149,7 @@ FOR(1, $1,[ */ static result_type emit(LIST(signal_impl* impl, LOOP(typename type_trait<T_arg%1>::take _A_a%1, $1))) { - if (impl->slots_.empty()) return; + if (!impl || impl->slots_.empty()) return; signal_exec exec(impl); for (iterator_type it = impl->slots_.begin(); it != impl->slots_.end(); ++it) @@ -702,14 +706,17 @@ struct slot_iterator_buf typedef signal_impl::const_iterator_type iterator_type; - slot_iterator_buf(const iterator_type& i, const emitter_type& c) + slot_iterator_buf() + : c_(0), invoked_(false) {} + + slot_iterator_buf(const iterator_type& i, const emitter_type* c) : i_(i), c_(c), invoked_(false) {} result_type operator*() const { if (!i_->empty() && !i_->blocked() && !invoked_) { - r_ = c_(static_cast<const slot_type&>(*i_)); + r_ = (*c_)(static_cast<const slot_type&>(*i_)); invoked_ = true; } return r_; @@ -746,14 +753,17 @@ struct slot_iterator_buf } bool operator == (const slot_iterator_buf& other) const - { return i_ == other.i_; } + { return (!c_ || (i_ == other.i_)); } /* If '!c_' the iterators are empty. + * Unfortunately, empty stl iterators are not equal. + * We are forcing equality so that 'first==last' + * in the accumulator's emit function yields true. */ bool operator != (const slot_iterator_buf& other) const - { return i_ != other.i_; } + { return (c_ && (i_ != other.i_)); } private: iterator_type i_; - const emitter_type& c_; + const emitter_type* c_; mutable result_type r_; mutable bool invoked_; }; @@ -773,14 +783,17 @@ struct slot_iterator_buf<T_emitter, void> typedef signal_impl::const_iterator_type iterator_type; - slot_iterator_buf(const iterator_type& i, const emitter_type& c) + slot_iterator_buf() + : c_(0), invoked_(false) {} + + slot_iterator_buf(const iterator_type& i, const emitter_type* c) : i_(i), c_(c), invoked_(false) {} void operator*() const { if (!i_->empty() && !i_->blocked() && !invoked_) { - c_(static_cast<const slot_type&>(*i_)); + (*c_)(static_cast<const slot_type&>(*i_)); invoked_ = true; } } @@ -823,7 +836,7 @@ struct slot_iterator_buf<T_emitter, void> private: iterator_type i_; - const emitter_type& c_; + const emitter_type* c_; mutable bool invoked_; }; diff --git a/tests/test_accumulated.cc b/tests/test_accumulated.cc index 38716c7..ecf96e5 100644 --- a/tests/test_accumulated.cc +++ b/tests/test_accumulated.cc @@ -19,7 +19,7 @@ struct arithmetic_mean_accumulator int n_ = 0; for (; first != last; ++first, ++n_) value_ += *first; - return value_ / n_; + return (n_ ? value_ / n_ : -1); // empty slot list <=> n_==0 } }; @@ -35,6 +35,8 @@ int main() { sigc::signal<int,int>::accumulated<arithmetic_mean_accumulator> sig; + std::cout << "Result (empty slot list): " << sig(0) << std::endl; + A a; sig.connect(sigc::ptr_fun1(&foo)); sig.connect(sigc::mem_fun1(&a, &A::foo)); diff --git a/tests/test_signal.cc b/tests/test_signal.cc index b78bfea..f8e7446 100644 --- a/tests/test_signal.cc +++ b/tests/test_signal.cc @@ -21,7 +21,13 @@ struct A : public sigc::trackable int main() { + // signal sigc::signal<int,int> sig; + + // emit empty signal + sig(0); + + // connect some slots before emitting & test auto-disconnection { A a; sig.connect(sigc::ptr_fun1(&foo)); |