#include "stdafx.h"
#pragma warning( disable : 4786 )
#include <list>
#include <string>
#include <iostream>
using namespace std;
#define max(a,b) (a)>(b)?(a):(b)
typedef list<int> LIST;
typedef string STRING;
struct MYUNION {
MYUNION() : currtype( NONE ) {}
~MYUNION() {cleanup();}
enum uniontype {NONE,_INT,_LIST,_STRING};
uniontype currtype;
inline int& getint();
inline LIST& getlist();
inline STRING& getstring();
protected:
union {
int i;
unsigned char buff[max(sizeof(LIST),sizeof(STRING))];
} U;
void cleanup();
};
inline int& MYUNION::getint()
{
if( currtype==_INT ) {
return U.i;
} else {
cleanup();
currtype=_INT;
return U.i;
} // else
}
inline LIST& MYUNION::getlist()
{
if( currtype==_LIST ) {
return *(reinterpret_cast<LIST*>(U.buff));
} else {
cleanup();
LIST* ptype = new(U.buff) LIST();
currtype=_LIST;
return *ptype;
} // else
}
inline STRING& MYUNION::getstring()
{
if( currtype==_STRING) {
return *(reinterpret_cast<STRING*>(U.buff));
} else {
cleanup();
STRING* ptype = new(U.buff) STRING();
currtype=_STRING;
return *ptype;
} // else
}
void MYUNION::cleanup()
{
switch( currtype ) {
case _LIST: {
LIST& ptype = getlist();
ptype.~LIST();
break;
} // case
case _STRING: {
STRING& ptype = getstring();
ptype.~STRING();
break;
} // case
default: break;
} // switch
currtype=NONE;
}
int main(int argc, char* argv[])
{
cout << "sizeof(int)=" << sizeof(int) << endl;
cout << "sizeof(LIST)=" << sizeof(LIST) << endl;
cout << "sizeof(STRING)=" << sizeof(STRING) << endl;
cout << "sizeof(MYUNION)=" << sizeof(MYUNION) << endl;
MYUNION u;
// access union as integer
u.getint() = 12345;
cout << "int=" << u.getint() << endl;
// access union as std::list
LIST& list = u.getlist();
list.push_back(5);
list.push_back(10);
list.push_back(15);
LIST::iterator it = list.begin();
while( it != list.end() ) {
cout << "list item=" << *(it) << endl;
it++;
} // while
// access union as std::string
STRING& str = u.getstring();
str = "Hello world!";
cout << "string='" << str.c_str() << "'" << endl;
return 0;
}
End of Listing