Functor.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2004 by Willem van Straten
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 // psrchive/Util/units/Functor.h
10 
11 #ifndef __Swinburne_Functor_h
12 #define __Swinburne_Functor_h
13 
14 #include "Reference.h"
15 
16 // an empty type used to allow one template name
17 struct __functor_empty {};
18 
20 
38 template<typename R, typename A1=__functor_empty, typename A2=__functor_empty>
39 class Functor;
40 
42 class FunctorBase : public Reference::Able {
43 public:
45  virtual bool is_valid () const = 0;
46 
48  virtual bool matches (const FunctorBase* that) const = 0;
49 };
50 
52 template<typename Function, typename Inherit>
53 class FunctorFunction : public Inherit {
54 public:
55 
57  bool matches (Function _function) const
58  { return function == _function; }
59 
61  bool is_valid () const { return function != 0; }
62 
64  virtual bool matches (const FunctorBase* that) const
65  { const FunctorFunction* like = dynamic_cast<const FunctorFunction*> (that);
66  return like && like->matches(function); }
67 
68  protected:
69 
71  Function function;
72 
73 };
74 
76 template<class Class, typename Method, class Inherit>
77 class FunctorMethod : public Inherit {
78 public:
79 
81  bool matches (const Class* _instance, Method _method) const
82  { return (instance && instance == _instance && method == _method); }
83 
85  bool is_valid () const { return instance && method != 0; }
86 
88  virtual bool matches (const FunctorBase* that) const
89  { const FunctorMethod* like = dynamic_cast<const FunctorMethod*> (that);
90  return like && like->matches(instance,method); }
91 
92 protected:
93 
96 
98  Method method;
99 
100 };
101 
102 // ///////////////////////////////////////////////////////////////////////////
103 //
104 // Generator Functor specialization
105 //
106 // ///////////////////////////////////////////////////////////////////////////
107 
109 
110 template< typename R, typename A1, typename A2 >
111 class Functor< R (), A1, A2 >
112 {
113  public:
114 
115  typedef R result_type;
116 
117  //
118  // the interface
119  //
120 
122  Functor () { }
123 
125  R operator() () const { return functor->call(); }
126 
128  template<class C, typename M> Functor (C* instance, M method)
129  { functor = new Method<C, M> (instance, method); }
130 
132  template<class C, typename M> Functor (const C& instance, M method)
133  { functor = new Method<const C, M> (&instance, method); }
134 
136  template<typename F> Functor (F function)
137  { functor = new Function<F> (function); }
138 
140  template<class C, typename M> void set (C* instance, M method)
141  { functor = new Method<C, M> (instance, method); }
142 
144  template<typename F> void set (F function)
145  { functor = new Function<F> (function); }
146 
147  //
148  // the implementation
149  //
150 
152  class Base : public FunctorBase {
153  public:
155  virtual R call () const = 0;
156  };
157 
159  template<typename F> class Function : public FunctorFunction<F,Base> {
160  public:
161 
163  Function (F _function)
164  { this->function = _function; }
165 
167  R call () const
168  { return R( (*(this->function)) () ); }
169 
170  };
171 
173  template<class C, typename M> class Method : public FunctorMethod<C,M,Base> {
174  public:
175 
177  Method (C* _instance, M _method)
178  { this->instance = _instance; this->method = _method; }
179 
181  R call () const
182  { return R( (this->instance->*(this->method)) () ); }
183 
184  };
185 
187  bool operator ! () const { return !functor; }
188 
190  operator bool () const { return functor; }
191 
193  const FunctorBase* get_functor () const { return functor; }
194 
195  protected:
196 
199 
200 };
201 
202 // ///////////////////////////////////////////////////////////////////////////
203 //
204 // Unary Functor specialization
205 //
206 // ///////////////////////////////////////////////////////////////////////////
207 
209 
210 template< typename R, typename A1, typename A2 >
211 class Functor< R (A1), A2 >
212 {
213  public:
214 
215  typedef A1 argument_type;
216  typedef R result_type;
217 
218  //
219  // the interface
220  //
221 
223  Functor () { }
224 
226  R operator() (const A1& p1) const { return functor->call(p1); }
227 
229  template<class C, typename M> Functor (C* instance, M method)
230  { functor = new Method<C, M> (instance, method); }
231 
233  template<class C, typename M> Functor (const C& instance, M method)
234  { functor = new Method<const C, M> (&instance, method); }
235 
237  template<typename F> Functor (F function)
238  { functor = new Function<F> (function); }
239 
241  template<class C, typename M> void set (C* instance, M method)
242  { functor = new Method<C, M> (instance, method); }
243 
245  template<typename F> void set (F function)
246  { functor = new Function<F> (function); }
247 
248  //
249  // the implementation
250  //
251 
253  class Base : public FunctorBase {
254  public:
256  virtual R call (const A1& p1) const = 0;
257  };
258 
260  template<typename F> class Function : public FunctorFunction<F,Base> {
261  public:
262 
264  Function (F _function)
265  { this->function = _function; }
266 
268  R call (const A1& p1) const
269  { return static_cast<R>( (*(this->function))(p1) ); }
270 
271  };
272 
274  template<class C, typename M> class Method : public FunctorMethod<C,M,Base> {
275  public:
276 
278  Method (C* _instance, M _method)
279  { this->instance = _instance; this->method = _method; }
280 
282  R call (const A1& p1) const try
283  { return R( (this->instance->*(this->method)) (p1) ); }
284  catch (Error& error) { throw error += "Functor<R(T)>::Method::call"; }
285 
286  };
287 
289  bool operator ! () const { return !functor; }
290 
292  operator bool () const { return functor; }
293 
295  const FunctorBase* get_functor () const { return functor; }
296 
297  protected:
298 
301 
302 };
303 
304 
305 // ///////////////////////////////////////////////////////////////////////////
306 //
307 // Binary Functor specialization
308 //
309 // ///////////////////////////////////////////////////////////////////////////
310 
312 
313 template< typename R, typename A1, typename A2 >
314 class Functor< R (A1, A2) >
315 {
316  public:
317 
318  typedef A1 first_argument_type;
319  typedef A2 second_argument_type;
320  typedef R result_type;
321 
322  //
323  // the interface
324  //
325 
327  Functor () { }
328 
330  R operator() (const A1& p1, const A2& p2) const
331  { return functor->call(p1,p2); }
332 
334  template<class C, typename M> Functor (C* instance, M method)
335  { functor = new Method<C, M> (instance, method); }
336 
338  template<class C, typename M> Functor (const C& instance, M method)
339  { functor = new Method<const C, M> (&instance, method); }
340 
342  template<typename F> Functor (F function)
343  { functor = new Function<F> (function); }
344 
346  template<class C, typename M> void set (C* instance, M method)
347  { functor = new Method<C, M> (instance, method); }
348 
350  template<typename F> void set (F function)
351  { functor = new Function<F> (function); }
352 
353  //
354  // the implementation
355  //
356 
358  class Base : public FunctorBase {
359  public:
361  virtual R call (const A1& p1, const A2& p2) const = 0;
362  };
363 
365  template<typename F> class Function : public FunctorFunction<F,Base> {
366  public:
367 
369  Function (F _function)
370  { this->function = _function; }
371 
373  R call (const A1& p1, const A2& p2) const
374  { return R( (*(this->function)) (p1, p2) ); }
375 
376  };
377 
379  template<class C, typename M> class Method : public FunctorMethod<C,M,Base> {
380  public:
381 
383  Method (C* _instance, M _method)
384  { this->instance = _instance; this->method = _method; }
385 
387  R call (const A1& p1, const A2& p2) const
388  { return R( (this->instance->*(this->method)) (p1, p2) ); }
389 
390  };
391 
393  bool operator ! () const { return !functor; }
394 
396  operator bool () const { return functor; }
397 
399  const FunctorBase* get_functor () const { return functor; }
400 
401  protected:
402 
405 
406 };
407 
408 template<typename R, typename A1, typename A2>
409 bool operator == (const Functor<R,A1,A2>& f1, const Functor<R,A1,A2>& f2)
410 {
411  if (!f1 && !f2)
412  return true;
413 
414  if (!f1 || !f2)
415  return false;
416 
417  if (f1.get_functor() == f2.get_functor())
418  return true;
419 
420  return f1.get_functor()->matches( f2.get_functor() );
421 
422 }
423 
424 #endif
void set(F function)
Set equal to a generator function.
Definition: Functor.h:144
Function(F _function)
Construct from a pointer to a function.
Definition: Functor.h:369
Functor(F function)
Construct from a binary function.
Definition: Functor.h:342
virtual bool matches(const FunctorBase *that) const
Return true if this matches that.
Definition: Functor.h:64
R call(const A1 &p1, const A2 &p2) const
Call the function.
Definition: Functor.h:373
Functor(const C &instance, M method)
Construct from a class instance and binary method.
Definition: Functor.h:338
void set(C *instance, M method)
Set equal to a class instance and unary method.
Definition: Functor.h:241
bool matches(Function _function) const
Return true if the function matches.
Definition: Functor.h:57
Functor(F function)
Construct from a generator function.
Definition: Functor.h:136
Method(C *_instance, M _method)
Construct from a pointer to a class instance and method.
Definition: Functor.h:177
const FunctorBase * get_functor() const
Get the pointer to the functor implementation.
Definition: Functor.h:399
A convenient exception handling class.
Definition: Error.h:54
void set(C *instance, M method)
Set equal to a class instance and generator method.
Definition: Functor.h:140
Function(F _function)
Construct from a pointer to a function.
Definition: Functor.h:163
void set(C *instance, M method)
Set equal to a class instance and binary method.
Definition: Functor.h:346
Functor()
Default constructor.
Definition: Functor.h:122
Pure virtual base class of functor implementations.
Definition: Functor.h:42
void set(F function)
Set equal to a binary function.
Definition: Functor.h:350
R call() const
Call the function.
Definition: Functor.h:167
virtual bool matches(const FunctorBase *that) const =0
Return true if this matches that.
Functor()
Default constructor.
Definition: Functor.h:223
R call(const A1 &p1) const
Call the function.
Definition: Functor.h:268
Reference::To< Base > functor
The implementation.
Definition: Functor.h:404
bool is_valid() const
Return true if valid (able to be called)
Definition: Functor.h:61
void set(F function)
Set equal to a unary function.
Definition: Functor.h:245
const FunctorBase * get_functor() const
Get the pointer to the functor implementation.
Definition: Functor.h:193
Method method
The method to be called.
Definition: Functor.h:98
R call() const
Call the method through the class instance.
Definition: Functor.h:181
Method(C *_instance, M _method)
Construct from a pointer to a class instance and method.
Definition: Functor.h:278
R call(const A1 &p1) const
Call the method through the class instance.
Definition: Functor.h:282
Method(C *_instance, M _method)
Construct from a pointer to a class instance and method.
Definition: Functor.h:383
virtual bool matches(const FunctorBase *that) const
Return true if this matches that.
Definition: Functor.h:88
const FunctorBase * get_functor() const
Get the pointer to the functor implementation.
Definition: Functor.h:295
Functor(C *instance, M method)
Construct from a class instance and binary method.
Definition: Functor.h:334
Reference::To< Base > functor
The implementation.
Definition: Functor.h:198
Manages Reference::To references to the instance.
Definition: ReferenceAble.h:40
Functor(C *instance, M method)
Construct from a class instance and unary method.
Definition: Functor.h:229
Implements scaffolding of Class/Method functor implementations.
Definition: Functor.h:77
Reference::To< Class, false > instance
The instance of the class.
Definition: Functor.h:95
Implements an adaptable function object in compliance with the STL.
Definition: Functor.h:39
Functor(const C &instance, M method)
Construct from a class instance and unary method.
Definition: Functor.h:233
Reference::To< Base > functor
The implementation.
Definition: Functor.h:300
Functor(F function)
Construct from a unary function.
Definition: Functor.h:237
R call(const A1 &p1, const A2 &p2) const
Call the method through the class instance.
Definition: Functor.h:387
Functor(C *instance, M method)
Construct from a class instance and generator method.
Definition: Functor.h:128
Functor(const C &instance, M method)
Construct from a class instance and generator method.
Definition: Functor.h:132
bool is_valid() const
Return true if valid (able to be called)
Definition: Functor.h:85
Functor()
Default constructor.
Definition: Functor.h:327
bool matches(const Class *_instance, Method _method) const
Return true if the instance and method match.
Definition: Functor.h:81
virtual bool is_valid() const =0
Return true if valid (able to be called)
Implements scaffolding of Function functor implementations.
Definition: Functor.h:53
Function(F _function)
Construct from a pointer to a function.
Definition: Functor.h:264

Generated using doxygen 1.8.17