• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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