3
\$\begingroup\$

I use this code to create a common interface around my C++ objects. At first it was intended to only POD types (implemented with functions like malloc() and memcpy()) but later it was modified to allow using a reduced interface for other C++ objects, allowing for things like constructors/destructors to be called by the management functions.

This particular piece of code declares a pointer holder (the reference type) that provides access to the actual instance and contains a reference counter for automatic management. The reference type can be declared as a template or as a macro-declared struct depending on some #define.

//------------------------------------------------------------------------------------
//---------------------------------------- gcore_ref.h
//------------------------------------------------------------------------------------

namespace god
{
//#pragma pack(push, 1)
#if defined ( DEBUG ) || defined( _DEBUG )              
#   define __GPRECHECK()  size_t CheckPre   
#   define __GPOSTCHECK() size_t CheckPost  
#   define __GCORE_REF_DEBUG_MEMBERS()  size_t AllocID, Column;
#   define __GCORE_REF_STATIC_DEBUG_MEMBERS()   static size_t __breakAllocID;
#else
#   define __GPRECHECK() 
#   define __GPOSTCHECK()
#   define __GCORE_REF_DEBUG_MEMBERS()
#   define __GCORE_REF_STATIC_DEBUG_MEMBERS()
#endif      

    struct SGCoreGlobals
    {
        __GPRECHECK();
        size_t                  ObjectType;
        cue_t                   Cue;
        size_t                  CueLen;
        size_t                  DataSize;
        size_t                  DataAlign;
        size_t                  DataReserved;
        size_t                  DataSizePadded;
        refcount_t              Row;
        size_t                  PageSizeInInstances;
        void*                   __prelease;
        //void*                 __pacquire;
        __GPOSTCHECK();
    }; // gcore_globals

    // This is the common interface for SGCoreRef types
    struct SGCoreInt
    {
    };

#define GCORE_REF_MEMBERS(baseType)             \
    __GPRECHECK();                              \
    __GCORE_REF_DEBUG_MEMBERS();                \
    god::refcount_t             __nRefCount;    \
    const god::SGCoreGlobals    *Globals;       \
    baseType                    *Instance;      \
    __GPOSTCHECK();

#define GCORE_REF_STATIC_MEMBERS()          \
    __GCORE_REF_STATIC_DEBUG_MEMBERS();     \
    static const god::cue_t __kCue;         \
    static const uint32_t   __kDataSize;    \
    static const uint8_t    __kCueLen;

#if defined(GCORE_REF_AS_TEMPLATE)
    template <typename _TBase> struct gcore_ref : public SGCoreInt  
    {                                                               
        GCORE_REF_MEMBERS(_TBase);                                          
    public:                                                         
        GCORE_REF_STATIC_MEMBERS(); 
    };
#   define GODS_REF(baseType) god::gcore_ref<baseType>              
#   define __GCORE_REF_DECLARATION(baseType)
#else
#   define GODS_REF(baseType) __SGCoreRef##baseType
#   define __GCORE_REF_DECLARATION(baseType)                \
        struct GODS_REF(baseType) : public god::SGCoreInt   \
        {                                                   \
            GCORE_REF_MEMBERS(baseType);                    \
        public:                                             \
            GCORE_REF_STATIC_MEMBERS();                     \
        }
#endif
} // namespace

//------------------------------------------------------------------------------------
//---------------------------------------- gcore.h
//------------------------------------------------------------------------------------

// Core POD structs ------------------------------------------------------------------
#define __GODS_REF_PREFIX   gref_
#define __GODS_REF_POSTFIX  
#define GODS_REF_PREFIX     grefh_
#define GODS_REF_POSTFIX    
#define __GODS(Token)   gref_##Token
#define GODS(Token)     grefh_##Token


#define GDECLARE_COMMON_TYPES(baseType) \
    __GCORE_REF_DECLARATION(baseType);  

#if defined(GCORE_REF_AS_TEMPLATE)
#   define GDECLARE_COMMON_TYPEDEFS(baseType)   \
        typedef struct GODS_REF(baseType)   __GODS(baseType), *GODS(baseType);  
        //typedef   god::gnco_ptr<baseType>     __GPtrNCO_##baseType;   \
        //typedef   god::glist<baseType>        __GListNCO_##baseType;
