Long time no see people,
My god, this section is not how I remember it. So I'll try to release some more advanced code so that perhaps people that used to hang around here come back.
You can used this code to store arbitrary objects in one single collection. However to pass complex objects use only void pointers. Think of this collection as a vector for every object:
Code:
vector< T > Collection;
Collection.push_back( "string" );
Collection.push_back( 123123.023f);
Collection.push_back( 14124 );
cDynamicCast.h:
Code:
#ifndef C_DYNAMIC_CAST
#define C_DYNAMIC_CAST
#include <vector>
#include <string>
using namespace std;
class cRawDynamic;
class cDynamic;
class cDynamicCollectionRaw;
class cDynamicCollection;
class cRawDynamic
{
char* _Data;
unsigned int _Size;
public:
cRawDynamic( const char* Data, const unsigned int Size );
~cRawDynamic();
void GetData( const char** Data, unsigned int* Size );
};
class cDynamic: public cRawDynamic
{ friend cDynamicCollection;
public:
template <typename T>
cDynamic( T Data )
: cRawDynamic( (char*)&Data, sizeof( T ) )
{
}
};
typedef vector< std::pair< string, cDynamic* > > DynamicCollection;
class cDynamicCollectionRaw
{
static unsigned int FindCollection( const DynamicCollection& Collection, const string& Name );
public:
static void AppendToCollection( DynamicCollection &Collection, cDynamic* Appendage, const string& Name );
static void RemoveFromCollection( DynamicCollection &Collection, const string& Name );
static void FreeCollection( DynamicCollection &Collection );
template< typename T >
static T Cast( DynamicCollection &Collection, const string& Name, T& Return )
{
unsigned int Index = 0;
if( ( Index = FindCollection( Collection, Name ) ) != -1 )
{
const char* Data;
unsigned int Size;
Collection[Index].second->GetData( (const char**) &Data, &Size );
return ( Return = *reinterpret_cast< T* > ( const_cast< char* > ( Data ) ) );
}
else throw "Error: cDynamicCollection::Cast: Variable " + Name + "not found";
return (T)NULL;
}
};
class cDynamicCollection: public cDynamicCollectionRaw
{
DynamicCollection _Collection;
public:
cDynamicCollection(){}
~cDynamicCollection()
{
FreeCollection( _Collection );
}
void Remove( const string& Name )
{
RemoveFromCollection( _Collection, Name );
}
template< typename T > T Add( const string& Name, T Value )
{
AppendToCollection( _Collection, new cDynamic( Value ), Name );
return Value;
}
template< typename T > T Get( const string& Name )
{
T Value;
Cast( _Collection, Name, Value );
return Value;
}
};
typedef cDynamicCollection dyn;
#endif
cDynamicCast.cpp
Code:
#include <memory>
#include "cDynamicCast.h"
cRawDynamic::cRawDynamic( const char* Data, const unsigned int Size )
: _Data( new char[ Size ] ), _Size( Size )
{
memcpy( _Data, Data, _Size );
}
cRawDynamic::~cRawDynamic()
{
if( _Data && _Size )
{
delete [] _Data;
_Data = NULL;
_Size = 0;
}
}
void cRawDynamic::GetData( const char** Data, unsigned int* Size )
{
*Data = _Data;
*Size = _Size;
}
unsigned int cDynamicCollectionRaw::FindCollection( const DynamicCollection& Collection, const string& Name )
{
for( unsigned int i = 0; i < Collection.size(); i++ )
{
if( Collection[i].first == Name )
return i;
}
return -1;
}
void cDynamicCollectionRaw::AppendToCollection( DynamicCollection &Collection, cDynamic* Appendage, const string& Name )
{
if( FindCollection( Collection, Name ) == -1 )
Collection.push_back( pair< string, cDynamic* >( Name, Appendage ) );
}
void cDynamicCollectionRaw::RemoveFromCollection( DynamicCollection &Collection, const string& Name )
{
unsigned int Index = 0;
if( ( Index = FindCollection( Collection, Name ) ) != -1 )
{
delete Collection[Index].second;
Collection[Index].second = NULL;
Collection[Index].first = "";
Collection.erase( Collection.begin() + Index );
}
}
void cDynamicCollectionRaw::FreeCollection( DynamicCollection &Collection )
{
for( unsigned int i = 0; i < Collection.size(); i++ )
{
delete Collection[i].second;
Collection[i].second = NULL;
Collection[i].first = "";
}
Collection.clear();
}
usage/main.cpp:
Code:
#include <iostream>
#include "cDynamicCast.h"
using namespace std;
struct MyType
{
int a, b;
};
int main( int argc, char* argv[] )
{
dyn c;
MyType asd = { 1, 2 };
MyType b;
int Int;
string pChar;
c.Add( "int", 123 );
c.Add( "char*", "This is a string" );
c.Add( "MyType", (void*)&asd );
Int = c.Get<int>( "int" );
pChar = c.Get<char*>( "char*" );
b = *c.Get<MyType*>( "MyType" );
cout << Int << endl
<< pChar << endl;
system( "pause" );
return 0;
}