Merge pull request #2258 from nlohmann/issue2179
Add ordered_json specialization with ordered object keys
This commit is contained in:
		
						commit
						e316f5c5b6
					
				
					 7 changed files with 256 additions and 3 deletions
				
			
		|  | @ -2807,6 +2807,19 @@ uses the standard template types. | |||
| @since version 1.0.0 | ||||
| */ | ||||
| using json = basic_json<>; | ||||
| 
 | ||||
| template<class Key, class T, class IgnoredLess, class Allocator> | ||||
| struct ordered_map; | ||||
| 
 | ||||
| /*!
 | ||||
| @brief ordered JSON class | ||||
| 
 | ||||
| This type preserves the insertion order of object keys. | ||||
| 
 | ||||
| @since version 3.9.0 | ||||
| */ | ||||
| using ordered_json = basic_json<nlohmann::ordered_map>; | ||||
| 
 | ||||
| }  // namespace nlohmann
 | ||||
| 
 | ||||
| #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
 | ||||
|  | @ -15973,6 +15986,79 @@ class serializer | |||
| 
 | ||||
| // #include <nlohmann/json_fwd.hpp>
 | ||||
| 
 | ||||
| // #include <nlohmann/ordered_map.hpp>
 | ||||
| 
 | ||||
| 
 | ||||
| #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
 | ||||
| 
 | ||||
| 
 | ||||
| /*!
 | ||||
| @brief namespace for Niels Lohmann | ||||
|  | @ -16099,7 +16185,7 @@ class basic_json | |||
|         detail::parser_callback_t<basic_json>cb = nullptr, | ||||
|         const bool allow_exceptions = true, | ||||
|         const bool ignore_comments = false | ||||
|     ) | ||||
|                                  ) | ||||
|     { | ||||
|         return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter), | ||||
|                 std::move(cb), allow_exceptions, ignore_comments); | ||||
|  | @ -24635,7 +24721,7 @@ template<> | |||
| inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( | ||||
|     is_nothrow_move_constructible<nlohmann::json>::value&& | ||||
|     is_nothrow_move_assignable<nlohmann::json>::value | ||||
| ) | ||||
|                               ) | ||||
| { | ||||
|     j1.swap(j2); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue