🐛 add more functions from std::map to nlohmann::ordered_map
This commit is contained in:
		
							parent
							
								
									e590604822
								
							
						
					
					
						commit
						f13af83a94
					
				
					 4 changed files with 308 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -18,6 +18,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
 | 
			
		|||
    using mapped_type = T;
 | 
			
		||||
    using Container = std::vector<std::pair<const Key, T>, Allocator>;
 | 
			
		||||
    using typename Container::iterator;
 | 
			
		||||
    using typename Container::const_iterator;
 | 
			
		||||
    using typename Container::size_type;
 | 
			
		||||
    using typename Container::value_type;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +98,74 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
 | 
			
		|||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iterator erase(iterator pos)
 | 
			
		||||
    {
 | 
			
		||||
        auto it = pos;
 | 
			
		||||
 | 
			
		||||
        // 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 pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    size_type count(const Key& key) const
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == key)
 | 
			
		||||
            {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iterator find(const Key& key)
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == key)
 | 
			
		||||
            {
 | 
			
		||||
                return it;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Container::end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const_iterator find(const Key& key) const
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == key)
 | 
			
		||||
            {
 | 
			
		||||
                return it;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Container::end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<iterator, bool> insert( value_type&& value )
 | 
			
		||||
    {
 | 
			
		||||
        return emplace(value.first, std::move(value.second));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<iterator, bool> insert( const value_type& value )
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == value.first)
 | 
			
		||||
            {
 | 
			
		||||
                return {it, false};
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Container::push_back(value);
 | 
			
		||||
        return {--this->end(), true};
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace nlohmann
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16408,6 +16408,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
 | 
			
		|||
    using mapped_type = T;
 | 
			
		||||
    using Container = std::vector<std::pair<const Key, T>, Allocator>;
 | 
			
		||||
    using typename Container::iterator;
 | 
			
		||||
    using typename Container::const_iterator;
 | 
			
		||||
    using typename Container::size_type;
 | 
			
		||||
    using typename Container::value_type;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16487,6 +16488,74 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
 | 
			
		|||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iterator erase(iterator pos)
 | 
			
		||||
    {
 | 
			
		||||
        auto it = pos;
 | 
			
		||||
 | 
			
		||||
        // 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 pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    size_type count(const Key& key) const
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == key)
 | 
			
		||||
            {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iterator find(const Key& key)
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == key)
 | 
			
		||||
            {
 | 
			
		||||
                return it;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Container::end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const_iterator find(const Key& key) const
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == key)
 | 
			
		||||
            {
 | 
			
		||||
                return it;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Container::end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<iterator, bool> insert( value_type&& value )
 | 
			
		||||
    {
 | 
			
		||||
        return emplace(value.first, std::move(value.second));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<iterator, bool> insert( const value_type& value )
 | 
			
		||||
    {
 | 
			
		||||
        for (auto it = this->begin(); it != this->end(); ++it)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->first == value.first)
 | 
			
		||||
            {
 | 
			
		||||
                return {it, false};
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Container::push_back(value);
 | 
			
		||||
        return {--this->end(), true};
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace nlohmann
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,4 +122,171 @@ TEST_CASE("ordered_map")
 | 
			
		|||
            CHECK(om.size() == 4);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SECTION("erase")
 | 
			
		||||
    {
 | 
			
		||||
        ordered_map<std::string, std::string> om;
 | 
			
		||||
        om["eins"] = "one";
 | 
			
		||||
        om["zwei"] = "two";
 | 
			
		||||
        om["drei"] = "three";
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            auto it = om.begin();
 | 
			
		||||
            CHECK(it->first == "eins");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it->first == "zwei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it->first == "drei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it == om.end());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SECTION("with Key&&")
 | 
			
		||||
        {
 | 
			
		||||
            CHECK(om.size() == 3);
 | 
			
		||||
            CHECK(om.erase(std::string("eins")) == 1);
 | 
			
		||||
            CHECK(om.size() == 2);
 | 
			
		||||
            CHECK(om.erase(std::string("vier")) == 0);
 | 
			
		||||
            CHECK(om.size() == 2);
 | 
			
		||||
 | 
			
		||||
            auto it = om.begin();
 | 
			
		||||
            CHECK(it->first == "zwei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it->first == "drei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it == om.end());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SECTION("with const Key&&")
 | 
			
		||||
        {
 | 
			
		||||
            const std::string eins = "eins";
 | 
			
		||||
            const std::string vier = "vier";
 | 
			
		||||
            CHECK(om.size() == 3);
 | 
			
		||||
            CHECK(om.erase(eins) == 1);
 | 
			
		||||
            CHECK(om.size() == 2);
 | 
			
		||||
            CHECK(om.erase(vier) == 0);
 | 
			
		||||
            CHECK(om.size() == 2);
 | 
			
		||||
 | 
			
		||||
            auto it = om.begin();
 | 
			
		||||
            CHECK(it->first == "zwei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it->first == "drei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it == om.end());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SECTION("with string literal")
 | 
			
		||||
        {
 | 
			
		||||
            CHECK(om.size() == 3);
 | 
			
		||||
            CHECK(om.erase("eins") == 1);
 | 
			
		||||
            CHECK(om.size() == 2);
 | 
			
		||||
            CHECK(om.erase("vier") == 0);
 | 
			
		||||
            CHECK(om.size() == 2);
 | 
			
		||||
 | 
			
		||||
            auto it = om.begin();
 | 
			
		||||
            CHECK(it->first == "zwei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it->first == "drei");
 | 
			
		||||
            ++it;
 | 
			
		||||
            CHECK(it == om.end());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SECTION("with iterator")
 | 
			
		||||
        {
 | 
			
		||||
            CHECK(om.size() == 3);
 | 
			
		||||
            CHECK(om.begin()->first == "eins");
 | 
			
		||||
            CHECK(std::next(om.begin(), 1)->first == "zwei");
 | 
			
		||||
            CHECK(std::next(om.begin(), 2)->first == "drei");
 | 
			
		||||
 | 
			
		||||
            auto it = om.erase(om.begin());
 | 
			
		||||
            CHECK(it->first == "zwei");
 | 
			
		||||
            CHECK(om.size() == 2);
 | 
			
		||||
 | 
			
		||||
            auto it2 = om.begin();
 | 
			
		||||
            CHECK(it2->first == "zwei");
 | 
			
		||||
            ++it2;
 | 
			
		||||
            CHECK(it2->first == "drei");
 | 
			
		||||
            ++it2;
 | 
			
		||||
            CHECK(it2 == om.end());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SECTION("count")
 | 
			
		||||
    {
 | 
			
		||||
        ordered_map<std::string, std::string> om;
 | 
			
		||||
        om["eins"] = "one";
 | 
			
		||||
        om["zwei"] = "two";
 | 
			
		||||
        om["drei"] = "three";
 | 
			
		||||
 | 
			
		||||
        const std::string eins("eins");
 | 
			
		||||
        const std::string vier("vier");
 | 
			
		||||
        CHECK(om.count("eins") == 1);
 | 
			
		||||
        CHECK(om.count(std::string("eins")) == 1);
 | 
			
		||||
        CHECK(om.count(eins) == 1);
 | 
			
		||||
        CHECK(om.count("vier") == 0);
 | 
			
		||||
        CHECK(om.count(std::string("vier")) == 0);
 | 
			
		||||
        CHECK(om.count(vier) == 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SECTION("find")
 | 
			
		||||
    {
 | 
			
		||||
        ordered_map<std::string, std::string> om;
 | 
			
		||||
        om["eins"] = "one";
 | 
			
		||||
        om["zwei"] = "two";
 | 
			
		||||
        om["drei"] = "three";
 | 
			
		||||
        const auto com = om;
 | 
			
		||||
 | 
			
		||||
        const std::string eins("eins");
 | 
			
		||||
        const std::string vier("vier");
 | 
			
		||||
        CHECK(om.find("eins") == om.begin());
 | 
			
		||||
        CHECK(om.find(std::string("eins")) == om.begin());
 | 
			
		||||
        CHECK(om.find(eins) == om.begin());
 | 
			
		||||
        CHECK(om.find("vier") == om.end());
 | 
			
		||||
        CHECK(om.find(std::string("vier")) == om.end());
 | 
			
		||||
        CHECK(om.find(vier) == om.end());
 | 
			
		||||
 | 
			
		||||
        CHECK(com.find("eins") == com.begin());
 | 
			
		||||
        CHECK(com.find(std::string("eins")) == com.begin());
 | 
			
		||||
        CHECK(com.find(eins) == com.begin());
 | 
			
		||||
        CHECK(com.find("vier") == com.end());
 | 
			
		||||
        CHECK(com.find(std::string("vier")) == com.end());
 | 
			
		||||
        CHECK(com.find(vier) == com.end());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SECTION("insert")
 | 
			
		||||
    {
 | 
			
		||||
        ordered_map<std::string, std::string> om;
 | 
			
		||||
        om["eins"] = "one";
 | 
			
		||||
        om["zwei"] = "two";
 | 
			
		||||
        om["drei"] = "three";
 | 
			
		||||
 | 
			
		||||
        SECTION("const value_type&")
 | 
			
		||||
        {
 | 
			
		||||
            ordered_map<std::string, std::string>::value_type vt1 {"eins", "1"};
 | 
			
		||||
            ordered_map<std::string, std::string>::value_type vt4 {"vier", "four"};
 | 
			
		||||
 | 
			
		||||
            auto res1 = om.insert(vt1);
 | 
			
		||||
            CHECK(res1.first == om.begin());
 | 
			
		||||
            CHECK(res1.second == false);
 | 
			
		||||
            CHECK(om.size() == 3);
 | 
			
		||||
 | 
			
		||||
            auto res4 = om.insert(vt4);
 | 
			
		||||
            CHECK(res4.first == om.begin() + 3);
 | 
			
		||||
            CHECK(res4.second == true);
 | 
			
		||||
            CHECK(om.size() == 4);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SECTION("value_type&&")
 | 
			
		||||
        {
 | 
			
		||||
            auto res1 = om.insert({"eins", "1"});
 | 
			
		||||
            CHECK(res1.first == om.begin());
 | 
			
		||||
            CHECK(res1.second == false);
 | 
			
		||||
            CHECK(om.size() == 3);
 | 
			
		||||
 | 
			
		||||
            auto res4 = om.insert({"vier", "four"});
 | 
			
		||||
            CHECK(res4.first == om.begin() + 3);
 | 
			
		||||
            CHECK(res4.second == true);
 | 
			
		||||
            CHECK(om.size() == 4);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1984,6 +1984,9 @@ TEST_CASE("regression tests")
 | 
			
		|||
        jsonAnimals.update(jsonCat);
 | 
			
		||||
        CHECK(jsonAnimals["animal"] == "cat");
 | 
			
		||||
 | 
			
		||||
        auto jsonAnimals_parsed = nlohmann::ordered_json::parse(jsonAnimals.dump());
 | 
			
		||||
        CHECK(jsonAnimals == jsonAnimals_parsed);
 | 
			
		||||
 | 
			
		||||
        std::vector<std::pair<std::string, int64_t>> intData = {std::make_pair("aaaa", 11),
 | 
			
		||||
                                                                std::make_pair("bbb", 222)
 | 
			
		||||
                                                               };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue