1c5f01b2fSopenharmony_ci// __ _____ _____ _____ 2c5f01b2fSopenharmony_ci// __| | __| | | | JSON for Modern C++ 3c5f01b2fSopenharmony_ci// | | |__ | | | | | | version 3.11.2 4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5c5f01b2fSopenharmony_ci// 6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT 8c5f01b2fSopenharmony_ci 9c5f01b2fSopenharmony_ci#pragma once 10c5f01b2fSopenharmony_ci 11c5f01b2fSopenharmony_ci#include <functional> // equal_to, less 12c5f01b2fSopenharmony_ci#include <initializer_list> // initializer_list 13c5f01b2fSopenharmony_ci#include <iterator> // input_iterator_tag, iterator_traits 14c5f01b2fSopenharmony_ci#include <memory> // allocator 15c5f01b2fSopenharmony_ci#include <stdexcept> // for out_of_range 16c5f01b2fSopenharmony_ci#include <type_traits> // enable_if, is_convertible 17c5f01b2fSopenharmony_ci#include <utility> // pair 18c5f01b2fSopenharmony_ci#include <vector> // vector 19c5f01b2fSopenharmony_ci 20c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_scope.hpp> 21c5f01b2fSopenharmony_ci#include <nlohmann/detail/meta/type_traits.hpp> 22c5f01b2fSopenharmony_ci 23c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_BEGIN 24c5f01b2fSopenharmony_ci 25c5f01b2fSopenharmony_ci/// ordered_map: a minimal map-like container that preserves insertion order 26c5f01b2fSopenharmony_ci/// for use within nlohmann::basic_json<ordered_map> 27c5f01b2fSopenharmony_citemplate <class Key, class T, class IgnoredLess = std::less<Key>, 28c5f01b2fSopenharmony_ci class Allocator = std::allocator<std::pair<const Key, T>>> 29c5f01b2fSopenharmony_ci struct ordered_map : std::vector<std::pair<const Key, T>, Allocator> 30c5f01b2fSopenharmony_ci{ 31c5f01b2fSopenharmony_ci using key_type = Key; 32c5f01b2fSopenharmony_ci using mapped_type = T; 33c5f01b2fSopenharmony_ci using Container = std::vector<std::pair<const Key, T>, Allocator>; 34c5f01b2fSopenharmony_ci using iterator = typename Container::iterator; 35c5f01b2fSopenharmony_ci using const_iterator = typename Container::const_iterator; 36c5f01b2fSopenharmony_ci using size_type = typename Container::size_type; 37c5f01b2fSopenharmony_ci using value_type = typename Container::value_type; 38c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_14 39c5f01b2fSopenharmony_ci using key_compare = std::equal_to<>; 40c5f01b2fSopenharmony_ci#else 41c5f01b2fSopenharmony_ci using key_compare = std::equal_to<Key>; 42c5f01b2fSopenharmony_ci#endif 43c5f01b2fSopenharmony_ci 44c5f01b2fSopenharmony_ci // Explicit constructors instead of `using Container::Container` 45c5f01b2fSopenharmony_ci // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4) 46c5f01b2fSopenharmony_ci ordered_map() noexcept(noexcept(Container())) : Container{} {} 47c5f01b2fSopenharmony_ci explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {} 48c5f01b2fSopenharmony_ci template <class It> 49c5f01b2fSopenharmony_ci ordered_map(It first, It last, const Allocator& alloc = Allocator()) 50c5f01b2fSopenharmony_ci : Container{first, last, alloc} {} 51c5f01b2fSopenharmony_ci ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() ) 52c5f01b2fSopenharmony_ci : Container{init, alloc} {} 53c5f01b2fSopenharmony_ci 54c5f01b2fSopenharmony_ci std::pair<iterator, bool> emplace(const key_type& key, T&& t) 55c5f01b2fSopenharmony_ci { 56c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 57c5f01b2fSopenharmony_ci { 58c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 59c5f01b2fSopenharmony_ci { 60c5f01b2fSopenharmony_ci return {it, false}; 61c5f01b2fSopenharmony_ci } 62c5f01b2fSopenharmony_ci } 63c5f01b2fSopenharmony_ci Container::emplace_back(key, std::forward<T>(t)); 64c5f01b2fSopenharmony_ci return {std::prev(this->end()), true}; 65c5f01b2fSopenharmony_ci } 66c5f01b2fSopenharmony_ci 67c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 68c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 69c5f01b2fSopenharmony_ci std::pair<iterator, bool> emplace(KeyType && key, T && t) 70c5f01b2fSopenharmony_ci { 71c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 72c5f01b2fSopenharmony_ci { 73c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 74c5f01b2fSopenharmony_ci { 75c5f01b2fSopenharmony_ci return {it, false}; 76c5f01b2fSopenharmony_ci } 77c5f01b2fSopenharmony_ci } 78c5f01b2fSopenharmony_ci Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t)); 79c5f01b2fSopenharmony_ci return {std::prev(this->end()), true}; 80c5f01b2fSopenharmony_ci } 81c5f01b2fSopenharmony_ci 82c5f01b2fSopenharmony_ci T& operator[](const key_type& key) 83c5f01b2fSopenharmony_ci { 84c5f01b2fSopenharmony_ci return emplace(key, T{}).first->second; 85c5f01b2fSopenharmony_ci } 86c5f01b2fSopenharmony_ci 87c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 88c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 89c5f01b2fSopenharmony_ci T & operator[](KeyType && key) 90c5f01b2fSopenharmony_ci { 91c5f01b2fSopenharmony_ci return emplace(std::forward<KeyType>(key), T{}).first->second; 92c5f01b2fSopenharmony_ci } 93c5f01b2fSopenharmony_ci 94c5f01b2fSopenharmony_ci const T& operator[](const key_type& key) const 95c5f01b2fSopenharmony_ci { 96c5f01b2fSopenharmony_ci return at(key); 97c5f01b2fSopenharmony_ci } 98c5f01b2fSopenharmony_ci 99c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 100c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 101c5f01b2fSopenharmony_ci const T & operator[](KeyType && key) const 102c5f01b2fSopenharmony_ci { 103c5f01b2fSopenharmony_ci return at(std::forward<KeyType>(key)); 104c5f01b2fSopenharmony_ci } 105c5f01b2fSopenharmony_ci 106c5f01b2fSopenharmony_ci T& at(const key_type& key) 107c5f01b2fSopenharmony_ci { 108c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 109c5f01b2fSopenharmony_ci { 110c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 111c5f01b2fSopenharmony_ci { 112c5f01b2fSopenharmony_ci return it->second; 113c5f01b2fSopenharmony_ci } 114c5f01b2fSopenharmony_ci } 115c5f01b2fSopenharmony_ci 116c5f01b2fSopenharmony_ci JSON_THROW(std::out_of_range("key not found")); 117c5f01b2fSopenharmony_ci } 118c5f01b2fSopenharmony_ci 119c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 120c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 121c5f01b2fSopenharmony_ci T & at(KeyType && key) 122c5f01b2fSopenharmony_ci { 123c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 124c5f01b2fSopenharmony_ci { 125c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 126c5f01b2fSopenharmony_ci { 127c5f01b2fSopenharmony_ci return it->second; 128c5f01b2fSopenharmony_ci } 129c5f01b2fSopenharmony_ci } 130c5f01b2fSopenharmony_ci 131c5f01b2fSopenharmony_ci JSON_THROW(std::out_of_range("key not found")); 132c5f01b2fSopenharmony_ci } 133c5f01b2fSopenharmony_ci 134c5f01b2fSopenharmony_ci const T& at(const key_type& key) const 135c5f01b2fSopenharmony_ci { 136c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 137c5f01b2fSopenharmony_ci { 138c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 139c5f01b2fSopenharmony_ci { 140c5f01b2fSopenharmony_ci return it->second; 141c5f01b2fSopenharmony_ci } 142c5f01b2fSopenharmony_ci } 143c5f01b2fSopenharmony_ci 144c5f01b2fSopenharmony_ci JSON_THROW(std::out_of_range("key not found")); 145c5f01b2fSopenharmony_ci } 146c5f01b2fSopenharmony_ci 147c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 148c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 149c5f01b2fSopenharmony_ci const T & at(KeyType && key) const 150c5f01b2fSopenharmony_ci { 151c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 152c5f01b2fSopenharmony_ci { 153c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 154c5f01b2fSopenharmony_ci { 155c5f01b2fSopenharmony_ci return it->second; 156c5f01b2fSopenharmony_ci } 157c5f01b2fSopenharmony_ci } 158c5f01b2fSopenharmony_ci 159c5f01b2fSopenharmony_ci JSON_THROW(std::out_of_range("key not found")); 160c5f01b2fSopenharmony_ci } 161c5f01b2fSopenharmony_ci 162c5f01b2fSopenharmony_ci size_type erase(const key_type& key) 163c5f01b2fSopenharmony_ci { 164c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 165c5f01b2fSopenharmony_ci { 166c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 167c5f01b2fSopenharmony_ci { 168c5f01b2fSopenharmony_ci // Since we cannot move const Keys, re-construct them in place 169c5f01b2fSopenharmony_ci for (auto next = it; ++next != this->end(); ++it) 170c5f01b2fSopenharmony_ci { 171c5f01b2fSopenharmony_ci it->~value_type(); // Destroy but keep allocation 172c5f01b2fSopenharmony_ci new (&*it) value_type{std::move(*next)}; 173c5f01b2fSopenharmony_ci } 174c5f01b2fSopenharmony_ci Container::pop_back(); 175c5f01b2fSopenharmony_ci return 1; 176c5f01b2fSopenharmony_ci } 177c5f01b2fSopenharmony_ci } 178c5f01b2fSopenharmony_ci return 0; 179c5f01b2fSopenharmony_ci } 180c5f01b2fSopenharmony_ci 181c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 182c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 183c5f01b2fSopenharmony_ci size_type erase(KeyType && key) 184c5f01b2fSopenharmony_ci { 185c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 186c5f01b2fSopenharmony_ci { 187c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 188c5f01b2fSopenharmony_ci { 189c5f01b2fSopenharmony_ci // Since we cannot move const Keys, re-construct them in place 190c5f01b2fSopenharmony_ci for (auto next = it; ++next != this->end(); ++it) 191c5f01b2fSopenharmony_ci { 192c5f01b2fSopenharmony_ci it->~value_type(); // Destroy but keep allocation 193c5f01b2fSopenharmony_ci new (&*it) value_type{std::move(*next)}; 194c5f01b2fSopenharmony_ci } 195c5f01b2fSopenharmony_ci Container::pop_back(); 196c5f01b2fSopenharmony_ci return 1; 197c5f01b2fSopenharmony_ci } 198c5f01b2fSopenharmony_ci } 199c5f01b2fSopenharmony_ci return 0; 200c5f01b2fSopenharmony_ci } 201c5f01b2fSopenharmony_ci 202c5f01b2fSopenharmony_ci iterator erase(iterator pos) 203c5f01b2fSopenharmony_ci { 204c5f01b2fSopenharmony_ci return erase(pos, std::next(pos)); 205c5f01b2fSopenharmony_ci } 206c5f01b2fSopenharmony_ci 207c5f01b2fSopenharmony_ci iterator erase(iterator first, iterator last) 208c5f01b2fSopenharmony_ci { 209c5f01b2fSopenharmony_ci if (first == last) 210c5f01b2fSopenharmony_ci { 211c5f01b2fSopenharmony_ci return first; 212c5f01b2fSopenharmony_ci } 213c5f01b2fSopenharmony_ci 214c5f01b2fSopenharmony_ci const auto elements_affected = std::distance(first, last); 215c5f01b2fSopenharmony_ci const auto offset = std::distance(Container::begin(), first); 216c5f01b2fSopenharmony_ci 217c5f01b2fSopenharmony_ci // This is the start situation. We need to delete elements_affected 218c5f01b2fSopenharmony_ci // elements (3 in this example: e, f, g), and need to return an 219c5f01b2fSopenharmony_ci // iterator past the last deleted element (h in this example). 220c5f01b2fSopenharmony_ci // Note that offset is the distance from the start of the vector 221c5f01b2fSopenharmony_ci // to first. We will need this later. 222c5f01b2fSopenharmony_ci 223c5f01b2fSopenharmony_ci // [ a, b, c, d, e, f, g, h, i, j ] 224c5f01b2fSopenharmony_ci // ^ ^ 225c5f01b2fSopenharmony_ci // first last 226c5f01b2fSopenharmony_ci 227c5f01b2fSopenharmony_ci // Since we cannot move const Keys, we re-construct them in place. 228c5f01b2fSopenharmony_ci // We start at first and re-construct (viz. copy) the elements from 229c5f01b2fSopenharmony_ci // the back of the vector. Example for first iteration: 230c5f01b2fSopenharmony_ci 231c5f01b2fSopenharmony_ci // ,--------. 232c5f01b2fSopenharmony_ci // v | destroy e and re-construct with h 233c5f01b2fSopenharmony_ci // [ a, b, c, d, e, f, g, h, i, j ] 234c5f01b2fSopenharmony_ci // ^ ^ 235c5f01b2fSopenharmony_ci // it it + elements_affected 236c5f01b2fSopenharmony_ci 237c5f01b2fSopenharmony_ci for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it) 238c5f01b2fSopenharmony_ci { 239c5f01b2fSopenharmony_ci it->~value_type(); // destroy but keep allocation 240c5f01b2fSopenharmony_ci new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it 241c5f01b2fSopenharmony_ci } 242c5f01b2fSopenharmony_ci 243c5f01b2fSopenharmony_ci // [ a, b, c, d, h, i, j, h, i, j ] 244c5f01b2fSopenharmony_ci // ^ ^ 245c5f01b2fSopenharmony_ci // first last 246c5f01b2fSopenharmony_ci 247c5f01b2fSopenharmony_ci // remove the unneeded elements at the end of the vector 248c5f01b2fSopenharmony_ci Container::resize(this->size() - static_cast<size_type>(elements_affected)); 249c5f01b2fSopenharmony_ci 250c5f01b2fSopenharmony_ci // [ a, b, c, d, h, i, j ] 251c5f01b2fSopenharmony_ci // ^ ^ 252c5f01b2fSopenharmony_ci // first last 253c5f01b2fSopenharmony_ci 254c5f01b2fSopenharmony_ci // first is now pointing past the last deleted element, but we cannot 255c5f01b2fSopenharmony_ci // use this iterator, because it may have been invalidated by the 256c5f01b2fSopenharmony_ci // resize call. Instead, we can return begin() + offset. 257c5f01b2fSopenharmony_ci return Container::begin() + offset; 258c5f01b2fSopenharmony_ci } 259c5f01b2fSopenharmony_ci 260c5f01b2fSopenharmony_ci size_type count(const key_type& key) const 261c5f01b2fSopenharmony_ci { 262c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 263c5f01b2fSopenharmony_ci { 264c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 265c5f01b2fSopenharmony_ci { 266c5f01b2fSopenharmony_ci return 1; 267c5f01b2fSopenharmony_ci } 268c5f01b2fSopenharmony_ci } 269c5f01b2fSopenharmony_ci return 0; 270c5f01b2fSopenharmony_ci } 271c5f01b2fSopenharmony_ci 272c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 273c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 274c5f01b2fSopenharmony_ci size_type count(KeyType && key) const 275c5f01b2fSopenharmony_ci { 276c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 277c5f01b2fSopenharmony_ci { 278c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 279c5f01b2fSopenharmony_ci { 280c5f01b2fSopenharmony_ci return 1; 281c5f01b2fSopenharmony_ci } 282c5f01b2fSopenharmony_ci } 283c5f01b2fSopenharmony_ci return 0; 284c5f01b2fSopenharmony_ci } 285c5f01b2fSopenharmony_ci 286c5f01b2fSopenharmony_ci iterator find(const key_type& key) 287c5f01b2fSopenharmony_ci { 288c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 289c5f01b2fSopenharmony_ci { 290c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 291c5f01b2fSopenharmony_ci { 292c5f01b2fSopenharmony_ci return it; 293c5f01b2fSopenharmony_ci } 294c5f01b2fSopenharmony_ci } 295c5f01b2fSopenharmony_ci return Container::end(); 296c5f01b2fSopenharmony_ci } 297c5f01b2fSopenharmony_ci 298c5f01b2fSopenharmony_ci template<class KeyType, detail::enable_if_t< 299c5f01b2fSopenharmony_ci detail::is_usable_as_key_type<key_compare, key_type, KeyType>::value, int> = 0> 300c5f01b2fSopenharmony_ci iterator find(KeyType && key) 301c5f01b2fSopenharmony_ci { 302c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 303c5f01b2fSopenharmony_ci { 304c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 305c5f01b2fSopenharmony_ci { 306c5f01b2fSopenharmony_ci return it; 307c5f01b2fSopenharmony_ci } 308c5f01b2fSopenharmony_ci } 309c5f01b2fSopenharmony_ci return Container::end(); 310c5f01b2fSopenharmony_ci } 311c5f01b2fSopenharmony_ci 312c5f01b2fSopenharmony_ci const_iterator find(const key_type& key) const 313c5f01b2fSopenharmony_ci { 314c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 315c5f01b2fSopenharmony_ci { 316c5f01b2fSopenharmony_ci if (m_compare(it->first, key)) 317c5f01b2fSopenharmony_ci { 318c5f01b2fSopenharmony_ci return it; 319c5f01b2fSopenharmony_ci } 320c5f01b2fSopenharmony_ci } 321c5f01b2fSopenharmony_ci return Container::end(); 322c5f01b2fSopenharmony_ci } 323c5f01b2fSopenharmony_ci 324c5f01b2fSopenharmony_ci std::pair<iterator, bool> insert( value_type&& value ) 325c5f01b2fSopenharmony_ci { 326c5f01b2fSopenharmony_ci return emplace(value.first, std::move(value.second)); 327c5f01b2fSopenharmony_ci } 328c5f01b2fSopenharmony_ci 329c5f01b2fSopenharmony_ci std::pair<iterator, bool> insert( const value_type& value ) 330c5f01b2fSopenharmony_ci { 331c5f01b2fSopenharmony_ci for (auto it = this->begin(); it != this->end(); ++it) 332c5f01b2fSopenharmony_ci { 333c5f01b2fSopenharmony_ci if (m_compare(it->first, value.first)) 334c5f01b2fSopenharmony_ci { 335c5f01b2fSopenharmony_ci return {it, false}; 336c5f01b2fSopenharmony_ci } 337c5f01b2fSopenharmony_ci } 338c5f01b2fSopenharmony_ci Container::push_back(value); 339c5f01b2fSopenharmony_ci return {--this->end(), true}; 340c5f01b2fSopenharmony_ci } 341c5f01b2fSopenharmony_ci 342c5f01b2fSopenharmony_ci template<typename InputIt> 343c5f01b2fSopenharmony_ci using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category, 344c5f01b2fSopenharmony_ci std::input_iterator_tag>::value>::type; 345c5f01b2fSopenharmony_ci 346c5f01b2fSopenharmony_ci template<typename InputIt, typename = require_input_iter<InputIt>> 347c5f01b2fSopenharmony_ci void insert(InputIt first, InputIt last) 348c5f01b2fSopenharmony_ci { 349c5f01b2fSopenharmony_ci for (auto it = first; it != last; ++it) 350c5f01b2fSopenharmony_ci { 351c5f01b2fSopenharmony_ci insert(*it); 352c5f01b2fSopenharmony_ci } 353c5f01b2fSopenharmony_ci } 354c5f01b2fSopenharmony_ci 355c5f01b2fSopenharmony_ciprivate: 356c5f01b2fSopenharmony_ci JSON_NO_UNIQUE_ADDRESS key_compare m_compare = key_compare(); 357c5f01b2fSopenharmony_ci}; 358c5f01b2fSopenharmony_ci 359c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_END 360