1 dnl Copyright 2002, The libsigc++ Development Team
3 dnl This library is free software; you can redistribute it and/or
4 dnl modify it under the terms of the GNU Lesser General Public
5 dnl License as published by the Free Software Foundation; either
6 dnl version 2.1 of the License, or (at your option) any later version.
8 dnl This library is distributed in the hope that it will be useful,
9 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
10 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 dnl Lesser General Public License for more details.
13 dnl You should have received a copy of the GNU Lesser General Public
14 dnl License along with this library; if not, write to the Free Software
15 dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 include(template.macros.m4)
21 define([SIGNAL_EMIT_N],[dnl
22 /** Abstracts signal emission.
23 * This template implements the emit() function of signal$1.
24 * Template specializations are available to optimize signal
25 * emission when no accumulator is used, for example when the template
26 * argument @e T_accumulator is @p nil.
28 template <LIST(class T_return, LOOP(class T_arg%1, $1), class T_accumulator)>
31 typedef signal_emit$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)> self_type;
32 typedef typename T_accumulator::result_type result_type;
33 typedef slot<T_return(LIST(LOOP(T_arg%1, $1)))> slot_type;
34 typedef internal::slot_iterator_buf<self_type, T_return> slot_iterator_buf_type;
35 typedef internal::slot_reverse_iterator_buf<self_type, T_return> slot_reverse_iterator_buf_type;
36 typedef signal_impl::const_iterator_type iterator_type;
39 /** Instantiates the class.
40 * The parameters are stored in member variables. operator()() passes
41 * the values on to some slot.
44 signal_emit$1(LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)) ifelse($1,0,,[
45 : LOOP(_A_a%1_(_A_a%1), $1)]) {}
48 /** Invokes a slot.],[
49 /** Invokes a slot using the buffered parameter values.])
50 * @param _A_slot Some slot to invoke.
51 * @return The slot's return value.
53 T_return operator()(const slot_type& _A_slot) const
54 { return (sigc::internal::function_pointer_cast<typename slot_type::call_type>(_A_slot.rep_->call_))(LIST(_A_slot.rep_, LOOP(_A_a%1_, $1))); }
55 dnl T_return operator()(const slot_type& _A_slot) const
56 dnl { return _A_slot(LOOP(_A_a%1_, $1)); }
58 /** Executes a list of slots using an accumulator of type @e T_accumulator.dnl
60 * The arguments are buffered in a temporary instance of signal_emit$1.])
62 * @param _A_a%1 Argument to be passed on to the slots.])
63 * @return The accumulated return values of the slot invocations as processed by the accumulator.
65 static result_type emit(LIST(signal_impl* impl, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)))
67 T_accumulator accumulator;
70 return accumulator(slot_iterator_buf_type(), slot_iterator_buf_type());
72 signal_exec exec(impl);
73 temp_slot_list slots(impl->slots_);
75 self_type self ifelse($1,0,,[(LOOP(_A_a%1, $1))]);
76 return accumulator(slot_iterator_buf_type(slots.begin(), &self),
77 slot_iterator_buf_type(slots.end(), &self));
80 _DEPRECATE_IFDEF_START
81 /** Executes a list of slots using an accumulator of type @e T_accumulator in reverse order.dnl
83 * The arguments are buffered in a temporary instance of signal_emit$1.])
85 * @param _A_a%1 Argument to be passed on to the slots.])
86 * @return The accumulated return values of the slot invocations as processed by the accumulator.
88 * @deprecated This is apparently not useful, but please let us know if you need it.
90 static result_type emit_reverse(LIST(signal_impl* impl, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)))
92 T_accumulator accumulator;
95 return accumulator(slot_iterator_buf_type(), slot_iterator_buf_type());
97 signal_exec exec(impl);
98 temp_slot_list slots(impl->slots_);
100 self_type self ifelse($1,0,,[(LOOP(_A_a%1, $1))]);
101 return accumulator(slot_reverse_iterator_buf_type(slots.end(), &self),
102 slot_reverse_iterator_buf_type(slots.begin(), &self));
108 type_trait_take_t<T_arg%1> _A_a%1_;])
111 /** Abstracts signal emission.
112 * This template specialization implements an optimized emit()
113 * function for the case that no accumulator is used.
115 template <LIST(class T_return, LOOP(class T_arg%1, $1))>
116 struct signal_emit$1<LIST(T_return, LOOP(T_arg%1, $1), nil)>
118 typedef signal_emit$1<LIST(T_return, LOOP(T_arg%1, $1), nil) > self_type;
119 typedef T_return result_type;
120 typedef slot<T_return(LIST(LOOP(T_arg%1, $1)))> slot_type;
121 typedef signal_impl::const_iterator_type iterator_type;
122 typedef typename slot_type::call_type call_type;
124 /** Executes a list of slots using an accumulator of type @e T_accumulator.dnl
126 * The arguments are passed directly on to the slots.])
127 * The return value of the last slot invoked is returned.
128 * @param first An iterator pointing to the first slot in the list.
129 * @param last An iterator pointing to the last slot in the list.dnl
131 * @param _A_a%1 Argument to be passed on to the slots.])
132 * @return The return value of the last slot invoked.
134 static result_type emit(LIST(signal_impl* impl, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)))
136 if (!impl || impl->slots_.empty())
139 signal_exec exec(impl);
140 T_return r_ = T_return();
142 //Use this scope to make sure that "slots" is destroyed before "exec" is destroyed.
143 //This avoids a leak on MSVC++ - see http://bugzilla.gnome.org/show_bug.cgi?id=306249
145 temp_slot_list slots(impl->slots_);
146 auto it = slots.begin();
147 for (; it != slots.end(); ++it)
148 if (!it->empty() && !it->blocked()) break;
150 if (it == slots.end())
151 return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows:
153 r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
154 for (++it; it != slots.end(); ++it)
156 if (it->empty() || it->blocked())
158 r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
165 _DEPRECATE_IFDEF_START
166 /** Executes a list of slots using an accumulator of type @e T_accumulator in reverse order.dnl
168 * The arguments are passed directly on to the slots.])
169 * The return value of the last slot invoked is returned.
170 * @param first An iterator pointing to the first slot in the list.
171 * @param last An iterator pointing to the last slot in the list.dnl
173 * @param _A_a%1 Argument to be passed on to the slots.])
174 * @return The return value of the last slot invoked.
176 * @deprecated This is apparently not useful, but please let us know if you need it.
178 static result_type emit_reverse(LIST(signal_impl* impl, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)))
180 if (!impl || impl->slots_.empty())
183 signal_exec exec(impl);
184 T_return r_ = T_return();
186 //Use this scope to make sure that "slots" is destroyed before "exec" is destroyed.
187 //This avoids a leak on MSVC++ - see http://bugzilla.gnome.org/show_bug.cgi?id=306249
189 #ifndef SIGC_HAVE_SUN_REVERSE_ITERATOR
190 typedef std::reverse_iterator<signal_impl::iterator_type> reverse_iterator_type;
192 typedef std::reverse_iterator<signal_impl::iterator_type, std::random_access_iterator_tag,
193 slot_base, slot_base&, slot_base*, std::ptrdiff_t> reverse_iterator_type;
196 temp_slot_list slots(impl->slots_);
197 reverse_iterator_type it(slots.end());
198 for (; it != reverse_iterator_type(slots.begin()); ++it)
199 if (!it->empty() && !it->blocked()) break;
201 if (it == reverse_iterator_type(slots.begin()))
202 return T_return(); // note that 'T_return r_();' doesn't work => define 'r_' after this line and initialize as follows:
204 r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
205 for (++it; it != reverse_iterator_type(slots.begin()); ++it)
207 if (it->empty() || it->blocked())
209 r_ = (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
218 /** Abstracts signal emission.
219 * This template specialization implements an optimized emit()
220 * function for the case that no accumulator is used and the
221 * return type is @p void.
223 template <LOOP(class T_arg%1, $1)>
224 struct signal_emit$1<LIST(void, LOOP(T_arg%1, $1), nil)>
226 typedef signal_emit$1<LIST(void, LOOP(T_arg%1, $1), nil)> self_type;
227 typedef void result_type;
228 typedef slot<void(LIST(LOOP(T_arg%1, $1)))> slot_type;
229 typedef signal_impl::const_iterator_type iterator_type;
230 typedef ifelse($1,0,void (*call_type)(slot_rep*),typename slot_type::call_type call_type);
232 /** Executes a list of slots using an accumulator of type @e T_accumulator.dnl
234 * The arguments are passed directly on to the slots.])
235 * @param first An iterator pointing to the first slot in the list.
236 * @param last An iterator pointing to the last slot in the list.dnl
238 * @param _A_a%1 Argument to be passed on to the slots.])
240 static result_type emit(LIST(signal_impl* impl, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)))
242 if (!impl || impl->slots_.empty()) return;
243 signal_exec exec(impl);
244 temp_slot_list slots(impl->slots_);
246 for (const auto& slot : slots)
248 if (slot.empty() || slot.blocked())
250 (sigc::internal::function_pointer_cast<call_type>(slot.rep_->call_))(LIST(slot.rep_, LOOP(_A_a%1, $1)));
254 _DEPRECATE_IFDEF_START
255 /** Executes a list of slots using an accumulator of type @e T_accumulator in reverse order.dnl
257 * The arguments are passed directly on to the slots.])
258 * @param first An iterator pointing to the first slot in the list.
259 * @param last An iterator pointing to the last slot in the list.dnl
261 * @param _A_a%1 Argument to be passed on to the slots.])
263 * @deprecated This is apparently not useful, but please let us know if you need it.
265 static result_type emit_reverse(LIST(signal_impl* impl, LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)))
267 if (!impl || impl->slots_.empty()) return;
268 signal_exec exec(impl);
269 temp_slot_list slots(impl->slots_);
271 #ifndef SIGC_HAVE_SUN_REVERSE_ITERATOR
272 typedef std::reverse_iterator<signal_impl::iterator_type> reverse_iterator_type;
274 typedef std::reverse_iterator<signal_impl::iterator_type, std::random_access_iterator_tag,
275 slot_base, slot_base&, slot_base*, std::ptrdiff_t> reverse_iterator_type;
277 for (auto it = reverse_iterator_type(slots.end()); it != reverse_iterator_type(slots.begin()); ++it)
279 if (it->empty() || it->blocked())
281 (sigc::internal::function_pointer_cast<call_type>(it->rep_->call_))(LIST(it->rep_, LOOP(_A_a%1, $1)));
288 define([SIGNAL_N],[dnl
289 /** Signal declaration.
290 * signal$1 can be used to connect() slots that are invoked
291 * during subsequent calls to emit(). Any functor or slot
292 * can be passed into connect(). It is converted into a slot
295 * If you want to connect one signal to another, use make_slot()
296 * to retrieve a functor that emits the signal when invoked.
298 * Be careful if you directly pass one signal into the connect()
299 * method of another: a shallow copy of the signal is made and
300 * the signal's slots are not disconnected until both the signal
301 * and its clone are destroyed, which is probably not what you want.
303 * The following template arguments are used:
304 * - @e T_return The desired return type for the emit() function (may be overridden by the accumulator).dnl
306 * - @e T_arg%1 Argument type used in the definition of emit().])
307 * - @e T_accumulator The accumulator type used for emission. The default
308 * @p nil means that no accumulator should be used, for example if signal
309 * emission returns the return value of the last slot invoked.
311 * You should use the more convenient unnumbered sigc::signal template.
315 template <LIST(class T_return, LOOP(class T_arg%1, $1), class T_accumulator=nil)>
320 typedef internal::signal_emit$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)> emitter_type;
321 typedef typename emitter_type::result_type result_type;
322 typedef slot<T_return(LIST(LOOP(T_arg%1, $1)))> slot_type;
323 typedef slot_list<slot_type> slot_list_type;
324 typedef typename slot_list_type::iterator iterator;
325 typedef typename slot_list_type::const_iterator const_iterator;
326 typedef typename slot_list_type::reverse_iterator reverse_iterator;
327 typedef typename slot_list_type::const_reverse_iterator const_reverse_iterator;
329 /** Add a slot to the list of slots.
330 * Any functor or slot may be passed into connect().
331 * It will be converted into a slot implicitly.
332 * The returned iterator may be stored for disconnection
333 * of the slot at some later point. It stays valid until
334 * the slot is removed from the list of slots. The iterator
335 * can also be implicitly converted into a sigc::connection object
336 * that may be used safely beyond the life time of the slot.
338 * std::function<> and C++11 lambda expressions are functors.
339 * These are examples of functors that can be connected to a signal.
341 * %std::bind() creates a functor, but this functor typically has an
342 * %operator()() which is a variadic template.
343 * Our functor_trait can't deduce the result type
344 * of such a functor. If you first assign the return value of %std::bind()
345 * to a std::function, you can connect the std::function to a signal.
347 * @param slot_ The slot to add to the list of slots.
348 * @return An iterator pointing to the new slot in the list.
350 iterator connect(const slot_type& slot_)
351 { return iterator(signal_base::connect(static_cast<const slot_base&>(slot_))); }
353 /** Add a slot to the list of slots.
354 * @see connect(const slot_type& slot_).
358 iterator connect(slot_type&& slot_)
359 { return iterator(signal_base::connect(std::move(static_cast<slot_base&>(slot_)))); }
361 /** Triggers the emission of the signal.
362 * During signal emission all slots that have been connected
363 * to the signal are invoked unless they are manually set into
364 * a blocking state. The parameters are passed on to the slots.
365 * If @e T_accumulated is not @p nil, an accumulator of this type
366 * is used to process the return values of the slot invocations.
367 * Otherwise, the return value of the last slot invoked is returned.dnl
369 * @param _A_a%1 Argument to be passed on to the slots.])
370 * @return The accumulated return values of the slot invocations.
372 result_type emit(LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)) const
373 { return emitter_type::emit(LIST(impl_, LOOP(_A_a%1, $1))); }
375 _DEPRECATE_IFDEF_START
376 /** Triggers the emission of the signal in reverse order (see emit()).
378 * @deprecated This is apparently not useful, but please let us know if you need it.
380 result_type emit_reverse(LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)) const
381 { return emitter_type::emit_reverse(LIST(impl_, LOOP(_A_a%1, $1))); }
384 /** Triggers the emission of the signal (see emit()).
386 * @deprecated This is apparently not useful, but let us know if you need it.
388 result_type operator()(LOOP(type_trait_take_t<T_arg%1> _A_a%1, $1)) const
389 { return emit(LOOP(_A_a%1, $1)); }
391 /** Creates a functor that calls emit() on this signal.
393 * sigc::mem_fun(mysignal, &sigc::signal$1::emit)
395 * yields the same result.
396 * @return A functor that calls emit() on this signal.
398 bound_const_mem_functor$1<LIST(result_type, signal$1, LOOP(type_trait_take_t<T_arg%1>, $1))> make_slot() const
399 { return bound_const_mem_functor$1<LIST(result_type, signal$1, LOOP(type_trait_take_t<T_arg%1>, $1))>(*this, &signal$1::emit); }
401 _DEPRECATE_IFDEF_START
402 /** Creates an STL-style interface for the signal's list of slots.
403 * This interface supports iteration, insertion and removal of slots.
404 * @return An STL-style interface for the signal's list of slots.
406 * @deprecated This is apparently not useful, but please let us know if you need it.
408 slot_list_type slots()
409 { return slot_list_type(impl()); }
411 /** Creates an STL-style interface for the signal's list of slots.
412 * This interface supports iteration, insertion and removal of slots.
413 * @return An STL-style interface for the signal's list of slots.
415 * @deprecated This is apparently not useful, but please let us know if you need it.
417 const slot_list_type slots() const
418 { return slot_list_type(const_cast<signal$1*>(this)->impl()); }
423 signal$1(const signal$1& src)
424 : signal_base(src) {}
426 signal$1(signal$1&& src)
427 : signal_base(std::move(src)) {}
429 signal$1& operator=(const signal$1& src)
431 signal_base::operator=(src);
435 signal$1& operator=(signal$1&& src)
437 signal_base::operator=(std::move(src));
445 /** Convenience wrapper for the numbered sigc::signal# templates.
446 * signal can be used to connect() slots that are invoked
447 * during subsequent calls to emit(). Any functor or slot
448 * can be passed into connect(). It is converted into a slot
451 * If you want to connect one signal to another, use make_slot()
452 * to retrieve a functor that emits the signal when invoked.
454 * Be careful if you directly pass one signal into the connect()
455 * method of another: a shallow copy of the signal is made and
456 * the signal's slots are not disconnected until both the signal
457 * and its clone are destroyed, which is probably not what you want!
459 * The template arguments determine the function signature of
460 * the emit() function:
461 * - @e T_return The desired return type of the emit() function.dnl
463 * - @e T_arg%1 Argument type used in the definition of emit(). The default @p nil means no argument.])
465 * To specify an accumulator type the nested class signal::accumulated can be used.
470 * sigc::signal<void, long> sig;
471 * sig.connect(sigc::ptr_fun(&foo));
475 * @deprecated Please use the syntax similar to that used by std::function<>:
477 * sigc::slot<void(bool, int)> some_slot;
482 template <LIST(class T_return, LOOP(class T_arg%1 = nil, $1))>
485 /** Convenience wrapper for the numbered sigc::signal$1 template.
486 * See the base class for useful methods.
487 * This is the template specialization of the unnumbered sigc::signal
488 * template for $1 argument(s).
490 * @deprecated Please use the syntax similar to that used by std::function<>:
492 * sigc::slot<void(bool, int)> some_slot;
499 template <LIST(class T_return, LOOP(class T_arg%1, $1))>
500 class signal ifelse($1, $2,,[<LIST(T_return, LOOP(T_arg%1,$1), LOOP(nil, CALL_SIZE - $1))>])])
501 : public signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>
505 /** Convenience wrapper for the numbered sigc::signal# templates.
506 * Like sigc::signal but the additional template parameter @e T_accumulator
507 * defines the accumulator type that should be used.
509 * An accumulator is a functor that uses a pair of special iterators
510 * to step through a list of slots and calculate a return value
511 * from the results of the slot invokations. The iterators' operator*()
512 * executes the slot. The return value is buffered, so that in an expression
513 * like @code a = (*i) * (*i); @endcode the slot is executed only once.
514 * The accumulator must define its return value as @p result_type.
517 * This accumulator calculates the arithmetic mean value:
519 * struct arithmetic_mean_accumulator
521 * typedef double result_type;
522 * template<typename T_iterator>
523 * result_type operator()(T_iterator first, T_iterator last) const
525 * result_type value_ = 0;
527 * for (; first != last; ++first, ++n_)
529 * return value_ / n_;
535 * This accumulator stops signal emission when a slot returns zero:
537 * struct interruptable_accumulator
539 * typedef bool result_type;
540 * template<typename T_iterator>
541 * result_type operator()(T_iterator first, T_iterator last) const
543 * for (; first != last; ++first, ++n_)
544 * if (!*first) return false;
552 /** Convenience wrapper for the numbered sigc::signal$1 template.
553 * Like sigc::signal but the additional template parameter @e T_accumulator
554 * defines the accumulator type that should be used.
557 template <class T_accumulator>
559 : public signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>
563 accumulated(const accumulated& src)
564 : signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>(src) {}
569 signal(const signal& src)
570 : signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(src) {}
573 : signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(std::move(src)) {}
575 signal& operator=(const signal& src)
577 signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(src);
581 signal& operator=(signal&& src)
583 signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(std::move(src));
589 * This specialization allow use of the sigc::signal<R(Args...)> syntax,
591 template <LIST(class T_return, LOOP(class T_arg%1, $1))>
592 class signal<T_return(LIST(LOOP(T_arg%1, $1)))>
593 : public signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>
597 /** Convenience wrapper for the numbered sigc::signal# templates.
598 * Like sigc::signal but the additional template parameter @e T_accumulator
599 * defines the accumulator type that should be used.
601 * An accumulator is a functor that uses a pair of special iterators
602 * to step through a list of slots and calculate a return value
603 * from the results of the slot invokations. The iterators' operator*()
604 * executes the slot. The return value is buffered, so that in an expression
605 * like @code a = (*i) * (*i); @endcode the slot is executed only once.
606 * The accumulator must define its return value as @p result_type.
609 * This accumulator calculates the arithmetic mean value:
611 * struct arithmetic_mean_accumulator
613 * typedef double result_type;
614 * template<typename T_iterator>
615 * result_type operator()(T_iterator first, T_iterator last) const
617 * result_type value_ = 0;
619 * for (; first != last; ++first, ++n_)
621 * return value_ / n_;
627 * This accumulator stops signal emission when a slot returns zero:
629 * struct interruptable_accumulator
631 * typedef bool result_type;
632 * template<typename T_iterator>
633 * result_type operator()(T_iterator first, T_iterator last) const
635 * for (; first != last; ++first, ++n_)
636 * if (!*first) return false;
644 /** Convenience wrapper for the numbered sigc::signal$1 template.
645 * Like sigc::signal but the additional template parameter @e T_accumulator
646 * defines the accumulator type that should be used.
649 template <class T_accumulator>
651 : public signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>
655 accumulated(const accumulated& src)
656 : signal$1<LIST(T_return, LOOP(T_arg%1, $1), T_accumulator)>(src) {}
661 signal(const signal& src)
662 : signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(src) {}
665 : signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>(std::move(src)) {}
667 signal& operator=(const signal& src)
669 signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(src);
673 signal& operator=(signal&& src)
675 signal$1<LIST(T_return, LOOP(T_arg%1, $1),nil)>::operator=(std::move(src));
684 #ifndef _SIGC_SIGNAL_H_
685 #define _SIGC_SIGNAL_H_
688 #include <sigc++/signal_base.h>
689 #include <sigc++/type_traits.h>
690 #include <sigc++/trackable.h>
691 #include <sigc++/functors/slot.h>
692 #include <sigc++/functors/mem_fun.h>
694 //TODO: See comment in functor_trait.h.
695 #if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
696 #define SIGC_NIL_HAS_BEEN_PUSHED 1
697 #pragma push_macro("nil")
701 //SIGC_TYPEDEF_REDEFINE_ALLOWED:
702 // TODO: This should have its own test, but I can not create one that gives the error instead of just a warning. murrayc.
703 // I have just used this because there is a correlation between these two problems.
704 #ifdef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
705 //Compilers, such as older versions of SUN Forte C++, that do not allow this also often
706 //do not allow a typedef to have the same name as a class in the typedef's definition.
707 //For Sun Forte CC 5.7 (SUN Workshop 10), comment this out to fix the build.
708 #define SIGC_TYPEDEF_REDEFINE_ALLOWED 1
713 /** STL-style iterator for slot_list.
717 template <typename T_slot>
720 typedef std::size_t size_type;
721 typedef std::ptrdiff_t difference_type;
722 typedef std::bidirectional_iterator_tag iterator_category;
724 typedef T_slot slot_type;
726 typedef T_slot value_type;
727 typedef T_slot* pointer;
728 typedef T_slot& reference;
730 typedef typename internal::signal_impl::iterator_type iterator_type;
735 explicit slot_iterator(const iterator_type& i)
738 reference operator*() const
739 { return static_cast<reference>(*i_); }
741 pointer operator->() const
742 { return &(operator*()); }
744 slot_iterator& operator++()
750 slot_iterator operator++(int)
752 slot_iterator __tmp(*this);
757 slot_iterator& operator--()
763 slot_iterator operator--(int)
765 slot_iterator __tmp(*this);
770 bool operator == (const slot_iterator& other) const
771 { return i_ == other.i_; }
773 bool operator != (const slot_iterator& other) const
774 { return i_ != other.i_; }
779 /** STL-style const iterator for slot_list.
783 template <typename T_slot>
784 struct slot_const_iterator
786 typedef std::size_t size_type;
787 typedef std::ptrdiff_t difference_type;
788 typedef std::bidirectional_iterator_tag iterator_category;
790 typedef T_slot slot_type;
792 typedef T_slot value_type;
793 typedef const T_slot* pointer;
794 typedef const T_slot& reference;
796 typedef typename internal::signal_impl::const_iterator_type iterator_type;
798 slot_const_iterator()
801 explicit slot_const_iterator(const iterator_type& i)
804 reference operator*() const
805 { return static_cast<reference>(*i_); }
807 pointer operator->() const
808 { return &(operator*()); }
810 slot_const_iterator& operator++()
816 slot_const_iterator operator++(int)
818 slot_const_iterator __tmp(*this);
823 slot_const_iterator& operator--()
829 slot_const_iterator operator--(int)
831 slot_const_iterator __tmp(*this);
836 bool operator == (const slot_const_iterator& other) const
837 { return i_ == other.i_; }
839 bool operator != (const slot_const_iterator& other) const
840 { return i_ != other.i_; }
845 /** STL-style list interface for sigc::signal#.
846 * slot_list can be used to iterate over the list of slots that
847 * is managed by a signal. Slots can be added or removed from
848 * the list while existing iterators stay valid.
852 template <class T_slot>
855 typedef T_slot slot_type;
857 typedef slot_type& reference;
858 typedef const slot_type& const_reference;
860 typedef slot_iterator<slot_type> iterator;
861 typedef slot_const_iterator<slot_type> const_iterator;
863 #ifndef SIGC_HAVE_SUN_REVERSE_ITERATOR
864 typedef std::reverse_iterator<iterator> reverse_iterator;
865 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
867 typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
868 int, int&, int*, std::ptrdiff_t> reverse_iterator;
870 typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
871 int, const int&, const int*, std::ptrdiff_t> const_reverse_iterator;
872 #endif /* SIGC_HAVE_SUN_REVERSE_ITERATOR */
878 explicit slot_list(internal::signal_impl* __list)
882 { return iterator(list_->slots_.begin()); }
884 const_iterator begin() const
885 { return const_iterator(list_->slots_.begin()); }
888 { return iterator(list_->slots_.end()); }
890 const_iterator end() const
891 { return const_iterator(list_->slots_.end()); }
893 reverse_iterator rbegin()
894 { return reverse_iterator(end()); }
896 const_reverse_iterator rbegin() const
897 { return const_reverse_iterator(end()); }
899 reverse_iterator rend()
900 { return reverse_iterator(begin()); }
902 const_reverse_iterator rend() const
903 { return const_reverse_iterator(begin()); }
908 const_reference front() const
912 { return *(--end()); }
914 const_reference back() const
915 { return *(--end()); }
917 iterator insert(iterator i, const slot_type& slot_)
918 { return iterator(list_->insert(i.i_, static_cast<const slot_base&>(slot_))); }
920 iterator insert(iterator i, slot_type&& slot_)
921 { return iterator(list_->insert(i.i_, std::move(static_cast<slot_base&>(slot_)))); }
923 void push_front(const slot_type& c)
924 { insert(begin(), c); }
926 void push_front(slot_type&& c)
927 { insert(begin(), std::move(c)); }
929 void push_back(const slot_type& c)
930 { insert(end(), c); }
932 void push_back(slot_type&& c)
933 { insert(end(), std::move(c)); }
935 iterator erase(iterator i)
936 { return iterator(list_->erase(i.i_)); }
938 iterator erase(iterator first_, iterator last_)
940 while (first_ != last_)
941 first_ = erase(first_);
955 internal::signal_impl* list_;
961 /** Special iterator over sigc::internal::signal_impl's slot list that holds extra data.
962 * This iterators is for use in accumulators. operator*() executes
963 * the slot. The return value is buffered, so that in an expression
964 * like @code a = (*i) * (*i); @endcode the slot is executed only once.
966 template <class T_emitter, class T_result = typename T_emitter::result_type>
967 struct slot_iterator_buf
969 typedef std::size_t size_type;
970 typedef std::ptrdiff_t difference_type;
971 typedef std::bidirectional_iterator_tag iterator_category;
973 //These are needed just to make this a proper C++ iterator,
974 //that can be used with standard C++ algorithms.
975 typedef T_result value_type;
976 typedef T_result& reference;
977 typedef T_result* pointer;
979 typedef T_emitter emitter_type;
980 typedef T_result result_type;
981 typedef typename T_emitter::slot_type slot_type;
983 typedef signal_impl::const_iterator_type iterator_type;
986 : c_(nullptr), invoked_(false) {}
988 slot_iterator_buf(const iterator_type& i, const emitter_type* c)
989 : i_(i), c_(c), invoked_(false) {}
991 result_type operator*() const
993 if (!i_->empty() && !i_->blocked() && !invoked_)
995 r_ = (*c_)(static_cast<const slot_type&>(*i_));
1001 slot_iterator_buf& operator++()
1008 slot_iterator_buf operator++(int)
1010 slot_iterator_buf __tmp(*this);
1016 slot_iterator_buf& operator--()
1023 slot_iterator_buf operator--(int)
1025 slot_iterator_buf __tmp(*this);
1031 bool operator == (const slot_iterator_buf& other) const
1032 { return (!c_ || (i_ == other.i_)); } /* If '!c_' the iterators are empty.
1033 * Unfortunately, empty stl iterators are not equal.
1034 * We are forcing equality so that 'first==last'
1035 * in the accumulator's emit function yields true. */
1037 bool operator != (const slot_iterator_buf& other) const
1038 { return (c_ && (i_ != other.i_)); }
1042 const emitter_type* c_;
1043 mutable result_type r_;
1044 mutable bool invoked_;
1047 /** Template specialization of slot_iterator_buf for void return signals.
1049 template <class T_emitter>
1050 struct slot_iterator_buf<T_emitter, void>
1052 typedef std::size_t size_type;
1053 typedef std::ptrdiff_t difference_type;
1054 typedef std::bidirectional_iterator_tag iterator_category;
1056 typedef T_emitter emitter_type;
1057 typedef void result_type;
1058 typedef typename T_emitter::slot_type slot_type;
1060 typedef signal_impl::const_iterator_type iterator_type;
1063 : c_(nullptr), invoked_(false) {}
1065 slot_iterator_buf(const iterator_type& i, const emitter_type* c)
1066 : i_(i), c_(c), invoked_(false) {}
1068 void operator*() const
1070 if (!i_->empty() && !i_->blocked() && !invoked_)
1072 (*c_)(static_cast<const slot_type&>(*i_));
1077 slot_iterator_buf& operator++()
1084 slot_iterator_buf operator++(int)
1086 slot_iterator_buf __tmp(*this);
1092 slot_iterator_buf& operator--()
1099 slot_iterator_buf operator--(int)
1101 slot_iterator_buf __tmp(*this);
1107 bool operator == (const slot_iterator_buf& other) const
1108 { return i_ == other.i_; }
1110 bool operator != (const slot_iterator_buf& other) const
1111 { return i_ != other.i_; }
1115 const emitter_type* c_;
1116 mutable bool invoked_;
1119 /** Reverse version of sigc::internal::slot_iterator_buf. */
1120 template <class T_emitter, class T_result = typename T_emitter::result_type>
1121 struct slot_reverse_iterator_buf
1123 typedef std::size_t size_type;
1124 typedef std::ptrdiff_t difference_type;
1125 typedef std::bidirectional_iterator_tag iterator_category;
1127 //These are needed just to make this a proper C++ iterator,
1128 //that can be used with standard C++ algorithms.
1129 typedef T_result value_type;
1130 typedef T_result& reference;
1131 typedef T_result* pointer;
1133 typedef T_emitter emitter_type;
1134 typedef T_result result_type;
1135 typedef typename T_emitter::slot_type slot_type;
1137 typedef signal_impl::const_iterator_type iterator_type;
1139 slot_reverse_iterator_buf()
1140 : c_(nullptr), invoked_(false) {}
1142 slot_reverse_iterator_buf(const iterator_type& i, const emitter_type* c)
1143 : i_(i), c_(c), invoked_(false) {}
1145 result_type operator*() const
1149 if (!__tmp->empty() && !__tmp->blocked() && !invoked_)
1151 r_ = (*c_)(static_cast<const slot_type&>(*__tmp));
1157 slot_reverse_iterator_buf& operator++()
1164 slot_reverse_iterator_buf operator++(int)
1166 slot_reverse_iterator_buf __tmp(*this);
1172 slot_reverse_iterator_buf& operator--()
1179 slot_reverse_iterator_buf operator--(int)
1181 slot_reverse_iterator_buf __tmp(*this);
1187 bool operator == (const slot_reverse_iterator_buf& other) const
1188 { return (!c_ || (i_ == other.i_)); } /* If '!c_' the iterators are empty.
1189 * Unfortunately, empty stl iterators are not equal.
1190 * We are forcing equality so that 'first==last'
1191 * in the accumulator's emit function yields true. */
1193 bool operator != (const slot_reverse_iterator_buf& other) const
1194 { return (c_ && (i_ != other.i_)); }
1198 const emitter_type* c_;
1199 mutable result_type r_;
1200 mutable bool invoked_;
1203 /** Template specialization of slot_reverse_iterator_buf for void return signals.
1205 template <class T_emitter>
1206 struct slot_reverse_iterator_buf<T_emitter, void>
1208 typedef std::size_t size_type;
1209 typedef std::ptrdiff_t difference_type;
1210 typedef std::bidirectional_iterator_tag iterator_category;
1212 typedef T_emitter emitter_type;
1213 typedef void result_type;
1214 typedef typename T_emitter::slot_type slot_type;
1216 typedef signal_impl::const_iterator_type iterator_type;
1218 slot_reverse_iterator_buf()
1219 : c_(nullptr), invoked_(false) {}
1221 slot_reverse_iterator_buf(const iterator_type& i, const emitter_type* c)
1222 : i_(i), c_(c), invoked_(false) {}
1224 void operator*() const
1228 if (!__tmp->empty() && !__tmp->blocked() && !invoked_)
1230 (*c_)(static_cast<const slot_type&>(*__tmp));
1235 slot_reverse_iterator_buf& operator++()
1242 slot_reverse_iterator_buf operator++(int)
1244 slot_reverse_iterator_buf __tmp(*this);
1250 slot_reverse_iterator_buf& operator--()
1257 slot_reverse_iterator_buf operator--(int)
1259 slot_reverse_iterator_buf __tmp(*this);
1265 bool operator == (const slot_reverse_iterator_buf& other) const
1266 { return i_ == other.i_; }
1268 bool operator != (const slot_reverse_iterator_buf& other) const
1269 { return i_ != other.i_; }
1273 const emitter_type* c_;
1274 mutable bool invoked_;
1277 FOR(0,CALL_SIZE,[[SIGNAL_EMIT_N(%1)]])
1278 } /* namespace internal */
1280 FOR(0,CALL_SIZE,[[SIGNAL_N(%1)]])
1282 SIGNAL(CALL_SIZE,CALL_SIZE)
1283 FOR(0,eval(CALL_SIZE-1),[[SIGNAL(%1)]])
1285 } /* namespace sigc */
1287 #ifdef SIGC_NIL_HAS_BEEN_PUSHED
1288 #undef SIGC_NIL_HAS_BEEN_PUSHED
1289 #pragma pop_macro("nil")
1292 #endif /* _SIGC_SIGNAL_H_ */