dnl Copyright 2013, The libsigc++ Development Team dnl dnl This file is part of libsigc++. dnl dnl This library is free software; you can redistribute it and/or dnl modify it under the terms of the GNU Lesser General Public dnl License as published by the Free Software Foundation; either dnl version 2.1 of the License, or (at your option) any later version. dnl dnl This library is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl Lesser General Public License for more details. dnl dnl You should have received a copy of the GNU Lesser General Public dnl License along with this library. If not, see . dnl divert(-1) include(template.macros.m4) define([TRACK_OBJECT_OPERATOR],[dnl /** Invokes the wrapped functor passing on the arguments.dnl FOR(1, $1,[ * @param _A_arg%1 Argument to be passed on to the functor.]) * @return The return value of the functor invocation. */ template typename deduce_result_type::type operator()(LOOP(T_arg%1 _A_arg%1, $1)) { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES (LOOP(_A_arg%1, $1)); } #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD template typename deduce_result_type::type sun_forte_workaround(LOOP(T_arg%1 _A_arg%1, $1)) { return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES (LOOP(_A_arg%1, $1)); } #endif ])dnl end TRACK_OBJECT_OPERATOR dnl track_obj_functor[2..CALL_SIZE]. $1 is assumed to be >= 2. define([TRACK_OBJECT_FUNCTOR],[dnl /** track_obj_functor$1 wraps a functor and stores $1 references to trackable objects. * Use the convenience function track_obj() to create an instance of track_obj_functor$1. * * @tparam T_functor The type of functor to wrap.dnl FOR(1,$1,[ * @tparam T_obj%1 The type of a trackable object.]) * * @newin{2,4} * * @ingroup track_obj */ template class track_obj_functor$1 : public track_obj_functor1 { public: /** Constructs a track_obj_functor$1 object that wraps the passed functor and * stores references to the passed trackable objects. * @param _A_func Functor.dnl FOR(1,$1,[ * @param _A_obj%1 Trackable object.]) */ track_obj_functor$1(const T_functor& _A_func, LOOP(const T_obj%1& _A_obj%1, $1)) : track_obj_functor1(_A_func, _A_obj1)FOR(2,$1,[[, ]obj%1_(_A_obj%1)]) {} #ifndef DOXYGEN_SHOULD_SKIP_THIS //protected: // public, so that visit_each() can access it.dnl FOR(2,$1,[ const_limit_reference obj%1_;]) #endif /* DOXYGEN_SHOULD_SKIP_THIS */ }; // end class track_obj_functor$1 ])dnl end TRACK_OBJECT_FUNCTOR define([TRACK_OBJECT_VISIT_EACH],[dnl //template specialization of visitor<>::do_visit_each<>(action, functor): /** Performs a functor on each of the targets of a functor. * The function overload for sigc::track_obj_functor$1 performs a functor * on the functor and on the trackable object instances stored in the * sigc::track_obj_functor$1 object. * * @newin{2,4} * * @ingroup track_obj */ template struct visitor > { template static void do_visit_each(const T_action& _A_action, const track_obj_functor$1& _A_target) { sigc::visit_each(_A_action, _A_target.functor_);dnl FOR(1,$1,[ sigc::visit_each(_A_action, _A_target.obj%1_);]) } }; ])dnl end TRACK_OBJECT_VISIT_EACH define([TRACK_OBJECT],[dnl /** Creates an adaptor of type sigc::track_obj_functor$1 which wraps a functor. * @param _A_func Functor that shall be wrapped.dnl FOR(1,$1,[ * @param _A_obj%1 Trackable object.]) * @return Adaptor that executes _A_func() on invocation. * * @newin{2,4} * * @ingroup track_obj */ template inline track_obj_functor$1 track_obj(const T_functor& _A_func, LOOP(const T_obj%1& _A_obj%1, $1)) { return track_obj_functor$1 (_A_func, LOOP(_A_obj%1, $1)); } ])dnl end TRACK_OBJECT divert(0)dnl _FIREWALL([ADAPTORS_TRACK_OBJ]) #include #include namespace sigc { /** @defgroup track_obj track_obj() * sigc::track_obj() tracks trackable objects, referenced from a functor. * It can be useful when you assign a C++11 lambda expression or a std::function<> * to a slot, or connect it to a signal, and the lambda expression or std::function<> * contains references to sigc::trackable derived objects. * * The functor returned by sigc::track_obj() is formally an adaptor, but it does * not alter the signature, return type or behaviour of the supplied functor. * Up to CALL_SIZE objects can be tracked. operator()() can have up to CALL_SIZE arguments. * * @par Example: * @code * struct bar : public sigc::trackable {}; * sigc::signal some_signal; * void foo(bar&); * { * bar some_bar; * some_signal.connect([[&some_bar]](){ foo(some_bar); }); * // NOT disconnected automatically when some_bar goes out of scope * some_signal.connect(sigc::track_obj([[&some_bar]](){ foo(some_bar); }, some_bar); * // disconnected automatically when some_bar goes out of scope * } * @endcode * * @newin{2,4} * * @ingroup adaptors */ /** track_obj_functor1 wraps a functor and stores a reference to a trackable object. * Use the convenience function track_obj() to create an instance of track_obj_functor1. * * @tparam T_functor The type of functor to wrap. * @tparam T_obj1 The type of a trackable object. * * @newin{2,4} * * @ingroup track_obj */ template class track_obj_functor1 : public adapts { public: typedef typename adapts::adaptor_type adaptor_type; #ifndef DOXYGEN_SHOULD_SKIP_THIS template struct deduce_result_type { typedef typename adaptor_type::template deduce_result_type::type type; }; #endif typedef typename adaptor_type::result_type result_type; /** Constructs a track_obj_functor1 object that wraps the passed functor and * stores a reference to the passed trackable object. * @param _A_func Functor. * @param _A_obj1 Trackable object. */ track_obj_functor1(const T_functor& _A_func, const T_obj1& _A_obj1) : adapts(_A_func), obj1_(_A_obj1) {} /** Invokes the wrapped functor. * @return The return value of the functor invocation. */ result_type operator()() { return this->functor_(); } FOR(1,CALL_SIZE,[[TRACK_OBJECT_OPERATOR(%1)]])dnl #ifndef DOXYGEN_SHOULD_SKIP_THIS //protected: // public, so that visit_each() can access it. const_limit_reference obj1_; #endif /* DOXYGEN_SHOULD_SKIP_THIS */ }; // end class track_obj_functor1 FOR(2,CALL_SIZE,[[TRACK_OBJECT_FUNCTOR(%1)]])dnl #ifndef DOXYGEN_SHOULD_SKIP_THIS FOR(1,CALL_SIZE,[[TRACK_OBJECT_VISIT_EACH(%1)]])dnl #endif // DOXYGEN_SHOULD_SKIP_THIS FOR(1,CALL_SIZE,[[TRACK_OBJECT(%1)]])dnl } /* namespace sigc */