CHROMA
objfunctor.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! @file
3  * @brief Generic functor class
4  */
5 
6 #ifndef __objfunctor_h__
7 #define __objfunctor_h__
8 
9 #include "typelist.h"
10 #include "typetraits.h"
11 #include <typeinfo>
12 #include <memory>
13 
14 namespace Chroma
15 {
16 ////////////////////////////////////////////////////////////////////////////////
17 // class template FunctorImpl (internal)
18 ////////////////////////////////////////////////////////////////////////////////
19 
20  namespace Private
21  {
22  template <typename R>
24  {
25  typedef R ResultType;
26 
27  typedef EmptyType Parm1;
28  typedef EmptyType Parm2;
29  typedef EmptyType Parm3;
30  typedef EmptyType Parm4;
31  typedef EmptyType Parm5;
32 
33  virtual FunctorImplBase* DoClone() const = 0;
34  template <class U>
35  static U* Clone(U* pObj)
36  {
37  if (!pObj) return 0;
38  U* pClone = static_cast<U*>(pObj->DoClone());
39  assert(typeid(*pClone) == typeid(*pObj));
40  return pClone;
41  }
42  };
43  }
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 // macro DEFINE_CLONE_FUNCTORIMPL
47 // Implements the DoClone function for a functor implementation
48 ////////////////////////////////////////////////////////////////////////////////
49 
50 #define DEFINE_CLONE_FUNCTORIMPL(Cls) \
51  virtual Cls* DoClone() const { return new Cls(*this); }
52 
53 ////////////////////////////////////////////////////////////////////////////////
54 // class template FunctorImpl
55 // The base class for a hierarchy of functors. The FunctorImpl class is not used
56 // directly; rather, the Functor class manages and forwards to a pointer to
57 // FunctorImpl
58 // You may want to derive your own functors from FunctorImpl.
59 // Specializations of FunctorImpl for up to 5 parameters follow
60 ////////////////////////////////////////////////////////////////////////////////
61 
62  template <typename R, class TList>
63  class FunctorImpl;
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 // class template FunctorImpl
67 // Specialization for 0 (zero) parameters
68 ////////////////////////////////////////////////////////////////////////////////
69 
70  template <typename R>
72  : public Private::FunctorImplBase<R>
73  {
74  public:
75  typedef R ResultType;
76  virtual R operator()() = 0;
77  };
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 // class template FunctorImpl
81 // Specialization for 1 parameter
82 ////////////////////////////////////////////////////////////////////////////////
83 
84  template <typename R, typename P1>
85  class FunctorImpl<R, TYPELIST_1(P1)>
86  : public Private::FunctorImplBase<R>
87  {
88  public:
89  typedef R ResultType;
91  virtual R operator()(Parm1) = 0;
92  };
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 // class template FunctorImpl
96 // Specialization for 2 parameters
97 ////////////////////////////////////////////////////////////////////////////////
98 
99  template <typename R, typename P1, typename P2>
100  class FunctorImpl<R, TYPELIST_2(P1, P2)>
101  : public Private::FunctorImplBase<R>
102  {
103  public:
104  typedef R ResultType;
107  virtual R operator()(Parm1, Parm2) = 0;
108  };
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 // class template FunctorImpl
112 // Specialization for 3 parameters
113 ////////////////////////////////////////////////////////////////////////////////
114 
115  template <typename R, typename P1, typename P2, typename P3>
116  class FunctorImpl<R, TYPELIST_3(P1, P2, P3)>
117  : public Private::FunctorImplBase<R>
118  {
119  public:
120  typedef R ResultType;
124  virtual R operator()(Parm1, Parm2, Parm3) = 0;
125  };
126 
127 ////////////////////////////////////////////////////////////////////////////////
128 // class template FunctorImpl
129 // Specialization for 4 parameters
130 ////////////////////////////////////////////////////////////////////////////////
131 
132  template <typename R, typename P1, typename P2, typename P3, typename P4>
133  class FunctorImpl<R, TYPELIST_4(P1, P2, P3, P4)>
134  : public Private::FunctorImplBase<R>
135  {
136  public:
137  typedef R ResultType;
142  virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
143  };
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 // class template FunctorImpl
147 // Specialization for 5 parameters
148 ////////////////////////////////////////////////////////////////////////////////
149 
150  template <typename R, typename P1, typename P2, typename P3, typename P4,
151  typename P5>
152  class FunctorImpl<R, TYPELIST_5(P1, P2, P3, P4, P5)>
153  : public Private::FunctorImplBase<R>
154  {
155  public:
156  typedef R ResultType;
162  virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
163  };
164 
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 // class template FunctorHandler
168 // Wraps functors and pointers to functions
169 ////////////////////////////////////////////////////////////////////////////////
170 
171  template <class ParentFunctor, typename Fun>
173  : public ParentFunctor::Impl
174  {
175  typedef typename ParentFunctor::Impl Base;
176 
177  public:
178  typedef typename Base::ResultType ResultType;
179  typedef typename Base::Parm1 Parm1;
180  typedef typename Base::Parm2 Parm2;
181  typedef typename Base::Parm3 Parm3;
182  typedef typename Base::Parm4 Parm4;
183  typedef typename Base::Parm5 Parm5;
184 
185  FunctorHandler(const Fun& fun) : f_(fun) {}
186 
188 
189  // operator() implementations for up to 5 arguments
190 
191  ResultType operator()()
192  { return f_(); }
193 
195  { return f_(p1); }
196 
198  { return f_(p1, p2); }
199 
201  { return f_(p1, p2, p3); }
202 
204  { return f_(p1, p2, p3, p4); }
205 
207  { return f_(p1, p2, p3, p4, p5); }
208 
209  private:
210  Fun f_;
211  };
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 // class template FunctorHandler
215 // Wraps pointers to member functions
216 ////////////////////////////////////////////////////////////////////////////////
217 
218  template <class ParentFunctor, typename PointerToObj,
219  typename PointerToMemFn>
220  class MemFunHandler : public ParentFunctor::Impl
221  {
222  typedef typename ParentFunctor::Impl Base;
223 
224  public:
225  typedef typename Base::ResultType ResultType;
226  typedef typename Base::Parm1 Parm1;
227  typedef typename Base::Parm2 Parm2;
228  typedef typename Base::Parm3 Parm3;
229  typedef typename Base::Parm4 Parm4;
230  typedef typename Base::Parm5 Parm5;
231 
232  MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
233  : pObj_(pObj), pMemFn_(pMemFn)
234  {}
235 
237 
238  ResultType operator()()
239  { return ((*pObj_).*pMemFn_)(); }
240 
242  { return ((*pObj_).*pMemFn_)(p1); }
243 
245  { return ((*pObj_).*pMemFn_)(p1, p2); }
246 
248  { return ((*pObj_).*pMemFn_)(p1, p2, p3); }
249 
251  { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); }
252 
254  { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); }
255 
256  private:
257  PointerToObj pObj_;
258  PointerToMemFn pMemFn_;
259  };
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 // class template Functor
263 // A generalized functor implementation with value semantics
264 ////////////////////////////////////////////////////////////////////////////////
265 
266  template <typename R, class TList = NullType>
268  {
269  public:
270  // Handy type definitions for the body type
272  typedef R ResultType;
273  typedef TList ParmList;
274  typedef typename Impl::Parm1 Parm1;
275  typedef typename Impl::Parm2 Parm2;
276  typedef typename Impl::Parm3 Parm3;
277  typedef typename Impl::Parm4 Parm4;
278  typedef typename Impl::Parm5 Parm5;
279 
280  // Member functions
281 
283  {}
284 
285  ObjectFunctor(const ObjectFunctor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
286  {}
287 
288  ObjectFunctor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
289  {}
290 
291  template <typename Fun>
292  ObjectFunctor(Fun fun)
293  : spImpl_(new FunctorHandler<ObjectFunctor, Fun>(fun))
294  {}
295 
296  template <class PtrObj, typename MemFn>
297  ObjectFunctor(const PtrObj& p, MemFn memFn)
298  : spImpl_(new MemFunHandler<ObjectFunctor, PtrObj, MemFn>(p, memFn))
299  {}
300 
302  {
303  ObjectFunctor copy(rhs);
304  // swap auto_ptrs by hand
305  Impl* p = spImpl_.release();
306  spImpl_.reset(copy.spImpl_.release());
307  copy.spImpl_.reset(p);
308  return *this;
309  }
310 
312  { return (*spImpl_)(); }
313 
315  { return (*spImpl_)(p1); }
316 
318  { return (*spImpl_)(p1, p2); }
319 
321  { return (*spImpl_)(p1, p2, p3); }
322 
324  { return (*spImpl_)(p1, p2, p3, p4); }
325 
327  { return (*spImpl_)(p1, p2, p3, p4, p5); }
328 
329  private:
330  std::auto_ptr<Impl> spImpl_;
331  };
332 
333  namespace Private
334  {
335  template <class Fctor> struct BinderFirstTraits;
336 
337  template <typename R, class TList>
338  struct BinderFirstTraits< ObjectFunctor<R, TList> >
339  {
340  typedef typename TL::Erase<TList,
341  typename TL::TypeAt<TList, 0>::Result>::Result
344  typedef typename BoundFunctorType::Impl Impl;
345  };
346  }
347 
348 ////////////////////////////////////////////////////////////////////////////////
349 // class template BinderFirst
350 // Binds the first parameter of a ObjectFunctor object to a specific value
351 ////////////////////////////////////////////////////////////////////////////////
352 
353  template <class OriginalFunctor>
354  class BinderFirst
355  : public Private::BinderFirstTraits<OriginalFunctor>::Impl
356  {
358  typedef typename OriginalFunctor::ResultType ResultType;
359 
360  typedef typename OriginalFunctor::Parm1 BoundType;
361 
362  typedef typename OriginalFunctor::Parm2 Parm1;
363  typedef typename OriginalFunctor::Parm3 Parm2;
364  typedef typename OriginalFunctor::Parm4 Parm3;
365  typedef typename OriginalFunctor::Parm5 Parm4;
366  typedef EmptyType Parm5;
367 
368  public:
369  BinderFirst(const OriginalFunctor& fun, BoundType bound)
370  : f_(fun), b_(bound)
371  {}
372 
374 
375  // operator() implementations for up to 5 arguments
376 
377  ResultType operator()()
378  { return f_(b_); }
379 
381  { return f_(b_, p1); }
382 
384  { return f_(b_, p1, p2); }
385 
387  { return f_(b_, p1, p2, p3); }
388 
390  { return f_(b_, p1, p2, p3, p4); }
391 
392  private:
393  OriginalFunctor f_;
395  };
396 
397 ////////////////////////////////////////////////////////////////////////////////
398 // function template BindFirst
399 // Binds the first parameter of a Functor object to a specific value
400 ////////////////////////////////////////////////////////////////////////////////
401 
402  template <class Fctor>
405  const Fctor& fun,
406  typename Fctor::Parm1 bound)
407  {
409  Outgoing;
410 
411  return Outgoing(std::auto_ptr<typename Outgoing::Impl>(
412  new BinderFirst<Fctor>(fun, bound)));
413  }
414 
415 ////////////////////////////////////////////////////////////////////////////////
416 // class template Chainer
417 // Chains two functor calls one after another
418 ////////////////////////////////////////////////////////////////////////////////
419 
420  template <typename Fun1, typename Fun2>
421  class Chainer : public Fun2::Impl
422  {
423  typedef Fun2 Base;
424 
425  public:
426  typedef typename Base::ResultType ResultType;
427  typedef typename Base::Parm1 Parm1;
428  typedef typename Base::Parm2 Parm2;
429  typedef typename Base::Parm3 Parm3;
430  typedef typename Base::Parm4 Parm4;
431  typedef typename Base::Parm5 Parm5;
432 
433  Chainer(const Fun1& fun1, const Fun2& fun2) : f1_(fun1), f2_(fun2) {}
434 
436 
437  // operator() implementations for up to 5 arguments
438 
439  ResultType operator()()
440  { return f1_(), f2_(); }
441 
443  { return f1_(p1), f2_(p1); }
444 
446  { return f1_(p1, p2), f2_(p1, p2); }
447 
449  { return f1_(p1, p2, p3), f2_(p1, p2, p3); }
450 
452  { return f1_(p1, p2, p3, p4), f2_(p1, p2, p3, p4); }
453 
455  { return f1_(p1, p2, p3, p4, p5), f2_(p1, p2, p3, p4, p5); }
456 
457  private:
458  Fun1 f1_;
459  Fun2 f2_;
460  };
461 
462 ////////////////////////////////////////////////////////////////////////////////
463 // function template Chain
464 // Chains two functor calls one after another
465 ////////////////////////////////////////////////////////////////////////////////
466 
467 
468  template <class Fun1, class Fun2>
469  Fun2 Chain(
470  const Fun1& fun1,
471  const Fun2& fun2)
472  {
473  return Fun2(std::auto_ptr<typename Fun2::Impl>(
474  new Chainer<Fun1, Fun2>(fun1, fun2)));
475  }
476 
477 } // namespace Chroma
478 
479 #endif
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
Definition: objfunctor.h:386
OriginalFunctor::ResultType ResultType
Definition: objfunctor.h:358
OriginalFunctor::Parm3 Parm2
Definition: objfunctor.h:363
OriginalFunctor f_
Definition: objfunctor.h:393
OriginalFunctor::Parm1 BoundType
Definition: objfunctor.h:360
OriginalFunctor::Parm5 Parm4
Definition: objfunctor.h:365
ResultType operator()(Parm1 p1)
Definition: objfunctor.h:380
ResultType operator()(Parm1 p1, Parm2 p2)
Definition: objfunctor.h:383
Private::BinderFirstTraits< OriginalFunctor >::Impl Base
Definition: objfunctor.h:357
BinderFirst(const OriginalFunctor &fun, BoundType bound)
Definition: objfunctor.h:369
OriginalFunctor::Parm4 Parm3
Definition: objfunctor.h:364
OriginalFunctor::Parm2 Parm1
Definition: objfunctor.h:362
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
Definition: objfunctor.h:389
Base::Parm1 Parm1
Definition: objfunctor.h:427
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
Definition: objfunctor.h:448
Base::Parm4 Parm4
Definition: objfunctor.h:430
Base::Parm3 Parm3
Definition: objfunctor.h:429
ResultType operator()(Parm1 p1, Parm2 p2)
Definition: objfunctor.h:445
Base::ResultType ResultType
Definition: objfunctor.h:426
Base::Parm2 Parm2
Definition: objfunctor.h:428
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
Definition: objfunctor.h:451
Base::Parm5 Parm5
Definition: objfunctor.h:431
Chainer(const Fun1 &fun1, const Fun2 &fun2)
Definition: objfunctor.h:433
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
Definition: objfunctor.h:454
ResultType operator()(Parm1 p1)
Definition: objfunctor.h:442
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
Definition: objfunctor.h:206
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
Definition: objfunctor.h:200
ResultType operator()(Parm1 p1)
Definition: objfunctor.h:194
Base::ResultType ResultType
Definition: objfunctor.h:178
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
Definition: objfunctor.h:203
ResultType operator()(Parm1 p1, Parm2 p2)
Definition: objfunctor.h:197
ParentFunctor::Impl Base
Definition: objfunctor.h:175
FunctorHandler(const Fun &fun)
Definition: objfunctor.h:185
TypeTraits< P1 >::ParameterType Parm1
Definition: objfunctor.h:90
TypeTraits< P1 >::ParameterType Parm1
Definition: objfunctor.h:105
TypeTraits< P2 >::ParameterType Parm2
Definition: objfunctor.h:106
TypeTraits< P2 >::ParameterType Parm2
Definition: objfunctor.h:122
virtual R operator()(Parm1, Parm2, Parm3)=0
TypeTraits< P3 >::ParameterType Parm3
Definition: objfunctor.h:123
TypeTraits< P1 >::ParameterType Parm1
Definition: objfunctor.h:121
virtual R operator()(Parm1, Parm2, Parm3, Parm4)=0
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5)=0
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
Definition: objfunctor.h:250
ParentFunctor::Impl Base
Definition: objfunctor.h:222
MemFunHandler(const PointerToObj &pObj, PointerToMemFn pMemFn)
Definition: objfunctor.h:232
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
Definition: objfunctor.h:247
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
Definition: objfunctor.h:253
Base::ResultType ResultType
Definition: objfunctor.h:225
ResultType operator()(Parm1 p1, Parm2 p2)
Definition: objfunctor.h:244
ResultType operator()(Parm1 p1)
Definition: objfunctor.h:241
PointerToMemFn pMemFn_
Definition: objfunctor.h:258
PointerToObj pObj_
Definition: objfunctor.h:257
FunctorImpl< R, TList > Impl
Definition: objfunctor.h:271
ObjectFunctor(const PtrObj &p, MemFn memFn)
Definition: objfunctor.h:297
ObjectFunctor & operator=(const ObjectFunctor &rhs)
Definition: objfunctor.h:301
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
Definition: objfunctor.h:320
ResultType operator()()
Definition: objfunctor.h:311
ResultType operator()(Parm1 p1)
Definition: objfunctor.h:314
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
Definition: objfunctor.h:323
std::auto_ptr< Impl > spImpl_
Definition: objfunctor.h:330
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
Definition: objfunctor.h:326
ObjectFunctor(const ObjectFunctor &rhs)
Definition: objfunctor.h:285
ResultType operator()(Parm1 p1, Parm2 p2)
Definition: objfunctor.h:317
ObjectFunctor(std::auto_ptr< Impl > spImpl)
Definition: objfunctor.h:288
Select< isStdArith||isPointer||isMemberPointer, T, ReferredType & >::Result ParameterType
Definition: typetraits.h:225
void get(multi1d< LatticeColorMatrix > &u, XMLBufferWriter &file_xml, XMLBufferWriter &record_xml)
Get the default gauge field.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
Fun2 Chain(const Fun1 &fun1, const Fun2 &fun2)
Definition: objfunctor.h:469
Private::BinderFirstTraits< Fctor >::BoundFunctorType BindFirst(const Fctor &fun, typename Fctor::Parm1 bound)
Definition: objfunctor.h:404
#define DEFINE_CLONE_FUNCTORIMPL(Cls)
Definition: objfunctor.h:50
TL::Erase< TList, typename TL::TypeAt< TList, 0 >::Result >::Result ParmList
Definition: objfunctor.h:342
virtual FunctorImplBase * DoClone() const =0
static U * Clone(U *pObj)
Definition: objfunctor.h:35
multi1d< LatticeColorMatrix > U
Typelist support.
#define TYPELIST_3(T1, T2, T3)
Definition: typelist.h:45
#define TYPELIST_2(T1, T2)
Definition: typelist.h:43
#define TYPELIST_1(T1)
Definition: typelist.h:41
#define TYPELIST_4(T1, T2, T3, T4)
Definition: typelist.h:47
#define TYPELIST_5(T1, T2, T3, T4, T5)
Definition: typelist.h:49
Type traits support.