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