1 // __ _____ _____ _____ 2 // __| | __| | | | JSON for Modern C++ (supporting code) 3 // | | |__ | | | | | | version 3.11.2 4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 // 6 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7 // SPDX-License-Identifier: MIT 8 9 #include "doctest_compatibility.h" 10 11 #include <nlohmann/json.hpp> 12 using nlohmann::ordered_map; 13 14 15 TEST_CASE("ordered_map") 16 { 17 SECTION("constructor") 18 { 19 SECTION("constructor from iterator range") 20 { 21 std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}}; 22 ordered_map<std::string, std::string> om(m.begin(), m.end()); 23 CHECK(om.size() == 3); 24 } 25 26 SECTION("copy assignment") 27 { 28 std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}}; 29 ordered_map<std::string, std::string> om(m.begin(), m.end()); 30 const auto com = om; 31 om.clear(); // silence a warning by forbidding having "const auto& com = om;" 32 CHECK(com.size() == 3); 33 } 34 } 35 36 SECTION("at") 37 { 38 std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}}; 39 ordered_map<std::string, std::string> om(m.begin(), m.end()); 40 const auto com = om; 41 42 SECTION("with Key&&") 43 { 44 CHECK(om.at(std::string("eins")) == std::string("one")); 45 CHECK(com.at(std::string("eins")) == std::string("one")); 46 CHECK_THROWS_AS(om.at(std::string("vier")), std::out_of_range); 47 CHECK_THROWS_AS(com.at(std::string("vier")), std::out_of_range); 48 } 49 50 SECTION("with const Key&&") 51 { 52 const std::string eins = "eins"; 53 const std::string vier = "vier"; 54 CHECK(om.at(eins) == std::string("one")); 55 CHECK(com.at(eins) == std::string("one")); 56 CHECK_THROWS_AS(om.at(vier), std::out_of_range); 57 CHECK_THROWS_AS(com.at(vier), std::out_of_range); 58 } 59 60 SECTION("with string literal") 61 { 62 CHECK(om.at("eins") == std::string("one")); 63 CHECK(com.at("eins") == std::string("one")); 64 CHECK_THROWS_AS(om.at("vier"), std::out_of_range); 65 CHECK_THROWS_AS(com.at("vier"), std::out_of_range); 66 } 67 } 68 69 SECTION("operator[]") 70 { 71 std::map<std::string, std::string> m {{"eins", "one"}, {"zwei", "two"}, {"drei", "three"}}; 72 ordered_map<std::string, std::string> om(m.begin(), m.end()); 73 const auto com = om; 74 75 SECTION("with Key&&") 76 { 77 CHECK(om[std::string("eins")] == std::string("one")); 78 CHECK(com[std::string("eins")] == std::string("one")); 79 80 CHECK(om[std::string("vier")] == std::string("")); 81 CHECK(om.size() == 4); 82 } 83 84 SECTION("with const Key&&") 85 { 86 const std::string eins = "eins"; 87 const std::string vier = "vier"; 88 89 CHECK(om[eins] == std::string("one")); 90 CHECK(com[eins] == std::string("one")); 91 92 CHECK(om[vier] == std::string("")); 93 CHECK(om.size() == 4); 94 } 95 96 SECTION("with string literal") 97 { 98 CHECK(om["eins"] == std::string("one")); 99 CHECK(com["eins"] == std::string("one")); 100 101 CHECK(om["vier"] == std::string("")); 102 CHECK(om.size() == 4); 103 } 104 } 105 106 SECTION("erase") 107 { 108 ordered_map<std::string, std::string> om; 109 om["eins"] = "one"; 110 om["zwei"] = "two"; 111 om["drei"] = "three"; 112 113 { 114 auto it = om.begin(); 115 CHECK(it->first == "eins"); 116 ++it; 117 CHECK(it->first == "zwei"); 118 ++it; 119 CHECK(it->first == "drei"); 120 ++it; 121 CHECK(it == om.end()); 122 } 123 124 SECTION("with Key&&") 125 { 126 CHECK(om.size() == 3); 127 CHECK(om.erase(std::string("eins")) == 1); 128 CHECK(om.size() == 2); 129 CHECK(om.erase(std::string("vier")) == 0); 130 CHECK(om.size() == 2); 131 132 auto it = om.begin(); 133 CHECK(it->first == "zwei"); 134 ++it; 135 CHECK(it->first == "drei"); 136 ++it; 137 CHECK(it == om.end()); 138 } 139 140 SECTION("with const Key&&") 141 { 142 const std::string eins = "eins"; 143 const std::string vier = "vier"; 144 CHECK(om.size() == 3); 145 CHECK(om.erase(eins) == 1); 146 CHECK(om.size() == 2); 147 CHECK(om.erase(vier) == 0); 148 CHECK(om.size() == 2); 149 150 auto it = om.begin(); 151 CHECK(it->first == "zwei"); 152 ++it; 153 CHECK(it->first == "drei"); 154 ++it; 155 CHECK(it == om.end()); 156 } 157 158 SECTION("with string literal") 159 { 160 CHECK(om.size() == 3); 161 CHECK(om.erase("eins") == 1); 162 CHECK(om.size() == 2); 163 CHECK(om.erase("vier") == 0); 164 CHECK(om.size() == 2); 165 166 auto it = om.begin(); 167 CHECK(it->first == "zwei"); 168 ++it; 169 CHECK(it->first == "drei"); 170 ++it; 171 CHECK(it == om.end()); 172 } 173 174 SECTION("with iterator") 175 { 176 CHECK(om.size() == 3); 177 CHECK(om.begin()->first == "eins"); 178 CHECK(std::next(om.begin(), 1)->first == "zwei"); 179 CHECK(std::next(om.begin(), 2)->first == "drei"); 180 181 auto it = om.erase(om.begin()); 182 CHECK(it->first == "zwei"); 183 CHECK(om.size() == 2); 184 185 auto it2 = om.begin(); 186 CHECK(it2->first == "zwei"); 187 ++it2; 188 CHECK(it2->first == "drei"); 189 ++it2; 190 CHECK(it2 == om.end()); 191 } 192 193 SECTION("with iterator pair") 194 { 195 SECTION("range in the middle") 196 { 197 // need more elements 198 om["vier"] = "four"; 199 om["fünf"] = "five"; 200 201 // delete "zwei" and "drei" 202 auto it = om.erase(om.begin() + 1, om.begin() + 3); 203 CHECK(it->first == "vier"); 204 CHECK(om.size() == 3); 205 } 206 207 SECTION("range at the beginning") 208 { 209 // need more elements 210 om["vier"] = "four"; 211 om["fünf"] = "five"; 212 213 // delete "eins" and "zwei" 214 auto it = om.erase(om.begin(), om.begin() + 2); 215 CHECK(it->first == "drei"); 216 CHECK(om.size() == 3); 217 } 218 219 SECTION("range at the end") 220 { 221 // need more elements 222 om["vier"] = "four"; 223 om["fünf"] = "five"; 224 225 // delete "vier" and "fünf" 226 auto it = om.erase(om.begin() + 3, om.end()); 227 CHECK(it == om.end()); 228 CHECK(om.size() == 3); 229 } 230 } 231 } 232 233 SECTION("count") 234 { 235 ordered_map<std::string, std::string> om; 236 om["eins"] = "one"; 237 om["zwei"] = "two"; 238 om["drei"] = "three"; 239 240 const std::string eins("eins"); 241 const std::string vier("vier"); 242 CHECK(om.count("eins") == 1); 243 CHECK(om.count(std::string("eins")) == 1); 244 CHECK(om.count(eins) == 1); 245 CHECK(om.count("vier") == 0); 246 CHECK(om.count(std::string("vier")) == 0); 247 CHECK(om.count(vier) == 0); 248 } 249 250 SECTION("find") 251 { 252 ordered_map<std::string, std::string> om; 253 om["eins"] = "one"; 254 om["zwei"] = "two"; 255 om["drei"] = "three"; 256 const auto com = om; 257 258 const std::string eins("eins"); 259 const std::string vier("vier"); 260 CHECK(om.find("eins") == om.begin()); 261 CHECK(om.find(std::string("eins")) == om.begin()); 262 CHECK(om.find(eins) == om.begin()); 263 CHECK(om.find("vier") == om.end()); 264 CHECK(om.find(std::string("vier")) == om.end()); 265 CHECK(om.find(vier) == om.end()); 266 267 CHECK(com.find("eins") == com.begin()); 268 CHECK(com.find(std::string("eins")) == com.begin()); 269 CHECK(com.find(eins) == com.begin()); 270 CHECK(com.find("vier") == com.end()); 271 CHECK(com.find(std::string("vier")) == com.end()); 272 CHECK(com.find(vier) == com.end()); 273 } 274 275 SECTION("insert") 276 { 277 ordered_map<std::string, std::string> om; 278 om["eins"] = "one"; 279 om["zwei"] = "two"; 280 om["drei"] = "three"; 281 282 SECTION("const value_type&") 283 { 284 ordered_map<std::string, std::string>::value_type vt1 {"eins", "1"}; 285 ordered_map<std::string, std::string>::value_type vt4 {"vier", "four"}; 286 287 auto res1 = om.insert(vt1); 288 CHECK(res1.first == om.begin()); 289 CHECK(res1.second == false); 290 CHECK(om.size() == 3); 291 292 auto res4 = om.insert(vt4); 293 CHECK(res4.first == om.begin() + 3); 294 CHECK(res4.second == true); 295 CHECK(om.size() == 4); 296 } 297 298 SECTION("value_type&&") 299 { 300 auto res1 = om.insert({"eins", "1"}); 301 CHECK(res1.first == om.begin()); 302 CHECK(res1.second == false); 303 CHECK(om.size() == 3); 304 305 auto res4 = om.insert({"vier", "four"}); 306 CHECK(res4.first == om.begin() + 3); 307 CHECK(res4.second == true); 308 CHECK(om.size() == 4); 309 } 310 } 311 } 312