#else
#   define GDECLARE_COMMON_TYPEDEFS(baseType)   \
        typedef struct GODS_REF(baseType)   __GODS(baseType), *GODS(baseType);  
#endif

// This macro is used to declare factory/refcount functions for the structures that implement them
#define __GDECLARE_COMMON_MEMORY_FUNCTIONS(baseType)                                                \
    void                grelease    ( __GODS(baseType)** inout_pCoreInstance );                     \
    void                grelease    ( __GODS(baseType)** inout_pCoreInstances, uint32_t* nCount );  \
    __GODS(baseType)*   gacquire    ( __GODS(baseType)* in_coreInstance );                          \
    size_t              gwritable   ( const __GODS(baseType)* in_Instance );                        \
    baseType*           gget        ( __GODS(baseType)* in_GInstance );                             \
    const baseType*     gget        ( const __GODS(baseType)* in_GInstance );

#define __GDECLARE_COMMON_COPIABLE_FUNCTIONS(baseType)                                                          \
    void                gcreate     ( __GODS(baseType)** inout_pCoreInstance );                                 \
    void                gcreate     ( __GODS(baseType)** inout_pCoreInstance, uint32_t nCount );                \
    void                gcreate     ( __GODS(baseType)** inout_pCoreInstance, const baseType& in_InitData );    \
    void                gcreate     ( __GODS(baseType)** p2, const baseType* lstInstances, uint32_t nCount );   \
    void                gcopy       ( __GODS(baseType)* dst_Target  , const __GODS(baseType)* src_Data );       \
    void                gclone      ( __GODS(baseType)** out_pTarget, const __GODS(baseType)* src_Data );       \
    void                gget        ( baseType& out_SData, const __GODS(baseType)* in_GInstance );

// This macro declares functions to retrieve formatted informative text about the structures. These must be coded individually for each structure 
#define __GDECLARE_COMMON_DEBUG_STRING_FUNCTIONS(baseType)                                                      \
    void printInfoString( const baseType* in_Data );                                                            \
    void printInfoString( const __GODS(baseType)* in_Data );                                                    \
    void getInfoString( wchar_t* dst_pOutputBuffer, uint32_t nBufferSize,   const baseType* in_Data );          \
    void getInfoString( wchar_t* dst_pOutputBuffer, uint32_t nBufferSize,   const __GODS(baseType)* in_Data );  \
    void getInfoString( char* dst_pOutputBuffer, uint32_t nBufferSize,      const __GODS(baseType)* in_Data );  \
    void getInfoString( char* dst_pOutputBuffer, uint32_t nBufferSize,      const baseType* in_Data );

#define __GDECLARE_POD_MEMORY_FUNCTIONS(baseType)                                   \
    __GDECLARE_COMMON_MEMORY_FUNCTIONS(baseType);                                   \
    __GDECLARE_COMMON_COPIABLE_FUNCTIONS(baseType);                                 \
    int32_t gcompare( const __GODS(baseType)* in_A, const __GODS(baseType)* in_B ); \
    int32_t gcompare( const baseType* in_A, const baseType* in_B );

// This macro is used to declare read/write functions of the structure data (serialization)
#define __GDECLARE_POD_SERIALIZATION_FUNCTIONS(baseType)                                                                                \
    uint32_t fileDeserializeData( __GODS(baseType)** out_lstDataInstances, uint32_t in_nInstanceCount, FILE* in_fp );                   \
    uint32_t fileSerializeData  ( __GODS(baseType)* const* in_lstDataInstances, uint32_t in_nInstanceCount, FILE* out_fp );             \
    uint32_t memDeserializeData ( __GODS(baseType)** out_lstDataInstances, uint32_t in_nInstanceCount, const void* in_pMemoryBuffer );  \
    uint32_t memSerializeData   ( __GODS(baseType)* const* in_lstDataInstances, uint32_t in_nInstanceCount, void* out_pMemoryBuffer );

