rippled
Loading...
Searching...
No Matches
Issue_test.cpp
1#include <xrpl/basics/UnorderedContainers.h>
2#include <xrpl/beast/unit_test.h>
3#include <xrpl/protocol/Book.h>
4#include <xrpl/protocol/Issue.h>
5
6#include <sys/types.h>
7
8#include <map>
9#include <optional>
10#include <set>
11#include <typeinfo>
12#include <unordered_set>
13
14#if BEAST_MSVC
15#define STL_SET_HAS_EMPLACE 1
16#else
17#define STL_SET_HAS_EMPLACE 0
18#endif
19
20#ifndef XRPL_ASSETS_ENABLE_STD_HASH
21#if BEAST_MAC || BEAST_IOS
22#define XRPL_ASSETS_ENABLE_STD_HASH 0
23#else
24#define XRPL_ASSETS_ENABLE_STD_HASH 1
25#endif
26#endif
27
28namespace xrpl {
29
31{
32public:
33 using Domain = uint256;
34
35 // Comparison, hash tests for uint60 (via base_uint)
36 template <typename Unsigned>
37 void
39 {
40 Unsigned const u1(1);
41 Unsigned const u2(2);
42 Unsigned const u3(3);
43
44 BEAST_EXPECT(u1 != u2);
45 BEAST_EXPECT(u1 < u2);
46 BEAST_EXPECT(u1 <= u2);
47 BEAST_EXPECT(u2 <= u2);
48 BEAST_EXPECT(u2 == u2);
49 BEAST_EXPECT(u2 >= u2);
50 BEAST_EXPECT(u3 >= u2);
51 BEAST_EXPECT(u3 > u2);
52
54
55 BEAST_EXPECT(hash(u1) == hash(u1));
56 BEAST_EXPECT(hash(u2) == hash(u2));
57 BEAST_EXPECT(hash(u3) == hash(u3));
58 BEAST_EXPECT(hash(u1) != hash(u2));
59 BEAST_EXPECT(hash(u1) != hash(u3));
60 BEAST_EXPECT(hash(u2) != hash(u3));
61 }
62
63 //--------------------------------------------------------------------------
64
65 // Comparison, hash tests for Issue
66 template <class Issue>
67 void
69 {
70 Currency const c1(1);
71 AccountID const i1(1);
72 Currency const c2(2);
73 AccountID const i2(2);
74 Currency const c3(3);
75 AccountID const i3(3);
76
77 BEAST_EXPECT(Issue(c1, i1) != Issue(c2, i1));
78 BEAST_EXPECT(Issue(c1, i1) < Issue(c2, i1));
79 BEAST_EXPECT(Issue(c1, i1) <= Issue(c2, i1));
80 BEAST_EXPECT(Issue(c2, i1) <= Issue(c2, i1));
81 BEAST_EXPECT(Issue(c2, i1) == Issue(c2, i1));
82 BEAST_EXPECT(Issue(c2, i1) >= Issue(c2, i1));
83 BEAST_EXPECT(Issue(c3, i1) >= Issue(c2, i1));
84 BEAST_EXPECT(Issue(c3, i1) > Issue(c2, i1));
85 BEAST_EXPECT(Issue(c1, i1) != Issue(c1, i2));
86 BEAST_EXPECT(Issue(c1, i1) < Issue(c1, i2));
87 BEAST_EXPECT(Issue(c1, i1) <= Issue(c1, i2));
88 BEAST_EXPECT(Issue(c1, i2) <= Issue(c1, i2));
89 BEAST_EXPECT(Issue(c1, i2) == Issue(c1, i2));
90 BEAST_EXPECT(Issue(c1, i2) >= Issue(c1, i2));
91 BEAST_EXPECT(Issue(c1, i3) >= Issue(c1, i2));
92 BEAST_EXPECT(Issue(c1, i3) > Issue(c1, i2));
93
95
96 BEAST_EXPECT(hash(Issue(c1, i1)) == hash(Issue(c1, i1)));
97 BEAST_EXPECT(hash(Issue(c1, i2)) == hash(Issue(c1, i2)));
98 BEAST_EXPECT(hash(Issue(c1, i3)) == hash(Issue(c1, i3)));
99 BEAST_EXPECT(hash(Issue(c2, i1)) == hash(Issue(c2, i1)));
100 BEAST_EXPECT(hash(Issue(c2, i2)) == hash(Issue(c2, i2)));
101 BEAST_EXPECT(hash(Issue(c2, i3)) == hash(Issue(c2, i3)));
102 BEAST_EXPECT(hash(Issue(c3, i1)) == hash(Issue(c3, i1)));
103 BEAST_EXPECT(hash(Issue(c3, i2)) == hash(Issue(c3, i2)));
104 BEAST_EXPECT(hash(Issue(c3, i3)) == hash(Issue(c3, i3)));
105 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i2)));
106 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i3)));
107 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i1)));
108 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i2)));
109 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i3)));
110 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i1)));
111 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i2)));
112 BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i3)));
113 }
114
115 template <class Set>
116 void
118 {
119 Currency const c1(1);
120 AccountID const i1(1);
121 Currency const c2(2);
122 AccountID const i2(2);
123 Issue const a1(c1, i1);
124 Issue const a2(c2, i2);
125
126 {
127 Set c;
128
129 c.insert(a1);
130 if (!BEAST_EXPECT(c.size() == 1))
131 return;
132 c.insert(a2);
133 if (!BEAST_EXPECT(c.size() == 2))
134 return;
135
136 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
137 return;
138 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
139 return;
140 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
141 return;
142 if (!BEAST_EXPECT(c.empty()))
143 return;
144 }
145
146 {
147 Set c;
148
149 c.insert(a1);
150 if (!BEAST_EXPECT(c.size() == 1))
151 return;
152 c.insert(a2);
153 if (!BEAST_EXPECT(c.size() == 2))
154 return;
155
156 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
157 return;
158 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
159 return;
160 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
161 return;
162 if (!BEAST_EXPECT(c.empty()))
163 return;
164
165#if STL_SET_HAS_EMPLACE
166 c.emplace(c1, i1);
167 if (!BEAST_EXPECT(c.size() == 1))
168 return;
169 c.emplace(c2, i2);
170 if (!BEAST_EXPECT(c.size() == 2))
171 return;
172#endif
173 }
174 }
175
176 template <class Map>
177 void
179 {
180 Currency const c1(1);
181 AccountID const i1(1);
182 Currency const c2(2);
183 AccountID const i2(2);
184 Issue const a1(c1, i1);
185 Issue const a2(c2, i2);
186
187 {
188 Map c;
189
190 c.insert(std::make_pair(a1, 1));
191 if (!BEAST_EXPECT(c.size() == 1))
192 return;
193 c.insert(std::make_pair(a2, 2));
194 if (!BEAST_EXPECT(c.size() == 2))
195 return;
196
197 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
198 return;
199 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
200 return;
201 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
202 return;
203 if (!BEAST_EXPECT(c.empty()))
204 return;
205 }
206
207 {
208 Map c;
209
210 c.insert(std::make_pair(a1, 1));
211 if (!BEAST_EXPECT(c.size() == 1))
212 return;
213 c.insert(std::make_pair(a2, 2));
214 if (!BEAST_EXPECT(c.size() == 2))
215 return;
216
217 if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
218 return;
219 if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
220 return;
221 if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
222 return;
223 if (!BEAST_EXPECT(c.empty()))
224 return;
225 }
226 }
227
228 template <class Set>
229 void
231 {
232 Currency const c1(1);
233 AccountID const i1(1);
234 Currency const c2(2);
235 AccountID const i2(2);
236 Issue const a1(c1, i1);
237 Issue const a2(c2, i2);
238 uint256 const domain1{1};
239 uint256 const domain2{2};
240
241 Set c;
242
243 c.insert(std::make_pair(a1, domain1));
244 if (!BEAST_EXPECT(c.size() == 1))
245 return;
246 c.insert(std::make_pair(a2, domain1));
247 if (!BEAST_EXPECT(c.size() == 2))
248 return;
249 c.insert(std::make_pair(a2, domain2));
250 if (!BEAST_EXPECT(c.size() == 3))
251 return;
252
253 if (!BEAST_EXPECT(c.erase(std::make_pair(Issue(c1, i2), domain1)) == 0))
254 return;
255 if (!BEAST_EXPECT(c.erase(std::make_pair(a1, domain1)) == 1))
256 return;
257 if (!BEAST_EXPECT(c.erase(std::make_pair(a2, domain1)) == 1))
258 return;
259 if (!BEAST_EXPECT(c.erase(std::make_pair(a2, domain2)) == 1))
260 return;
261 if (!BEAST_EXPECT(c.empty()))
262 return;
263 }
264
265 template <class Map>
266 void
268 {
269 Currency const c1(1);
270 AccountID const i1(1);
271 Currency const c2(2);
272 AccountID const i2(2);
273 Issue const a1(c1, i1);
274 Issue const a2(c2, i2);
275 uint256 const domain1{1};
276 uint256 const domain2{2};
277
278 Map c;
279
280 c.insert(std::make_pair(std::make_pair(a1, domain1), 1));
281 if (!BEAST_EXPECT(c.size() == 1))
282 return;
283 c.insert(std::make_pair(std::make_pair(a2, domain1), 2));
284 if (!BEAST_EXPECT(c.size() == 2))
285 return;
286 c.insert(std::make_pair(std::make_pair(a2, domain2), 2));
287 if (!BEAST_EXPECT(c.size() == 3))
288 return;
289
290 if (!BEAST_EXPECT(c.erase(std::make_pair(Issue(c1, i2), domain1)) == 0))
291 return;
292 if (!BEAST_EXPECT(c.erase(std::make_pair(a1, domain1)) == 1))
293 return;
294 if (!BEAST_EXPECT(c.erase(std::make_pair(a2, domain1)) == 1))
295 return;
296 if (!BEAST_EXPECT(c.erase(std::make_pair(a2, domain2)) == 1))
297 return;
298 if (!BEAST_EXPECT(c.empty()))
299 return;
300 }
301
302 void
304 {
305 testcase("std::set <std::pair<Issue, Domain>>");
306 testIssueDomainSet<std::set<std::pair<Issue, Domain>>>();
307
308 testcase("std::set <std::pair<Issue, Domain>>");
309 testIssueDomainSet<std::set<std::pair<Issue, Domain>>>();
310
311 testcase("hash_set <std::pair<Issue, Domain>>");
312 testIssueDomainSet<hash_set<std::pair<Issue, Domain>>>();
313
314 testcase("hash_set <std::pair<Issue, Domain>>");
315 testIssueDomainSet<hash_set<std::pair<Issue, Domain>>>();
316 }
317
318 void
320 {
321 testcase("std::map <std::pair<Issue, Domain>, int>");
322 testIssueDomainMap<std::map<std::pair<Issue, Domain>, int>>();
323
324 testcase("std::map <std::pair<Issue, Domain>, int>");
325 testIssueDomainMap<std::map<std::pair<Issue, Domain>, int>>();
326
327#if XRPL_ASSETS_ENABLE_STD_HASH
328 testcase("hash_map <std::pair<Issue, Domain>, int>");
329 testIssueDomainMap<hash_map<std::pair<Issue, Domain>, int>>();
330
331 testcase("hash_map <std::pair<Issue, Domain>, int>");
332 testIssueDomainMap<hash_map<std::pair<Issue, Domain>, int>>();
333
334 testcase("hardened_hash_map <std::pair<Issue, Domain>, int>");
335 testIssueDomainMap<hardened_hash_map<std::pair<Issue, Domain>, int>>();
336
337 testcase("hardened_hash_map <std::pair<Issue, Domain>, int>");
338 testIssueDomainMap<hardened_hash_map<std::pair<Issue, Domain>, int>>();
339#endif
340 }
341
342 void
344 {
345 testcase("std::set <Issue>");
346 testIssueSet<std::set<Issue>>();
347
348 testcase("std::set <Issue>");
349 testIssueSet<std::set<Issue>>();
350
351#if XRPL_ASSETS_ENABLE_STD_HASH
352 testcase("std::unordered_set <Issue>");
353 testIssueSet<std::unordered_set<Issue>>();
354
355 testcase("std::unordered_set <Issue>");
356 testIssueSet<std::unordered_set<Issue>>();
357#endif
358
359 testcase("hash_set <Issue>");
360 testIssueSet<hash_set<Issue>>();
361
362 testcase("hash_set <Issue>");
363 testIssueSet<hash_set<Issue>>();
364 }
365
366 void
368 {
369 testcase("std::map <Issue, int>");
370 testIssueMap<std::map<Issue, int>>();
371
372 testcase("std::map <Issue, int>");
373 testIssueMap<std::map<Issue, int>>();
374
375#if XRPL_ASSETS_ENABLE_STD_HASH
376 testcase("std::unordered_map <Issue, int>");
377 testIssueMap<std::unordered_map<Issue, int>>();
378
379 testcase("std::unordered_map <Issue, int>");
380 testIssueMap<std::unordered_map<Issue, int>>();
381
382 testcase("hash_map <Issue, int>");
383 testIssueMap<hash_map<Issue, int>>();
384
385 testcase("hash_map <Issue, int>");
386 testIssueMap<hash_map<Issue, int>>();
387
388#endif
389 }
390
391 //--------------------------------------------------------------------------
392
393 // Comparison, hash tests for Book
394 template <class Book>
395 void
397 {
398 Currency const c1(1);
399 AccountID const i1(1);
400 Currency const c2(2);
401 AccountID const i2(2);
402 Currency const c3(3);
403 AccountID const i3(3);
404
405 Issue a1(c1, i1);
406 Issue a2(c1, i2);
407 Issue a3(c2, i2);
408 Issue a4(c3, i2);
409 uint256 const domain1{1};
410 uint256 const domain2{2};
411
412 // Books without domains
413 BEAST_EXPECT(Book(a1, a2, std::nullopt) != Book(a2, a3, std::nullopt));
414 BEAST_EXPECT(Book(a1, a2, std::nullopt) < Book(a2, a3, std::nullopt));
415 BEAST_EXPECT(Book(a1, a2, std::nullopt) <= Book(a2, a3, std::nullopt));
416 BEAST_EXPECT(Book(a2, a3, std::nullopt) <= Book(a2, a3, std::nullopt));
417 BEAST_EXPECT(Book(a2, a3, std::nullopt) == Book(a2, a3, std::nullopt));
418 BEAST_EXPECT(Book(a2, a3, std::nullopt) >= Book(a2, a3, std::nullopt));
419 BEAST_EXPECT(Book(a3, a4, std::nullopt) >= Book(a2, a3, std::nullopt));
420 BEAST_EXPECT(Book(a3, a4, std::nullopt) > Book(a2, a3, std::nullopt));
421
422 // test domain books
423 {
424 // Books with different domains
425 BEAST_EXPECT(Book(a2, a3, domain1) != Book(a2, a3, domain2));
426 BEAST_EXPECT(Book(a2, a3, domain1) < Book(a2, a3, domain2));
427 BEAST_EXPECT(Book(a2, a3, domain2) > Book(a2, a3, domain1));
428
429 // One Book has a domain, the other does not
430 BEAST_EXPECT(Book(a2, a3, domain1) != Book(a2, a3, std::nullopt));
431 BEAST_EXPECT(Book(a2, a3, std::nullopt) < Book(a2, a3, domain1));
432 BEAST_EXPECT(Book(a2, a3, domain1) > Book(a2, a3, std::nullopt));
433
434 // Both Books have the same domain
435 BEAST_EXPECT(Book(a2, a3, domain1) == Book(a2, a3, domain1));
436 BEAST_EXPECT(Book(a2, a3, domain2) == Book(a2, a3, domain2));
437 BEAST_EXPECT(Book(a2, a3, std::nullopt) == Book(a2, a3, std::nullopt));
438
439 // Both Books have no domain
440 BEAST_EXPECT(Book(a2, a3, std::nullopt) == Book(a2, a3, std::nullopt));
441
442 // Testing comparisons with >= and <=
443
444 // When comparing books with domain1 vs domain2
445 BEAST_EXPECT(Book(a2, a3, domain1) <= Book(a2, a3, domain2));
446 BEAST_EXPECT(Book(a2, a3, domain2) >= Book(a2, a3, domain1));
447 BEAST_EXPECT(Book(a2, a3, domain1) >= Book(a2, a3, domain1));
448 BEAST_EXPECT(Book(a2, a3, domain2) <= Book(a2, a3, domain2));
449
450 // One Book has domain1 and the other has no domain
451 BEAST_EXPECT(Book(a2, a3, domain1) > Book(a2, a3, std::nullopt));
452 BEAST_EXPECT(Book(a2, a3, std::nullopt) < Book(a2, a3, domain1));
453
454 // One Book has domain2 and the other has no domain
455 BEAST_EXPECT(Book(a2, a3, domain2) > Book(a2, a3, std::nullopt));
456 BEAST_EXPECT(Book(a2, a3, std::nullopt) < Book(a2, a3, domain2));
457
458 // Comparing two Books with no domains
459 BEAST_EXPECT(Book(a2, a3, std::nullopt) <= Book(a2, a3, std::nullopt));
460 BEAST_EXPECT(Book(a2, a3, std::nullopt) >= Book(a2, a3, std::nullopt));
461
462 // Test case where domain1 is less than domain2
463 BEAST_EXPECT(Book(a2, a3, domain1) <= Book(a2, a3, domain2));
464 BEAST_EXPECT(Book(a2, a3, domain2) >= Book(a2, a3, domain1));
465
466 // Test case where domain2 is equal to domain1
467 BEAST_EXPECT(Book(a2, a3, domain1) >= Book(a2, a3, domain1));
468 BEAST_EXPECT(Book(a2, a3, domain1) <= Book(a2, a3, domain1));
469
470 // More test cases involving a4 (with domain2)
471
472 // Comparing Book with domain2 (a4) to a Book with domain1
473 BEAST_EXPECT(Book(a2, a3, domain1) < Book(a3, a4, domain2));
474 BEAST_EXPECT(Book(a3, a4, domain2) > Book(a2, a3, domain1));
475
476 // Comparing Book with domain2 (a4) to a Book with no domain
477 BEAST_EXPECT(Book(a3, a4, domain2) > Book(a2, a3, std::nullopt));
478 BEAST_EXPECT(Book(a2, a3, std::nullopt) < Book(a3, a4, domain2));
479
480 // Comparing Book with domain2 (a4) to a Book with the same domain
481 BEAST_EXPECT(Book(a3, a4, domain2) == Book(a3, a4, domain2));
482
483 // Comparing Book with domain2 (a4) to a Book with domain1
484 BEAST_EXPECT(Book(a2, a3, domain1) < Book(a3, a4, domain2));
485 BEAST_EXPECT(Book(a3, a4, domain2) > Book(a2, a3, domain1));
486 }
487
488 std::hash<Book> hash;
489
490 // log << std::hex << hash (Book (a1, a2));
491 // log << std::hex << hash (Book (a1, a2));
492 //
493 // log << std::hex << hash (Book (a1, a3));
494 // log << std::hex << hash (Book (a1, a3));
495 //
496 // log << std::hex << hash (Book (a1, a4));
497 // log << std::hex << hash (Book (a1, a4));
498 //
499 // log << std::hex << hash (Book (a2, a3));
500 // log << std::hex << hash (Book (a2, a3));
501 //
502 // log << std::hex << hash (Book (a2, a4));
503 // log << std::hex << hash (Book (a2, a4));
504 //
505 // log << std::hex << hash (Book (a3, a4));
506 // log << std::hex << hash (Book (a3, a4));
507
508 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) == hash(Book(a1, a2, std::nullopt)));
509 BEAST_EXPECT(hash(Book(a1, a3, std::nullopt)) == hash(Book(a1, a3, std::nullopt)));
510 BEAST_EXPECT(hash(Book(a1, a4, std::nullopt)) == hash(Book(a1, a4, std::nullopt)));
511 BEAST_EXPECT(hash(Book(a2, a3, std::nullopt)) == hash(Book(a2, a3, std::nullopt)));
512 BEAST_EXPECT(hash(Book(a2, a4, std::nullopt)) == hash(Book(a2, a4, std::nullopt)));
513 BEAST_EXPECT(hash(Book(a3, a4, std::nullopt)) == hash(Book(a3, a4, std::nullopt)));
514
515 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) != hash(Book(a1, a3, std::nullopt)));
516 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) != hash(Book(a1, a4, std::nullopt)));
517 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) != hash(Book(a2, a3, std::nullopt)));
518 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) != hash(Book(a2, a4, std::nullopt)));
519 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) != hash(Book(a3, a4, std::nullopt)));
520
521 // Books with domain
522 BEAST_EXPECT(hash(Book(a1, a2, domain1)) == hash(Book(a1, a2, domain1)));
523 BEAST_EXPECT(hash(Book(a1, a3, domain1)) == hash(Book(a1, a3, domain1)));
524 BEAST_EXPECT(hash(Book(a1, a4, domain1)) == hash(Book(a1, a4, domain1)));
525 BEAST_EXPECT(hash(Book(a2, a3, domain1)) == hash(Book(a2, a3, domain1)));
526 BEAST_EXPECT(hash(Book(a2, a4, domain1)) == hash(Book(a2, a4, domain1)));
527 BEAST_EXPECT(hash(Book(a3, a4, domain1)) == hash(Book(a3, a4, domain1)));
528 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) == hash(Book(a1, a2, std::nullopt)));
529
530 // Comparing Books with domain1 vs no domain
531 BEAST_EXPECT(hash(Book(a1, a2, std::nullopt)) != hash(Book(a1, a2, domain1)));
532 BEAST_EXPECT(hash(Book(a1, a3, std::nullopt)) != hash(Book(a1, a3, domain1)));
533 BEAST_EXPECT(hash(Book(a1, a4, std::nullopt)) != hash(Book(a1, a4, domain1)));
534 BEAST_EXPECT(hash(Book(a2, a3, std::nullopt)) != hash(Book(a2, a3, domain1)));
535 BEAST_EXPECT(hash(Book(a2, a4, std::nullopt)) != hash(Book(a2, a4, domain1)));
536 BEAST_EXPECT(hash(Book(a3, a4, std::nullopt)) != hash(Book(a3, a4, domain1)));
537
538 // Books with domain1 but different Issues
539 BEAST_EXPECT(hash(Book(a1, a2, domain1)) != hash(Book(a1, a3, domain1)));
540 BEAST_EXPECT(hash(Book(a1, a2, domain1)) != hash(Book(a1, a4, domain1)));
541 BEAST_EXPECT(hash(Book(a2, a3, domain1)) != hash(Book(a2, a4, domain1)));
542 BEAST_EXPECT(hash(Book(a1, a2, domain1)) != hash(Book(a2, a3, domain1)));
543 BEAST_EXPECT(hash(Book(a2, a4, domain1)) != hash(Book(a3, a4, domain1)));
544 BEAST_EXPECT(hash(Book(a3, a4, domain1)) != hash(Book(a1, a4, domain1)));
545
546 // Books with domain1 and domain2
547 BEAST_EXPECT(hash(Book(a1, a2, domain1)) != hash(Book(a1, a2, domain2)));
548 BEAST_EXPECT(hash(Book(a1, a3, domain1)) != hash(Book(a1, a3, domain2)));
549 BEAST_EXPECT(hash(Book(a1, a4, domain1)) != hash(Book(a1, a4, domain2)));
550 BEAST_EXPECT(hash(Book(a2, a3, domain1)) != hash(Book(a2, a3, domain2)));
551 BEAST_EXPECT(hash(Book(a2, a4, domain1)) != hash(Book(a2, a4, domain2)));
552 BEAST_EXPECT(hash(Book(a3, a4, domain1)) != hash(Book(a3, a4, domain2)));
553 }
554
555 //--------------------------------------------------------------------------
556
557 template <class Set>
558 void
560 {
561 Currency const c1(1);
562 AccountID const i1(1);
563 Currency const c2(2);
564 AccountID const i2(2);
565 Issue const a1(c1, i1);
566 Issue const a2(c2, i2);
567 Book const b1(a1, a2, std::nullopt);
568 Book const b2(a2, a1, std::nullopt);
569
570 uint256 const domain1{1};
571 uint256 const domain2{2};
572
573 Book const b1_d1(a1, a2, domain1);
574 Book const b2_d1(a2, a1, domain1);
575 Book const b1_d2(a1, a2, domain2);
576 Book const b2_d2(a2, a1, domain2);
577
578 {
579 Set c;
580
581 c.insert(b1);
582 if (!BEAST_EXPECT(c.size() == 1))
583 return;
584 c.insert(b2);
585 if (!BEAST_EXPECT(c.size() == 2))
586 return;
587
588 if (!BEAST_EXPECT(c.erase(Book(a1, a1, std::nullopt)) == 0))
589 return;
590 if (!BEAST_EXPECT(c.erase(Book(a1, a2, std::nullopt)) == 1))
591 return;
592 if (!BEAST_EXPECT(c.erase(Book(a2, a1, std::nullopt)) == 1))
593 return;
594 if (!BEAST_EXPECT(c.empty()))
595 return;
596 }
597
598 {
599 Set c;
600
601 c.insert(b1);
602 if (!BEAST_EXPECT(c.size() == 1))
603 return;
604 c.insert(b2);
605 if (!BEAST_EXPECT(c.size() == 2))
606 return;
607
608 if (!BEAST_EXPECT(c.erase(Book(a1, a1, std::nullopt)) == 0))
609 return;
610 if (!BEAST_EXPECT(c.erase(Book(a1, a2, std::nullopt)) == 1))
611 return;
612 if (!BEAST_EXPECT(c.erase(Book(a2, a1, std::nullopt)) == 1))
613 return;
614 if (!BEAST_EXPECT(c.empty()))
615 return;
616
617#if STL_SET_HAS_EMPLACE
618 c.emplace(a1, a2);
619 if (!BEAST_EXPECT(c.size() == 1))
620 return;
621 c.emplace(a2, a1);
622 if (!BEAST_EXPECT(c.size() == 2))
623 return;
624#endif
625 }
626
627 {
628 Set c;
629
630 c.insert(b1_d1);
631 if (!BEAST_EXPECT(c.size() == 1))
632 return;
633 c.insert(b2_d1);
634 if (!BEAST_EXPECT(c.size() == 2))
635 return;
636 c.insert(b1_d2);
637 if (!BEAST_EXPECT(c.size() == 3))
638 return;
639 c.insert(b2_d2);
640 if (!BEAST_EXPECT(c.size() == 4))
641 return;
642
643 // Try removing non-existent elements
644 if (!BEAST_EXPECT(c.erase(Book(a2, a2, domain1)) == 0))
645 return;
646
647 if (!BEAST_EXPECT(c.erase(Book(a1, a2, domain1)) == 1))
648 return;
649 if (!BEAST_EXPECT(c.erase(Book(a2, a1, domain1)) == 1))
650 return;
651 if (!BEAST_EXPECT(c.size() == 2))
652 return;
653
654 if (!BEAST_EXPECT(c.erase(Book(a1, a2, domain2)) == 1))
655 return;
656 if (!BEAST_EXPECT(c.erase(Book(a2, a1, domain2)) == 1))
657 return;
658 if (!BEAST_EXPECT(c.empty()))
659 return;
660 }
661
662 {
663 Set c;
664
665 c.insert(b1);
666 c.insert(b2);
667 c.insert(b1_d1);
668 c.insert(b2_d1);
669 if (!BEAST_EXPECT(c.size() == 4))
670 return;
671
672 if (!BEAST_EXPECT(c.erase(Book(a1, a2, std::nullopt)) == 1))
673 return;
674 if (!BEAST_EXPECT(c.erase(Book(a2, a1, std::nullopt)) == 1))
675 return;
676 if (!BEAST_EXPECT(c.size() == 2))
677 return;
678
679 if (!BEAST_EXPECT(c.erase(Book(a1, a2, domain1)) == 1))
680 return;
681 if (!BEAST_EXPECT(c.erase(Book(a2, a1, domain1)) == 1))
682 return;
683 if (!BEAST_EXPECT(c.empty()))
684 return;
685 }
686 }
687
688 template <class Map>
689 void
691 {
692 Currency const c1(1);
693 AccountID const i1(1);
694 Currency const c2(2);
695 AccountID const i2(2);
696 Issue const a1(c1, i1);
697 Issue const a2(c2, i2);
698 Book const b1(a1, a2, std::nullopt);
699 Book const b2(a2, a1, std::nullopt);
700
701 uint256 const domain1{1};
702 uint256 const domain2{2};
703
704 Book const b1_d1(a1, a2, domain1);
705 Book const b2_d1(a2, a1, domain1);
706 Book const b1_d2(a1, a2, domain2);
707 Book const b2_d2(a2, a1, domain2);
708
709 // typename Map::value_type value_type;
710 // std::pair <Book const, int> value_type;
711
712 {
713 Map c;
714
715 // c.insert (value_type (b1, 1));
716 c.insert(std::make_pair(b1, 1));
717 if (!BEAST_EXPECT(c.size() == 1))
718 return;
719 // c.insert (value_type (b2, 2));
720 c.insert(std::make_pair(b2, 1));
721 if (!BEAST_EXPECT(c.size() == 2))
722 return;
723
724 if (!BEAST_EXPECT(c.erase(Book(a1, a1, std::nullopt)) == 0))
725 return;
726 if (!BEAST_EXPECT(c.erase(Book(a1, a2, std::nullopt)) == 1))
727 return;
728 if (!BEAST_EXPECT(c.erase(Book(a2, a1, std::nullopt)) == 1))
729 return;
730 if (!BEAST_EXPECT(c.empty()))
731 return;
732 }
733
734 {
735 Map c;
736
737 // c.insert (value_type (b1, 1));
738 c.insert(std::make_pair(b1, 1));
739 if (!BEAST_EXPECT(c.size() == 1))
740 return;
741 // c.insert (value_type (b2, 2));
742 c.insert(std::make_pair(b2, 1));
743 if (!BEAST_EXPECT(c.size() == 2))
744 return;
745
746 if (!BEAST_EXPECT(c.erase(Book(a1, a1, std::nullopt)) == 0))
747 return;
748 if (!BEAST_EXPECT(c.erase(Book(a1, a2, std::nullopt)) == 1))
749 return;
750 if (!BEAST_EXPECT(c.erase(Book(a2, a1, std::nullopt)) == 1))
751 return;
752 if (!BEAST_EXPECT(c.empty()))
753 return;
754 }
755
756 {
757 Map c;
758
759 c.insert(std::make_pair(b1_d1, 10));
760 if (!BEAST_EXPECT(c.size() == 1))
761 return;
762 c.insert(std::make_pair(b2_d1, 20));
763 if (!BEAST_EXPECT(c.size() == 2))
764 return;
765 c.insert(std::make_pair(b1_d2, 30));
766 if (!BEAST_EXPECT(c.size() == 3))
767 return;
768 c.insert(std::make_pair(b2_d2, 40));
769 if (!BEAST_EXPECT(c.size() == 4))
770 return;
771
772 // Try removing non-existent elements
773 if (!BEAST_EXPECT(c.erase(Book(a2, a2, domain1)) == 0))
774 return;
775
776 if (!BEAST_EXPECT(c.erase(Book(a1, a2, domain1)) == 1))
777 return;
778 if (!BEAST_EXPECT(c.erase(Book(a2, a1, domain1)) == 1))
779 return;
780 if (!BEAST_EXPECT(c.size() == 2))
781 return;
782
783 if (!BEAST_EXPECT(c.erase(Book(a1, a2, domain2)) == 1))
784 return;
785 if (!BEAST_EXPECT(c.erase(Book(a2, a1, domain2)) == 1))
786 return;
787 if (!BEAST_EXPECT(c.empty()))
788 return;
789 }
790
791 {
792 Map c;
793
794 c.insert(std::make_pair(b1, 1));
795 c.insert(std::make_pair(b2, 2));
796 c.insert(std::make_pair(b1_d1, 3));
797 c.insert(std::make_pair(b2_d1, 4));
798 if (!BEAST_EXPECT(c.size() == 4))
799 return;
800
801 // Try removing non-existent elements
802 if (!BEAST_EXPECT(c.erase(Book(a1, a1, domain1)) == 0))
803 return;
804 if (!BEAST_EXPECT(c.erase(Book(a2, a2, domain2)) == 0))
805 return;
806
807 if (!BEAST_EXPECT(c.erase(Book(a1, a2, std::nullopt)) == 1))
808 return;
809 if (!BEAST_EXPECT(c.erase(Book(a2, a1, std::nullopt)) == 1))
810 return;
811 if (!BEAST_EXPECT(c.size() == 2))
812 return;
813
814 if (!BEAST_EXPECT(c.erase(Book(a1, a2, domain1)) == 1))
815 return;
816 if (!BEAST_EXPECT(c.erase(Book(a2, a1, domain1)) == 1))
817 return;
818 if (!BEAST_EXPECT(c.empty()))
819 return;
820 }
821 }
822
823 void
825 {
826 testcase("std::set <Book>");
827 testBookSet<std::set<Book>>();
828
829 testcase("std::set <Book>");
830 testBookSet<std::set<Book>>();
831
832#if XRPL_ASSETS_ENABLE_STD_HASH
833 testcase("std::unordered_set <Book>");
834 testBookSet<std::unordered_set<Book>>();
835
836 testcase("std::unordered_set <Book>");
837 testBookSet<std::unordered_set<Book>>();
838#endif
839
840 testcase("hash_set <Book>");
841 testBookSet<hash_set<Book>>();
842
843 testcase("hash_set <Book>");
844 testBookSet<hash_set<Book>>();
845 }
846
847 void
849 {
850 testcase("std::map <Book, int>");
851 testBookMap<std::map<Book, int>>();
852
853 testcase("std::map <Book, int>");
854 testBookMap<std::map<Book, int>>();
855
856#if XRPL_ASSETS_ENABLE_STD_HASH
857 testcase("std::unordered_map <Book, int>");
858 testBookMap<std::unordered_map<Book, int>>();
859
860 testcase("std::unordered_map <Book, int>");
861 testBookMap<std::unordered_map<Book, int>>();
862
863 testcase("hash_map <Book, int>");
864 testBookMap<hash_map<Book, int>>();
865
866 testcase("hash_map <Book, int>");
867 testBookMap<hash_map<Book, int>>();
868#endif
869 }
870
871 //--------------------------------------------------------------------------
872
873 void
874 run() override
875 {
876 testcase("Currency");
877 testUnsigned<Currency>();
878
879 testcase("AccountID");
880 testUnsigned<AccountID>();
881
882 // ---
883
884 testcase("Issue");
885 testIssue<Issue>();
886
887 testcase("Issue");
888 testIssue<Issue>();
889
892
893 // ---
894
895 testcase("Book");
896 testBook<Book>();
897
898 testcase("Book");
899 testBook<Book>();
900
901 testBookSets();
902 testBookMaps();
903
904 // ---
907 }
908};
909
910BEAST_DEFINE_TESTSUITE(Issue, protocol, xrpl);
911
912} // namespace xrpl
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:148
Specifies an order book.
Definition Book.h:17
void run() override
Runs the suite.
void testIssueDomainMaps()
void testIssueDomainMap()
void testIssueDomainSet()
void testIssueDomainSets()
A currency issued by an account.
Definition Issue.h:14
T is_same_v
T make_pair(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
base_uint< 256 > uint256
Definition base_uint.h:527