🐛 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 mapped_type = T;
|
||||||
using Container = std::vector<std::pair<const Key, T>, Allocator>;
|
using Container = std::vector<std::pair<const Key, T>, Allocator>;
|
||||||
using typename Container::iterator;
|
using typename Container::iterator;
|
||||||
|
using typename Container::const_iterator;
|
||||||
using typename Container::size_type;
|
using typename Container::size_type;
|
||||||
using typename Container::value_type;
|
using typename Container::value_type;
|
||||||
|
|
||||||
|
@ -97,6 +98,74 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
} // namespace nlohmann
|
||||||
|
|
|
@ -16408,6 +16408,7 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
||||||
using mapped_type = T;
|
using mapped_type = T;
|
||||||
using Container = std::vector<std::pair<const Key, T>, Allocator>;
|
using Container = std::vector<std::pair<const Key, T>, Allocator>;
|
||||||
using typename Container::iterator;
|
using typename Container::iterator;
|
||||||
|
using typename Container::const_iterator;
|
||||||
using typename Container::size_type;
|
using typename Container::size_type;
|
||||||
using typename Container::value_type;
|
using typename Container::value_type;
|
||||||
|
|
||||||
|
@ -16487,6 +16488,74 @@ template <class Key, class T, class IgnoredLess = std::less<Key>,
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
} // namespace nlohmann
|
||||||
|
|
|
@ -122,4 +122,171 @@ TEST_CASE("ordered_map")
|
||||||
CHECK(om.size() == 4);
|
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);
|
jsonAnimals.update(jsonCat);
|
||||||
CHECK(jsonAnimals["animal"] == "cat");
|
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::vector<std::pair<std::string, int64_t>> intData = {std::make_pair("aaaa", 11),
|
||||||
std::make_pair("bbb", 222)
|
std::make_pair("bbb", 222)
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue