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