Created
June 8, 2017 04:24
-
-
Save Mkalo/be97f5df8e5edbf6a8e31c753bc7df54 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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