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