/*
* Nekolib: An extention to the standard libraries for ease of use
* Copyright (C) 2018 Rebekah Rowe
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#pragma once
#include
#include
namespace neko {
// Is to be used like an unordered map, but by replacing hashing with iteration,
// it can be faster with a small amount of items Compared to boost::flat_map,
// they do not have an unordered version thus my implimentation is surprisingly
// faster.
template
class UnorderedFlatMap {
public:
using bucket_values = std::pair;
using bucket_type = std::vector;
using iterator = typename bucket_type::iterator;
using const_iterator = typename bucket_type::const_iterator;
UnorderedFlatMap() {}
UnorderedFlatMap(const bucket_type& _bucket) { this = _bucket; }
UnorderedFlatMap(std::initializer_list _bucket) {
bucket_type tmp = _bucket;
*this = tmp;
}
// vector funcs
inline void operator=(const bucket_type& input) {
this->clear();
for (const auto& i : input)
this->insert(i); // We do this to multiple same keys
}
inline void clear() { this->bucket.clear(); }
inline auto size() const { return this->bucket.size(); }
inline auto begin() const {
return this->bucket.begin();
} // TODO: fix iterators
inline auto end() const { return this->bucket.end(); }
// map funcs
inline std::pair insert(const bucket_values& in) {
auto find = this->find(in.first);
if (find != this->end()) { // Gotta retain normal map behaviour
throw "Element already exists!";
return {find, false};
} else {
this->bucket.push_back(in);
return {this->bucket.end() - 1, true};
}
}
inline auto emplace(T_Key key,
T_Value val) { // is this really what emplace is lmao
return this->insert({key, val});
}
inline void erase(const T_Key& in) { // by value
auto find = this->find(in);
if (find == this->end())
throw "Element doesnt exist";
else
bucket.erase(find);
}
inline void erase(iterator in) { // by iterator
bucket.erase(in);
}
inline void erase(const_iterator in) { // by iterator
bucket.erase(in);
}
inline T_Value& operator[](const T_Key& i) {
auto find = this->find(i);
if (find != this->end()) return find->second;
return this->insert({i, T_Value()}).first->second;
}
inline auto find(const T_Key& in) {
return std::find_if(this->bucket.begin(), this->bucket.end(),
[&](auto i) { return in == i.first; });
}
inline const auto find(const T_Key& in) const {
return std::find_if(this->bucket.begin(), this->bucket.end(),
[&](auto i) { return in == i.first; });
}
private:
bucket_type bucket;
};
// TODO, recreate boost::circular_buffer with static sizes
} // namespace neko