#define __GDECLARE_POD_STREAMING_FUNCTIONS( baseType )                                                                                              \
    uint32_t fileReadData ( __GODS(baseType)** out_lstDataInstances, uint32_t in_nInstanceCount, FILE* in_fp );                                     \
    uint32_t fileWriteData( __GODS(baseType)* const* in_lstDataInstances, uint32_t in_nInstanceCount, FILE* out_fp, const baseType* DefaultData );  \
    uint32_t memReadData  ( __GODS(baseType)** out_lstDataInstances, uint32_t in_nInstanceCount, const void* in_pMemoryBuffer );                    \
    uint32_t memWriteData ( __GODS(baseType)*  const* in_lstDataInstances, uint32_t in_nInstanceCount, void* out_pMemoryBuffer, const baseType* DefaultData );

// This macro is used to declare all core functions at once
#define __GDECLARE_POD_FUNCTIONS(baseType)              \
    __GDECLARE_POD_MEMORY_FUNCTIONS(baseType);          \
    __GDECLARE_POD_STREAMING_FUNCTIONS(baseType);       \
    __GDECLARE_POD_SERIALIZATION_FUNCTIONS(baseType);   \
    __GDECLARE_COMMON_DEBUG_STRING_FUNCTIONS(baseType);

#if defined(GCORE_REF_AS_TEMPLATE)
#   define GDECLARE_POD_TYPEDEFS GDECLARE_COMMON_TYPEDEFS
        //typedef   god::gobj_ptr<baseType>     __GPtrObj_##baseType;       \
        //typedef   god::gpod_ptr<baseType>     __GPtrPOD_##baseType;       \
        //typedef   god::gpodx_ptr<baseType>    __GPtrPODX_##baseType;      \
        //typedef   god::gobj_list<baseType>    __GListObj_##baseType;      \
        //typedef   god::gpod_list<baseType>    __GListPOD_##baseType;      \
        //typedef   god::gpod_grid2d<baseType>  __GGrid2DPOD_##baseType;
#else
#   define GDECLARE_POD_TYPEDEFS GDECLARE_COMMON_TYPEDEFS
#endif
#define GDECLARE_POD(baseType)          \
    GDECLARE_COMMON_TYPES(baseType);    \
    GDECLARE_POD_TYPEDEFS(baseType);    \
    __GDECLARE_POD_FUNCTIONS(baseType);

//-----------------------------------------------------------------------------// //--------------------------------------------------------------------------//
// This macro is used to declare all core functions at once
#define GDECLARE_NCO_NO_TYPEDEFS(baseType)                  \
    __GDECLARE_COMMON_MEMORY_FUNCTIONS(baseType);           \
    __GDECLARE_COMMON_DEBUG_STRING_FUNCTIONS(baseType);     \
    void galloc(__GODS(baseType)** inout_pCoreInstance);    \
    void galloc(__GODS(baseType)** inout_pCoreInstance, uint32_t nCount);

#define GDECLARE_NCO_TYPEDEFS GDECLARE_COMMON_TYPEDEFS
#define GDECLARE_NCO(baseType)          \
    GDECLARE_COMMON_TYPES(baseType);    \
    GDECLARE_NCO_TYPEDEFS(baseType);    \
    GDECLARE_NCO_NO_TYPEDEFS(baseType);

#if defined(GCORE_REF_AS_TEMPLATE)
#define GDECLARE_OBJ_TYPEDEFS GDECLARE_COMMON_TYPEDEFS
    //typedef   god::gobj_ptr<baseType>     __GPtrObj_##baseType;   \
    //typedef   god::gobj_list<baseType>    __GListObj_##baseType;
#else
#define GDECLARE_OBJ_TYPEDEFS GDECLARE_COMMON_TYPEDEFS
#endif
#define GDECLARE_OBJ(baseType)          \
    GDECLARE_COMMON_TYPES(baseType);    \
    GDECLARE_OBJ_TYPEDEFS(baseType);    \
    GDECLARE_NCO_NO_TYPEDEFS(baseType); \
    __GDECLARE_COMMON_COPIABLE_FUNCTIONS(baseType);

You can find the whole thing at the GitHub repository

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.