Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <iostream>
- #include <array>
- #include <vector>
- #include <algorithm>
- #include <limits>
- #include <stdexcept>
- #include <chrono>
- #include <unordered_map>
- template <typename T>
- class HashMap {
- using value_type = std::pair<std::string, T>;
- using cont_type = std::array<std::vector<value_type>, std::numeric_limits<unsigned char>::max() + 1>;
- public:
- T& operator [](const std::string& key) {
- if (auto ptr = try_get(key)) {
- return *ptr;
- } else {
- try_add(key, T(), &ptr);
- return *ptr;
- }
- }
- T* try_get(const std::string& key) noexcept {
- auto& vec = container[hashString(key)];
- auto iter = std::find_if(std::begin(vec), std::end(vec), [&](value_type& value) {
- return value.first == key;
- });
- if (iter == std::end(vec)) {
- return nullptr;
- }
- return &iter->second;
- }
- T& get(const std::string& key) {
- if (auto ptr = try_get(key)) {
- return *ptr;
- } else {
- throw std::invalid_argument("key not found");
- }
- }
- bool try_add(std::string key, T value, T **inserted = nullptr) {
- auto& vec = container[hashString(key)];
- auto iter = std::find_if(std::begin(vec), std::end(vec), [&](value_type& value) {
- return value.first == key;
- });
- if (iter == std::end(vec)) {
- vec.push_back(std::make_pair(std::move(key), std::move(value)));
- if (inserted) {
- *inserted = &vec.back().second;
- }
- return true;
- } else {
- if (inserted) {
- *inserted = &iter->second;
- }
- }
- return false;
- }
- T& add(std::string key, T value) {
- T *ptr;
- if (try_add(std::move(key), std::move(value), &ptr)) {
- return *ptr;
- } else {
- throw std::invalid_argument("duplicated key found");
- }
- }
- private:
- static inline unsigned char hashString(const std::string& str) {
- const unsigned char x = std::numeric_limits<unsigned char>::max() >> 1;
- switch (str.length()) {
- case 0:
- return 0;
- case 1:
- return str[0];
- default:
- return ((unsigned char)str[0] & x) + ((unsigned char)str[1] & x);
- }
- }
- private:
- cont_type container;
- };
Advertisement
Add Comment
Please, Sign In to add comment