Skip to content

Instantly share code, notes, and snippets.

@Mkalo
Created June 8, 2017 04:24
Show Gist options
  • Save Mkalo/be97f5df8e5edbf6a8e31c753bc7df54 to your computer and use it in GitHub Desktop.
Save Mkalo/be97f5df8e5edbf6a8e31c753bc7df54 to your computer and use it in GitHub Desktop.
#include <bits/stdc++.h>
struct Key {
union {
int64_t num;
std::string* str;
};
enum {
NUMBER,
STRING
} type;
Key(int64_t num) : num(num), type(NUMBER) { }
Key(std::string str) : str(new std::string(str)), type(STRING) { }
Key(const char* cp) : str(new std::string(cp)), type(STRING) { }
Key& operator=(const Key& other) {
type = other.type;
switch (other.type) {
case STRING:
str = new std::string(*other.str);
break;
case NUMBER:
num = other.num;
break;
default:
break;
}
}
Key(const Key& other) {
operator=(other);
}
~Key() {
if (type == STRING) {
delete str;
}
}
bool operator<(const Key& rhs) const {
if (type == STRING && rhs.type == STRING) {
return *str < *rhs.str;
} else if (type == NUMBER && rhs.type == NUMBER) {
return num < rhs.num;
} else {
return type < rhs.type;
}
}
friend std::ostream& operator<<(std::ostream& os, const Key& val);
};
struct Value {
union {
int64_t num;
std::string* str;
};
enum {
NIL,
NUMBER,
STRING
} type;
Value() : type(NIL) { }
Value(int64_t num) : num(num), type(NUMBER) { }
Value(std::string str) : str(new std::string(str)), type(STRING) { }
Value(const char* cp) : str(new std::string(cp)), type(STRING) { }
Value& operator=(const Value& other) {
type = other.type;
switch (other.type) {
case STRING:
str = new std::string(*other.str);
break;
case NUMBER:
num = other.num;
break;
default:
break;
}
}
Value(const Value& other) {
operator=(other);
}
~Value() {
if (type == STRING) {
delete str;
}
}
friend std::ostream& operator<<(std::ostream& os, const Value& val);
};
std::ostream& operator<<(std::ostream& os, const Value& val) {
switch (val.type) {
case Value::STRING:
os << *val.str;
break;
case Value::NUMBER:
os << val.num;
break;
default:
os << "nil";
}
return os;
}
std::ostream& operator<<(std::ostream& os, const Key& val) {
switch (val.type) {
case Key::STRING:
os << *val.str;
break;
case Key::NUMBER:
os << val.num;
break;
default:
os << "nil";
}
return os;
}
class Table {
public:
typedef typename std::map<Key, Value>::iterator iterator;
typedef typename std::map<Key, Value>::const_iterator const_iterator;
Table() = default;
Table(std::initializer_list<std::pair<Key, Value>> list) {
for (const auto& it : list) {
m[it.first] = it.second;
}
}
inline iterator begin() { return m.begin(); }
inline const_iterator begin() const { return m.begin(); }
inline iterator end() { return m.end(); }
inline const_iterator end() const { return m.end(); }
inline iterator find(const Key& key) { return m.find(key); }
inline const_iterator find(const Key& key) const { return m.find(key); }
inline void insert(iterator first, iterator last) { m.insert(first, last); }
inline void insert(const_iterator first, const_iterator last) { m.insert(first, last); }
inline bool insert(const Key& key, const Value& value) { return m.emplace(key, value).second; }
inline void reset() { m.clear(); };
Value& operator[](const Key& key) {
return m[key];
}
void print() {
for (const auto& it : m) {
std::cout << it.first << " = " << it.second << std::endl;
}
}
private:
std::map<Key, Value> m;
};
int main() {
Table t {
{"bbb", "aaaaaa"}
};
t[1] = 2;
t["zxzx"] = "adsad";
t[3] = "zdasd";
for (const auto& v : t) {
std::cout << v.first << ", " << v.second << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment