Skip to content

Instantly share code, notes, and snippets.

@Giemsa
Last active December 31, 2015 08:39
Show Gist options
  • Save Giemsa/7962113 to your computer and use it in GitHub Desktop.
Save Giemsa/7962113 to your computer and use it in GitHub Desktop.
共用体をラップしたクラス。あまり役に立ちそうにない。http://jumble-note.blogspot.jp/2013/12/c.html
#include <iostream>
#define def_t(n) \
typename T ## n = __type_util::_void
#define def_m(n) T ## n t ## n;
#define check(n) typename __type_util::is_void<T ## n, T>::type* = 0
#define def_a(n) \
template<typename T> \
inline T _get(const typename __type_util::guard<T ## n, n>::type, check(n)) const { return t ## n; } \
template<typename T> \
inline void _set(const typename __type_util::guard<T ## n, n>::type &t, check(n)) { t ## n = t; _id = n; }
namespace __type_util
{
struct _void { };
template<typename S, typename T>
struct is_void
{
typedef T type;
};
template<typename T>
struct is_void<_void, T>
{ };
template<typename T, int N>
struct guard
{
typedef T type;
};
template<int N>
struct guard<_void, N>
{
typedef guard<_void, N> type;
};
}
template<def_t(1), def_t(2), def_t(3), def_t(4), def_t(5), def_t(6), def_t(7), def_t(8)>
class Union
{
private:
int _id;
union
{
def_m(1)
def_m(2)
def_m(3)
def_m(4)
def_m(5)
def_m(6)
def_m(7)
def_m(8)
};
def_a(1)
def_a(2)
def_a(3)
def_a(4)
def_a(5)
def_a(6)
def_a(7)
def_a(8)
public:
Union() : _id(0) { }
template<typename T>
inline Union(const T &t) : _id(0) { _set<T>(t); }
template<typename T>
inline operator T() const { return _get<T>(T()); }
template<typename T>
inline T get() const { return _get<T>(T()); }
template<typename T>
inline T operator =(const T &t) { _set<T>(t); return t; }
inline int which() const { return _id; }
};
#undef def_a
#undef check
#undef def_m
#undef def_t
int main(int argc, const char * argv[])
{
Union<int, double> x = 100;
// check size
printf("size of x: %lu\n", sizeof(x));
// get int value
const int v = x;
printf("x(type: %d): %d\n", x.which(), v);
// set double value
x = 123.456;
printf("x(type: %d): %f\n", x.which(), x.get<double>());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment