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