File: track_obj.h.m4

package info (click to toggle)
libsigc%2B%2B-2.0 2.12.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,432 kB
  • sloc: cpp: 4,132; xml: 339; python: 196; makefile: 192; sh: 5
file content (254 lines) | stat: -rw-r--r-- 8,542 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
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 <http://www.gnu.org/licenses/>.
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 <LOOP([typename T_arg%1], $1)>
  typename deduce_result_type<LOOP(T_arg%1, $1)>::type
  operator()(LOOP(T_arg%1 _A_arg%1, $1))
  {
    return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP([
      _P_(T_arg%1)], $1)>
      (LOOP(_A_arg%1, $1));
  }

  #ifndef SIGC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
  template <LOOP([typename T_arg%1], $1)>
  typename deduce_result_type<LOOP(T_arg%1, $1)>::type
  sun_forte_workaround(LOOP(T_arg%1 _A_arg%1, $1))
  {
    return this->functor_.SIGC_WORKAROUND_OPERATOR_PARENTHESES<LOOP([
      _P_(T_arg%1)], $1)>
      (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_object() 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 <typename T_functor, LOOP(typename T_obj%1, $1)>
class track_obj_functor$1 : public track_obj_functor1<T_functor, T_obj1>
{
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<T_functor, T_obj1>(_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<T_obj%1> 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 <typename T_functor, LOOP(typename T_obj%1, $1)>
struct visitor<track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)> >
{
  template <typename T_action>
  static void do_visit_each(const T_action& _A_action,
                            const track_obj_functor$1<T_functor, LOOP(T_obj%1, $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
_DEPRECATE_IFDEF_START
/** 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}
 * @deprecated Use sigc::track_object() instead.
 *
 * @ingroup track_obj
 */
template <typename T_functor, LOOP(typename T_obj%1, $1)>
inline track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>
track_obj(const T_functor& _A_func, LOOP(const T_obj%1& _A_obj%1, $1))
{
  return track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>
    (_A_func, LOOP(_A_obj%1, $1));
}
_DEPRECATE_IFDEF_END

])dnl end TRACK_OBJECT

define([TRACK_OBJECT2],[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, derived directly or indirectly from sigc::trackable.]])
 * @return Adaptor that executes _A_func() on invocation.
 *
 * @newin{2,12}
 *
 * @ingroup track_obj
 */
template <typename T_functor, LOOP(typename T_obj%1, $1)>
inline track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>
track_object(const T_functor& _A_func, LOOP(const T_obj%1& _A_obj%1, $1))
{
  static_assert(LOOP([[std::is_base_of<sigc::trackable, T_obj%1>::value]], $1, [ && ]),
    "Each trackable object must be derived from sigc::trackable.");

  return track_obj_functor$1<T_functor, LOOP(T_obj%1, $1)>
    (_A_func, LOOP(_A_obj%1, $1));
}

])dnl end TRACK_OBJECT2

divert(0)dnl
_FIREWALL([ADAPTORS_TRACK_OBJ])
#include <sigc++/adaptors/adaptor_trait.h>
#include <sigc++/limit_reference.h>
#include <type_traits>

namespace sigc {

/** @defgroup track_obj track_obj(), track_object()
 * sigc::track_object() 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_object() 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.
 *
 * track_obj() is a deprecated alternative to track_object().
 *
 * @par Example:
 * @code
 * struct bar : public sigc::trackable {};
 * sigc::signal<void> 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_object([[&some_bar]](){ foo(some_bar); }, some_bar);
 *     // disconnected automatically when some_bar goes out of scope
 * }
 * @endcode
 *
 * @ingroup adaptors
 */

/** track_obj_functor1 wraps a functor and stores a reference to a trackable object.
 * Use the convenience function track_object() 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 <typename T_functor, typename T_obj1>
class track_obj_functor1 : public adapts<T_functor>
{
public:
  typedef typename adapts<T_functor>::adaptor_type adaptor_type;

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  template <LOOP(typename T_arg%1=void, CALL_SIZE)>
  struct deduce_result_type
    { typedef typename adaptor_type::template deduce_result_type<LOOP(_P_(T_arg%1), CALL_SIZE)>::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<T_functor>(_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<T_obj1> 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
FOR(1,CALL_SIZE,[[TRACK_OBJECT2(%1)]])dnl

} /* namespace sigc */