PlanInit

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

In C++ constructors of global objects are called in undefined order, except objects in the same translation unit initialized in the order of definition. CCore requires, however, the more precise control on this matter. PlanInit is a feature, designed for this. It provides the following:

Here is the usage pattern. Assume, you have the header XXX.h and the source XXX.cpp and you want to create the global object of the type GlobalXXXType using PlanInit. You declare the following global function in the XXX.h:

#include <CCore/inc/PlanInit.h>

PlanInitNode * GetPlanInitNode_XXX();

Then in the source file XXX.cpp you define the global object as following:

PlanInitObject<GlobalXXXType,PlanInitReq<GetPlanInitNode_YYY> > GlobalXXXObject CCORE_INITPRI_1 ;

PlanInitNode * GetPlanInitNode_XXX() { return &GlobalXXXObject; }

You may provide as many requirements as you need. PlanInit make sure the XXX initialization happens after YYY. Functions GetPlanInitNode_XXX() are required to specify dependencies. In CCore we don't expose global objects, they are hidden in source files and provide functionality using global functions.

The function GetPlanInitNode_CCore() marks the entire CCore initialization. If you are using the PlanInit in your project, make sure to add this node in requirement lists.

The type GlobalXXXType must provide a node tag:

class GlobalXXXType
 {
  public:

   ....

   static const char * GetTag() { return "XXX"; }
 };

The node GlobalXXXObject is an Object Pointer:

template <class T,class ... RR>
class PlanInitObject
 {
  public:

   T * operator + () const;
  
   bool operator ! () const;
   
   T * getPtr() const;
  
   T & operator * () const;
  
   T * operator -> () const;

   const char * getTag() const;
 };

CCore uses initialization priority attributes, implemented in the gcc family of C++ compilers. There are 4 levels of priority, reserved for CCore needs: CCORE_INITPRI_0, CCORE_INITPRI_1, CCORE_INITPRI_2 and CCORE_INITPRI_3. The first is used for most urgent objects. The second is reserved for PlanInit nodes. Finally, PlanInit object initialization happens on the third level. The last level is reserved for the initialization of global objects after the main CCore library is up but before "normal" global objects are coming up.