| #pragma once |
| |
| #include <functional> // less |
| #include <memory> // allocator |
| #include <utility> // pair |
| #include <vector> // vector |
| |
| namespace nlohmann |
| { |
| |
| /// ordered_map: a minimal map-like container that preserves insertion order |
| /// for use within nlohmann::basic_json<ordered_map> |
| template <class Key, class T, class IgnoredLess = std::less<Key>, |
| class Allocator = std::allocator<std::pair<const Key, T>>> |
| struct ordered_map : std::vector<std::pair<const Key, T>, Allocator> |
| { |
| using key_type = Key; |
| using mapped_type = T; |
| using Container = std::vector<std::pair<const Key, T>, Allocator>; |
| using typename Container::iterator; |
| using typename Container::size_type; |
| using typename Container::value_type; |
| |
| // Explicit constructors instead of `using Container::Container` |
| // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) |
| ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {} |
| template <class It> |
| ordered_map(It first, It last, const Allocator& alloc = Allocator()) |
| : Container{first, last, alloc} {} |
| ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() ) |
| : Container{init, alloc} {} |
| |
| std::pair<iterator, bool> emplace(key_type&& key, T&& t) |
| { |
| for (auto it = this->begin(); it != this->end(); ++it) |
| { |
| if (it->first == key) |
| { |
| return {it, false}; |
| } |
| } |
| Container::emplace_back(key, t); |
| return {--this->end(), true}; |
| } |
| |
| T& operator[](Key&& key) |
| { |
| return emplace(std::move(key), T{}).first->second; |
| } |
| |
| size_type erase(const Key& key) |
| { |
| for (auto it = this->begin(); it != this->end(); ++it) |
| { |
| if (it->first == key) |
| { |
| // Since we cannot move const Keys, re-construct them in place |
| for (auto next = it; ++next != this->end(); ++it) |
| { |
| it->~value_type(); // Destroy but keep allocation |
| new (&*it) value_type{std::move(*next)}; |
| } |
| Container::pop_back(); |
| return 1; |
| } |
| } |
| return 0; |
| } |
| }; |
| |
| } // namespace nlohmann |