FunctorType and Functor Init Pattern

Files CCore/inc/FunctorType.h CCore/src/FunctorType.cpp

Functor Init Pattern is widely used in CCore. In the modern C++ functors are commonly used. In CCore we often do it in the following manner:


template <class FuncInit>
void Call(FuncInit func_init)
 {
  FunctorTypeOf<FuncInit> func(func_init);

  func(); // call the functor
 }

I.e. the argument is not used directly as a functor. Instead we create the functor object inside a function from the provided argument and then call it. FunctorTypeOf<FuncInit> is a template typedef, defined in the header FunctorType.h. It defines the exact type of the functor object. The rule is simple: if the type FuncInit defines the inner type FunctorType, then this type is a functor type. Otherwise FuncInit itself is a functor type.


FunctorTypeOf<FuncInit> == typename FuncInit::FunctorType

OR

FunctorTypeOf<FuncInit> == FuncInit

So if the FuncInit is a "usual functor", then Call just call the copy of it. But the more complicated scenario is possible:


struct FuncInit // lightweight initializer
 {
  ....

  class FunctorType : NoCopy // heavy functor
   {
    public:

     FunctorType(FuncInit func_init);

     ~FunctorType();

     void operator () ();
   };
 };

....

FuncInit func_init;

Call(func_init);

In this example the "heavy" functor is created inside Call() from a lightweight initializer. The functor may be non-copyable and may have a non-trivial destructor (it may allocate and dispose resources temporary).

The helper class FunctorRefType is designed to pass a functor reference:


template <class T>
struct FunctorRefType
 {
  T *obj;
  
  explicit FunctorRefType(T &obj_) : obj(&obj_) {}
  
  using FunctorType = T & ;
  
  operator FunctorType() const { return *obj; }
 };

Use the Creator function FunctorRef() to create an object of type FunctorRefType.


template <class T>
FunctorRefType<T> FunctorRef(T &obj) { return FunctorRefType<T>(obj); }