Skip to content

Instantly share code, notes, and snippets.

@hatsusato
Last active January 1, 2016 03:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hatsusato/8086303 to your computer and use it in GitHub Desktop.
Save hatsusato/8086303 to your computer and use it in GitHub Desktop.
snipet of union in C++11 for KMC Advent Calendar 2013
class U {
enum class Tag { String, Vector } tag;
union {
std::string s;
std::vector<int> v;
};
void Clean() {
switch (tag) {
case Tag::String:
s.~basic_string();
break;
case Tag::Vector:
v.~vector();
break;
default:
assert(0); // Never reached
}
}
void Assign(const std::string& src) { new (&s) std::string{src}; }
void Assign(const std::vector<int>& src) { new (&v) std::vector<int>{src}; }
public:
U(const char* src) : tag{Tag::String}, s{src} {}
U(std::initializer_list<int> src) : tag{Tag::Vector}, v{src} {}
U(const U& src) : tag{src.tag} {
switch (tag) {
case Tag::String:
Assign(src.s);
break;
case Tag::Vector:
Assign(src.v);
break;
default:
assert(0); // Never reached
}
}
U& operator=(const U& rhs) {
if (tag == rhs.tag) {
switch (tag) {
case Tag::String:
s = rhs.s;
break;
case Tag::Vector:
v = rhs.v;
break;
default:
assert(0); // Never reached
}
} else {
Clean();
tag = rhs.tag;
switch (tag) {
case Tag::String:
Assign(rhs.s);
break;
case Tag::Vector:
Assign(rhs.v);
break;
default:
assert(0); // Never reached
}
}
return *this;
}
~U() { Clean(); }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment