xrpld
Loading...
Searching...
No Matches
MultiApiJson_test.cpp
1#include <xrpl/beast/unit_test/suite.h>
2#include <xrpl/json/json_value.h>
3#include <xrpl/protocol/ApiVersion.h>
4#include <xrpl/protocol/MultiApiJson.h>
5
6#include <array>
7#include <iterator>
8#include <limits>
9#include <optional>
10#include <type_traits>
11#include <utility>
12
13namespace xrpl::test {
14
15namespace {
16
17// This needs to be in a namespace because of deduction guide
18template <typename... Ts>
19struct Overload : Ts...
20{
21 using Ts::operator()...;
22};
23template <typename... Ts>
24Overload(Ts...) -> Overload<Ts...>;
25
26} // namespace
27
29{
30 static auto
31 makeJson(char const* key, int val)
32 {
34 obj1[key] = val;
35 return obj1;
36 }
37
38 void
39 run() override
40 {
42
43 json::Value const obj1 = makeJson("value", 1);
44 json::Value const obj2 = makeJson("value", 2);
45 json::Value const obj3 = makeJson("value", 3);
46 json::Value const jsonNull{};
47
48 MultiApiJson<1, 3> subject{};
49 static_assert(sizeof(subject) == sizeof(subject.val));
50 static_assert(subject.kSize == subject.val.size());
51 static_assert(std::is_same_v<decltype(subject.val), std::array<json::Value, 3>>);
52
53 BEAST_EXPECT(subject.val.size() == 3);
54 BEAST_EXPECT((subject.val == std::array<json::Value, 3>{jsonNull, jsonNull, jsonNull}));
55
56 subject.val[0] = obj1;
57 subject.val[1] = obj2;
58
59 {
60 testcase("forApiVersions, forAllApiVersions");
61
62 // Some static data for test inputs
63 static int const kPrimes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
64 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
65 static_assert(std::size(kPrimes) > RPC::kApiMaximumValidVersion);
66
68 static_assert(
70
71 int productAllVersions = 1;
73 ++i)
74 {
75 auto const index = i - RPC::kApiMinimumSupportedVersion;
76 BEAST_EXPECT(index == s1.index(i));
77 BEAST_EXPECT(s1.valid(i));
78 s1.val[index] = makeJson("value", kPrimes[i]);
79 productAllVersions *= kPrimes[i];
80 }
81 BEAST_EXPECT(!s1.valid(0));
82 BEAST_EXPECT(!s1.valid(RPC::kApiMaximumValidVersion + 1));
83 BEAST_EXPECT(!s1.valid(
84 std::numeric_limits<decltype(RPC::kApiMaximumValidVersion.value)>::max()));
85
86 int result = 1;
89 std::as_const(s1).visit(),
90 [this](json::Value const& json, unsigned int version, int* result) {
91 BEAST_EXPECT(
94 if (BEAST_EXPECT(json.isMember("value")))
95 {
96 *result *= json["value"].asInt();
97 }
98 },
99 &result);
100 BEAST_EXPECT(
101 result ==
104
105 // Check all the values with mutable data
106 forAllApiVersions(s1.visit(), [&s1, this](json::Value& json, auto version) {
107 BEAST_EXPECT(s1.val[s1.index(version)] == json);
108 if (BEAST_EXPECT(json.isMember("value")))
109 {
110 BEAST_EXPECT(json["value"].asInt() == kPrimes[version]);
111 }
112 });
113
114 result = 1;
116 std::as_const(s1).visit(),
117 [this](json::Value const& json, unsigned int version, int* result) {
118 BEAST_EXPECT(
121 if (BEAST_EXPECT(json.isMember("value")))
122 {
123 *result *= json["value"].asInt();
124 }
125 },
126 &result);
127
128 BEAST_EXPECT(result == productAllVersions);
129
130 // Several overloads we want to fail
131 static_assert([](auto&& v) {
132 return !requires {
134 std::forward<decltype(v)>(v).visit(), //
135 [](json::Value&, auto) {}); // missing const
136 };
137 }(std::as_const(s1)));
138 static_assert([](auto&& v) {
139 return !requires {
141 std::forward<decltype(v)>(v).visit(), //
142 [](json::Value&) {}); // missing const
143 };
144 }(std::as_const(s1)));
145 static_assert([](auto&& v) {
146 return !requires {
148 std::forward<decltype(v)>(v).visit(), //
149 []() {}); // missing parameters
150 };
151 }(std::as_const(s1)));
152 static_assert([](auto&& v) {
153 return !requires {
155 std::forward<decltype(v)>(v).visit(), //
156 [](auto) {},
157 1); // missing parameters
158 };
159 }(std::as_const(s1)));
160 static_assert([](auto&& v) {
161 return !requires {
163 std::forward<decltype(v)>(v).visit(), //
164 [](auto, auto) {},
165 1); // missing parameters
166 };
167 }(std::as_const(s1)));
168 static_assert([](auto&& v) {
169 return !requires {
171 std::forward<decltype(v)>(v).visit(), //
172 [](auto, auto, char const*) {},
173 1); // parameter type mismatch
174 };
175 }(std::as_const(s1)));
176
177 // Sanity checks
178 static_assert([](auto&& v) {
179 return requires {
181 std::forward<decltype(v)>(v).visit(), //
182 [](auto) {});
183 };
184 }(s1));
185 static_assert([](auto&& v) {
186 return requires {
188 std::forward<decltype(v)>(v).visit(), //
189 [](json::Value const&) {});
190 };
191 }(std::as_const(s1)));
192 static_assert([](auto&& v) {
193 return requires {
195 std::forward<decltype(v)>(v).visit(), //
196 [](auto...) {});
197 };
198 }(s1));
199 static_assert([](auto&& v) {
200 return requires {
202 std::forward<decltype(v)>(v).visit(), //
203 [](json::Value const&, auto...) {});
204 };
205 }(std::as_const(s1)));
206 static_assert([](auto&& v) {
207 return requires {
209 std::forward<decltype(v)>(v).visit(), //
210 [](json::Value&, auto, auto, auto...) {},
211 0,
212 "");
213 };
214 }(s1));
215 static_assert([](auto&& v) {
216 return requires {
218 std::forward<decltype(v)>(v).visit(), //
219 []<unsigned int Version>(
220 json::Value const&,
222 int,
223 char const*) {},
224 0,
225 "");
226 };
227 }(std::as_const(s1)));
228 static_assert([](auto&& v) {
229 return requires {
231 std::forward<decltype(v)>(v).visit(), //
232 [](auto...) {});
233 };
234 }(std::move(s1)));
235 static_assert([](auto&& v) {
236 return requires {
238 std::forward<decltype(v)>(v).visit(), //
239 [](auto...) {});
240 };
241 }(std::move(std::as_const(s1)))); // NOLINT(performance-move-const-arg)
242 }
243
244 {
245 testcase("default copy construction / assignment");
246
247 MultiApiJson<1, 3> x{subject};
248
249 BEAST_EXPECT(x.val.size() == subject.val.size());
250 BEAST_EXPECT(x.val[0] == subject.val[0]);
251 BEAST_EXPECT(x.val[1] == subject.val[1]);
252 BEAST_EXPECT(x.val[2] == subject.val[2]);
253 BEAST_EXPECT(x.val == subject.val);
254 BEAST_EXPECT(&x.val[0] != &subject.val[0]);
255 BEAST_EXPECT(&x.val[1] != &subject.val[1]);
256 BEAST_EXPECT(&x.val[2] != &subject.val[2]);
257
259 BEAST_EXPECT((y.val == std::array<json::Value, 3>{}));
260 y = subject;
261 BEAST_EXPECT(y.val == subject.val);
262 BEAST_EXPECT(&y.val[0] != &subject.val[0]);
263 BEAST_EXPECT(&y.val[1] != &subject.val[1]);
264 BEAST_EXPECT(&y.val[2] != &subject.val[2]);
265
266 y = std::move(x);
267 BEAST_EXPECT(y.val == subject.val);
268 BEAST_EXPECT(&y.val[0] != &subject.val[0]);
269 BEAST_EXPECT(&y.val[1] != &subject.val[1]);
270 BEAST_EXPECT(&y.val[2] != &subject.val[2]);
271 }
272
273 {
274 testcase("set");
275
277 x.set("name1", 42);
278 BEAST_EXPECT(x.val[0].isMember("name1"));
279 BEAST_EXPECT(x.val[1].isMember("name1"));
280 BEAST_EXPECT(x.val[0]["name1"].isInt());
281 BEAST_EXPECT(x.val[1]["name1"].isInt());
282 BEAST_EXPECT(x.val[0]["name1"].asInt() == 42);
283 BEAST_EXPECT(x.val[1]["name1"].asInt() == 42);
284
285 x.set("name2", "bar");
286 BEAST_EXPECT(x.val[0].isMember("name2"));
287 BEAST_EXPECT(x.val[1].isMember("name2"));
288 BEAST_EXPECT(x.val[0]["name2"].isString());
289 BEAST_EXPECT(x.val[1]["name2"].isString());
290 BEAST_EXPECT(x.val[0]["name2"].asString() == "bar");
291 BEAST_EXPECT(x.val[1]["name2"].asString() == "bar");
292
293 // Tests of requires clause - these are expected to match
294 static_assert(
295 [](auto&& v) { return requires { v.set("name", json::ValueType::Null); }; }(x));
296 static_assert([](auto&& v) { return requires { v.set("name", "value"); }; }(x));
297 static_assert([](auto&& v) { return requires { v.set("name", true); }; }(x));
298 static_assert([](auto&& v) { return requires { v.set("name", 42); }; }(x));
299
300 // Tests of requires clause - these are expected NOT to match
301 struct FooT final
302 {
303 };
304 static_assert([](auto&& v) { return !requires { v.set("name", FooT{}); }; }(x));
305 static_assert([](auto&& v) { return !requires { v.set("name", std::nullopt); }; }(x));
306 }
307
308 {
309 testcase("isMember");
310
311 // Well defined behaviour even if we have different types of members
312 BEAST_EXPECT(subject.isMember("foo") == decltype(subject)::IsMemberResult::None);
313
314 {
315 // All variants have element "One", none have element "Two"
317 s1.val[0] = makeJson("One", 12);
318 s1.val[1] = makeJson("One", 42);
319 BEAST_EXPECT(s1.isMember("One") == decltype(s1)::IsMemberResult::All);
320 BEAST_EXPECT(s1.isMember("Two") == decltype(s1)::IsMemberResult::None);
321 }
322
323 {
324 // Some variants have element "One" and some have "Two"
326 s2.val[0] = makeJson("One", 12);
327 s2.val[1] = makeJson("Two", 42);
328 BEAST_EXPECT(s2.isMember("One") == decltype(s2)::IsMemberResult::Some);
329 BEAST_EXPECT(s2.isMember("Two") == decltype(s2)::IsMemberResult::Some);
330 }
331
332 {
333 // Not all variants have element "One", because last one is null
335 s3.val[0] = makeJson("One", 12);
336 s3.val[1] = makeJson("One", 42);
337 BEAST_EXPECT(s3.isMember("One") == decltype(s3)::IsMemberResult::Some);
338 BEAST_EXPECT(s3.isMember("Two") == decltype(s3)::IsMemberResult::None);
339 }
340 }
341
342 {
343 testcase("visitor");
344
346 s1.val[0] = makeJson("value", 2);
347 s1.val[1] = makeJson("value", 3);
348 s1.val[2] = makeJson("value", 5);
349
350 BEAST_EXPECT(not s1.valid(0));
351 BEAST_EXPECT(s1.index(0) == 0);
352
353 BEAST_EXPECT(s1.valid(1));
354 BEAST_EXPECT(s1.index(1) == 0);
355
356 BEAST_EXPECT(not s1.valid(4));
357
358 // Test different overloads
359 static_assert([](auto&& v) {
360 return requires {
361 v.kVisitor(
362 v,
363 std::integral_constant<unsigned, 1>{},
364 [](json::Value&, std::integral_constant<unsigned, 1>) {});
365 };
366 }(s1));
367 BEAST_EXPECT(
368 s1.kVisitor(
369 s1,
370 std::integral_constant<unsigned, 1>{},
371 Overload{
372 [](json::Value& v, std::integral_constant<unsigned, 1>) {
373 return v["value"].asInt();
374 },
375 [](json::Value const&, auto) { return 0; },
376 [](auto, auto) { return 0; }}) == 2);
377
378 static_assert([](auto&& v) {
379 return requires {
380 v.kVisitor(v, std::integral_constant<unsigned, 1>{}, [](json::Value&) {});
381 };
382 }(s1));
383 BEAST_EXPECT(
384 s1.kVisitor(
385 s1,
386 std::integral_constant<unsigned, 1>{},
387 Overload{
388 [](json::Value& v) { return v["value"].asInt(); },
389 [](json::Value const&) { return 0; },
390 [](auto...) { return 0; }}) == 2);
391
392 static_assert([](auto&& v) {
393 return requires {
394 v.kVisitor(
395 v,
396 std::integral_constant<unsigned, 1>{},
397 [](json::Value const&, std::integral_constant<unsigned, 1>) {});
398 };
399 }(std::as_const(s1)));
400 BEAST_EXPECT(
401 s1.kVisitor(
402 std::as_const(s1),
403 std::integral_constant<unsigned, 2>{},
404 Overload{
405 [](json::Value const& v, std::integral_constant<unsigned, 2>) {
406 return v["value"].asInt();
407 },
408 [](json::Value&, auto) { return 0; },
409 [](auto, auto) { return 0; }}) == 3);
410
411 static_assert([](auto&& v) {
412 return requires {
413 v.kVisitor(v, std::integral_constant<unsigned, 1>{}, [](json::Value const&) {});
414 };
415 }(std::as_const(s1)));
416 BEAST_EXPECT(
417 s1.kVisitor(
418 std::as_const(s1),
420 Overload{
421 [](json::Value const& v) { return v["value"].asInt(); },
422 [](json::Value&) { return 0; },
423 [](auto...) { return 0; }}) == 3);
424
425 static_assert([](auto&& v) {
426 return requires { v.kVisitor(v, 1, [](json::Value&, unsigned) {}); };
427 }(s1));
428 BEAST_EXPECT(
429 s1.kVisitor(
430 s1, //
431 3u,
432 Overload{
433 [](json::Value& v, unsigned) { return v["value"].asInt(); },
434 [](json::Value const&, unsigned) { return 0; },
435 [](auto, auto) { return 0; }}) == 5);
436
437 static_assert(
438 [](auto&& v) { return requires { v.kVisitor(v, 1, [](json::Value&) {}); }; }(s1));
439 BEAST_EXPECT(
440 s1.kVisitor(
441 s1, //
442 3,
443 Overload{
444 [](json::Value& v) { return v["value"].asInt(); },
445 [](json::Value const&) { return 0; },
446 [](auto...) { return 0; }}) == 5);
447
448 static_assert([](auto&& v) {
449 return requires { v.kVisitor(v, 1, [](json::Value const&, unsigned) {}); };
450 }(std::as_const(s1)));
451 BEAST_EXPECT(
452 s1.kVisitor(
453 std::as_const(s1), //
454 2u,
455 Overload{
456 [](json::Value const& v, unsigned) { return v["value"].asInt(); },
457 [](json::Value const&, auto) { return 0; },
458 [](auto, auto) { return 0; }}) == 3);
459
460 static_assert([](auto&& v) {
461 return requires { v.kVisitor(v, 1, [](json::Value const&) {}); };
462 }(std::as_const(s1)));
463 BEAST_EXPECT(
464 s1.kVisitor(
465 std::as_const(s1), //
466 2,
467 Overload{
468 [](json::Value const& v) { return v["value"].asInt(); },
469 [](json::Value&) { return 0; },
470 [](auto...) { return 0; }}) == 3);
471
472 // Test type conversions
473 BEAST_EXPECT(
474 s1.kVisitor(
475 s1,
477 [](json::Value& v, unsigned) { return v["value"].asInt(); }) == 2);
478 BEAST_EXPECT(
479 s1.kVisitor(
480 std::as_const(s1),
482 [](json::Value const& v, unsigned) { return v["value"].asInt(); }) == 3);
483 BEAST_EXPECT(
484 s1.kVisitor(
485 s1, // to const
487 [](json::Value const& v, auto) { return v["value"].asInt(); }) == 5);
488 BEAST_EXPECT(
489 s1.kVisitor(
490 s1, // to const
492 [](json::Value const& v) { return v["value"].asInt(); }) == 5);
493 BEAST_EXPECT(
494 s1.kVisitor(
495 s1,
496 3, // to long
497 [](json::Value& v, long) { return v["value"].asInt(); }) == 5);
498 BEAST_EXPECT(
499 s1.kVisitor(
500 std::as_const(s1),
501 1, // to long
502 [](json::Value const& v, long) { return v["value"].asInt(); }) == 2);
503 BEAST_EXPECT(
504 s1.kVisitor(
505 s1, // to const
506 2,
507 [](json::Value const& v, auto) { return v["value"].asInt(); }) == 3);
508 BEAST_EXPECT(
509 s1.kVisitor(
510 s1, // type deduction
511 2,
512 [](auto& v, auto) { return v["value"].asInt(); }) == 3);
513 BEAST_EXPECT(
514 s1.kVisitor(
515 s1, // to const, type deduction
516 2,
517 [](auto const& v, auto) { return v["value"].asInt(); }) == 3);
518 BEAST_EXPECT(
519 s1.kVisitor(
520 s1, // type deduction
521 2,
522 [](auto& v) { return v["value"].asInt(); }) == 3);
523 BEAST_EXPECT(
524 s1.kVisitor(
525 s1, // to const, type deduction
526 2,
527 [](auto const& v) { return v["value"].asInt(); }) == 3);
528
529 // Test passing of additional arguments
530 BEAST_EXPECT(
531 s1.kVisitor(
532 s1,
534 [](json::Value& v, auto ver, auto a1, auto a2) {
535 return ver * a1 * a2 * v["value"].asInt();
536 },
537 5,
538 7) == 2 * 5 * 7 * 3);
539 BEAST_EXPECT(
540 s1.kVisitor(
541 s1,
543 [](json::Value& v, auto ver, auto... args) {
544 return ver * (1 * ... * args) * v["value"].asInt();
545 },
546 5,
547 7) == 2 * 5 * 7 * 3);
548
549 // Several overloads we want to fail
550 static_assert([](auto&& v) {
551 return !requires {
552 v.kVisitor(
553 v,
554 1, //
555 [](json::Value&, auto) {}); // missing const
556 };
557 }(std::as_const(s1)));
558
559 static_assert([](auto&& v) {
560 return !requires {
561 v.kVisitor(
562 decltype(v){}, // cannot bind rvalue
563 1,
564 [](json::Value&, auto) {});
565 };
566 }(s1));
567
568 static_assert([](auto&& v) {
569 return !requires {
570 v.kVisitor(
571 v,
572 1, //
573 []() {}); // missing parameter
574 };
575 }(s1));
576
577 static_assert([](auto&& v) {
578 return !requires {
579 v.kVisitor(
580 v,
581 1, //
582 [](json::Value&, int, int) {}); // too many parameters
583 };
584 }(s1));
585
586 // Want these to be unambiguous
587 static_assert([](auto&& v) { return requires { v.kVisitor(v, 1, [](auto) {}); }; }(s1));
588
589 static_assert(
590 [](auto&& v) { return requires { v.kVisitor(v, 1, [](json::Value&) {}); }; }(s1));
591
592 static_assert([](auto&& v) {
593 return requires { v.kVisitor(v, 1, [](json::Value&, auto...) {}); };
594 }(s1));
595
596 static_assert([](auto&& v) {
597 return requires { v.kVisitor(v, 1, [](json::Value const&) {}); };
598 }(s1));
599
600 static_assert([](auto&& v) {
601 return requires { v.kVisitor(v, 1, [](json::Value const&, auto...) {}); };
602 }(s1));
603
604 static_assert(
605 [](auto&& v) { return requires { v.kVisitor(v, 1, [](auto...) {}); }; }(s1));
606
607 static_assert(
608 [](auto&& v) { return requires { v.kVisitor(v, 1, [](auto, auto...) {}); }; }(s1));
609
610 static_assert([](auto&& v) {
611 return requires { v.kVisitor(v, 1, [](auto, auto, auto...) {}); };
612 }(s1));
613
614 static_assert([](auto&& v) {
615 return requires { v.kVisitor(v, 1, [](auto, auto, auto...) {}, ""); };
616 }(s1));
617
618 static_assert([](auto&& v) {
619 return requires { v.kVisitor(v, 1, [](auto, auto, auto, auto...) {}, ""); };
620 }(s1));
621 }
622
623 {
624 testcase("visit");
625
626 MultiApiJson<1, 3> s1{};
627 s1.val[0] = makeJson("value", 2);
628 s1.val[1] = makeJson("value", 3);
629 s1.val[2] = makeJson("value", 5);
630
631 // Test different overloads
632 static_assert([](auto&& v) {
633 return requires {
634 v.visit(
637 };
638 }(s1));
639 BEAST_EXPECT(
640 s1.visit(
642 Overload{
643 [](json::Value& v, std::integral_constant<unsigned, 1>) {
644 return v["value"].asInt();
645 },
646 [](json::Value const&, auto) { return 0; },
647 [](auto, auto) { return 0; }}) == 2);
648 static_assert([](auto&& v) {
649 return requires {
650 v.visit()(
653 };
654 }(s1));
655 BEAST_EXPECT(
656 s1.visit()(
658 Overload{
659 [](json::Value& v, std::integral_constant<unsigned, 1>) {
660 return v["value"].asInt();
661 },
662 [](json::Value const&, auto) { return 0; },
663 [](auto, auto) { return 0; }}) == 2);
664
665 static_assert([](auto&& v) {
666 return requires {
668 };
669 }(s1));
670 BEAST_EXPECT(
671 s1.visit(
673 Overload{
674 [](json::Value& v) { return v["value"].asInt(); },
675 [](json::Value const&) { return 0; },
676 [](auto...) { return 0; }}) == 2);
677 static_assert([](auto&& v) {
678 return requires {
680 };
681 }(s1));
682 BEAST_EXPECT(
683 s1.visit()(
685 Overload{
686 [](json::Value& v) { return v["value"].asInt(); },
687 [](json::Value const&) { return 0; },
688 [](auto...) { return 0; }}) == 2);
689
690 static_assert([](auto&& v) {
691 return requires {
692 v.visit(
695 };
696 }(std::as_const(s1)));
697 BEAST_EXPECT(
700 Overload{
702 return v["value"].asInt();
703 },
704 [](json::Value&, auto) { return 0; },
705 [](auto, auto) { return 0; }}) == 3);
706 static_assert([](auto&& v) {
707 return requires {
708 v.visit()(
711 };
712 }(std::as_const(s1)));
713 BEAST_EXPECT(
714 std::as_const(s1).visit()(
716 Overload{
718 return v["value"].asInt();
719 },
720 [](json::Value&, auto) { return 0; },
721 [](auto, auto) { return 0; }}) == 3);
722
723 static_assert([](auto&& v) {
724 return requires {
725 v.visit(std::integral_constant<unsigned, 1>{}, [](json::Value const&) {});
726 };
727 }(std::as_const(s1)));
728 BEAST_EXPECT(
731 Overload{
732 [](json::Value const& v) { return v["value"].asInt(); },
733 [](json::Value&) { return 0; },
734 [](auto...) { return 0; }}) == 3);
735 static_assert([](auto&& v) {
736 return requires {
737 v.visit()(std::integral_constant<unsigned, 1>{}, [](json::Value const&) {});
738 };
739 }(std::as_const(s1)));
740 BEAST_EXPECT(
741 std::as_const(s1).visit()(
743 Overload{
744 [](json::Value const& v) { return v["value"].asInt(); },
745 [](json::Value&) { return 0; },
746 [](auto...) { return 0; }}) == 3);
747
748 static_assert([](auto&& v) {
749 return requires { v.visit(1, [](json::Value&, unsigned) {}); };
750 }(s1));
751 BEAST_EXPECT(
752 s1.visit(
753 3u,
754 Overload{
755 [](json::Value& v, unsigned) { return v["value"].asInt(); },
756 [](json::Value const&, unsigned) { return 0; },
757 [](json::Value&, auto) { return 0; },
758 [](auto, auto) { return 0; }}) == 5);
759 static_assert([](auto&& v) {
760 return requires { v.visit()(1, [](json::Value&, unsigned) {}); };
761 }(s1));
762 BEAST_EXPECT(
763 s1.visit()(
764 3u,
765 Overload{
766 [](json::Value& v, unsigned) { return v["value"].asInt(); },
767 [](json::Value const&, unsigned) { return 0; },
768 [](json::Value&, auto) { return 0; },
769 [](auto, auto) { return 0; }}) == 5);
770
771 static_assert(
772 [](auto&& v) { return requires { v.visit(1, [](json::Value&) {}); }; }(s1));
773 BEAST_EXPECT(
774 s1.visit(
775 3,
776 Overload{
777 [](json::Value& v) { return v["value"].asInt(); },
778 [](json::Value const&) { return 0; },
779 [](auto...) { return 0; }}) == 5);
780 static_assert(
781 [](auto&& v) { return requires { v.visit()(1, [](json::Value&) {}); }; }(s1));
782 BEAST_EXPECT(
783 s1.visit()(
784 3,
785 Overload{
786 [](json::Value& v) { return v["value"].asInt(); },
787 [](json::Value const&) { return 0; },
788 [](auto...) { return 0; }}) == 5);
789
790 static_assert([](auto&& v) {
791 return requires { v.visit(1, [](json::Value const&, unsigned) {}); };
792 }(std::as_const(s1)));
793 BEAST_EXPECT(
795 2u,
796 Overload{
797 [](json::Value const& v, unsigned) { return v["value"].asInt(); },
798 [](json::Value const&, auto) { return 0; },
799 [](json::Value&, unsigned) { return 0; },
800 [](auto, auto) { return 0; }}) == 3);
801 static_assert([](auto&& v) {
802 return requires { v.visit()(1, [](json::Value const&, unsigned) {}); };
803 }(std::as_const(s1)));
804 BEAST_EXPECT(
805 std::as_const(s1).visit()(
806 2u,
807 Overload{
808 [](json::Value const& v, unsigned) { return v["value"].asInt(); },
809 [](json::Value const&, auto) { return 0; },
810 [](json::Value&, unsigned) { return 0; },
811 [](auto, auto) { return 0; }}) == 3);
812
813 static_assert([](auto&& v) {
814 return requires { v.visit(1, [](json::Value const&) {}); };
815 }(std::as_const(s1)));
816 BEAST_EXPECT(
818 2,
819 Overload{
820 [](json::Value const& v) { return v["value"].asInt(); },
821 [](json::Value&) { return 0; },
822 [](auto...) { return 0; }}) == 3);
823 static_assert([](auto&& v) {
824 return requires { v.visit()(1, [](json::Value const&) {}); };
825 }(std::as_const(s1)));
826 BEAST_EXPECT(
827 std::as_const(s1).visit()(
828 2,
829 Overload{
830 [](json::Value const& v) { return v["value"].asInt(); },
831 [](json::Value&) { return 0; },
832 [](auto...) { return 0; }}) == 3);
833
834 // Rvalue MultivarJson visitor only binds to regular reference
835 static_assert([](auto&& v) {
836 // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
837 return !requires { std::forward<decltype(v)>(v).visit(1, [](json::Value&&) {}); };
838 }(std::move(s1)));
839 static_assert([](auto&& v) {
840 return !requires {
841 std::forward<decltype(v)>(v).visit(1, [](json::Value const&&) {});
842 };
843 }(std::move(s1)));
844 static_assert([](auto&& v) {
845 return requires { std::forward<decltype(v)>(v).visit(1, [](json::Value&) {}); };
846 }(std::move(s1)));
847 static_assert([](auto&& v) {
848 return requires {
849 std::forward<decltype(v)>(v).visit(1, [](json::Value const&) {});
850 };
851 }(std::move(s1)));
852 static_assert([](auto&& v) {
853 // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
854 return !requires { std::forward<decltype(v)>(v).visit()(1, [](json::Value&&) {}); };
855 }(std::move(s1)));
856 static_assert([](auto&& v) {
857 return !requires {
858 std::forward<decltype(v)>(v).visit()(1, [](json::Value const&&) {});
859 };
860 }(std::move(s1)));
861 static_assert([](auto&& v) {
862 return requires { std::forward<decltype(v)>(v).visit()(1, [](json::Value&) {}); };
863 }(std::move(s1)));
864 static_assert([](auto&& v) {
865 return requires {
866 std::forward<decltype(v)>(v).visit()(1, [](json::Value const&) {});
867 };
868 }(std::move(s1)));
869 static_assert([](auto&& v) {
870 return !requires {
871 std::forward<decltype(v)>(v).visit(1, [](json::Value const&&) {});
872 };
873 }(std::move(std::as_const(s1)))); // NOLINT(performance-move-const-arg)
874 static_assert([](auto&& v) {
875 return requires {
876 std::forward<decltype(v)>(v).visit(1, [](json::Value const&) {});
877 };
878 }(std::move(std::as_const(s1)))); // NOLINT(performance-move-const-arg)
879 static_assert([](auto&& v) {
880 return !requires {
881 std::forward<decltype(v)>(v).visit()(1, [](json::Value const&&) {});
882 };
883 }(std::move(std::as_const(s1)))); // NOLINT(performance-move-const-arg)
884 static_assert([](auto&& v) {
885 return requires {
886 std::forward<decltype(v)>(v).visit()(1, [](json::Value const&) {});
887 };
888 }(std::move(std::as_const(s1)))); // NOLINT(performance-move-const-arg)
889
890 // Missing const
891 static_assert([](auto&& v) {
892 return !requires {
893 std::forward<decltype(v)>(v).visit(1, [](json::Value&, auto) {});
894 };
895 }(std::as_const(s1)));
896 static_assert([](auto&& v) {
897 return !requires {
898 std::forward<decltype(v)>(v).visit()(1, [](json::Value&, auto) {});
899 };
900 }(std::as_const(s1)));
901
902 // Missing parameter
903 static_assert([](auto&& v) {
904 return !requires { std::forward<decltype(v)>(v).visit(1, []() {}); };
905 }(s1));
906 static_assert([](auto&& v) {
907 return !requires { std::forward<decltype(v)>(v).visit()(1, []() {}); };
908 }(s1));
909
910 // Sanity checks
911 static_assert([](auto&& v) {
912 return requires { std::forward<decltype(v)>(v).visit(1, [](auto...) {}); };
913 }(std::as_const(s1)));
914 static_assert([](auto&& v) {
915 return requires { std::forward<decltype(v)>(v).visit()(1, [](auto...) {}); };
916 }(std::as_const(s1)));
917 }
918 }
919};
920
922
923} // namespace xrpl::test
T as_const(T... args)
A testsuite class.
Definition suite.h:50
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:149
Represents a JSON value.
Definition json_value.h:130
UInt size() const
Number of values in array or object.
Int asInt() const
T forward(T... args)
T is_same_v
JSON (JavaScript Object Notation).
Definition json_errors.h:5
@ Object
object value (collection of name/value pairs).
Definition json_value.h:26
@ Null
'null' value
Definition json_value.h:19
static constexpr auto kApiMinimumSupportedVersion
Definition ApiVersion.h:41
static constexpr auto kApiMaximumValidVersion
Definition ApiVersion.h:46
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
void forApiVersions(Fn const &fn, Args &&... args)
Definition ApiVersion.h:137
void forAllApiVersions(Fn const &fn, Args &&... args)
Definition ApiVersion.h:158
detail::MultiApiJson< RPC::kApiMinimumSupportedVersion, RPC::kApiMaximumValidVersion > MultiApiJson
T size(T... args)
void set(char const *key, auto const &v)
std::array< json::Value, kSize > val
static constexpr auto valid(unsigned int v) noexcept -> bool
static constexpr auto index(unsigned int v) noexcept -> std::size_t
static constexpr std::size_t kSize
static auto makeJson(char const *key, int val)
void run() override
Runs the suite.
T visit(T... args)