rippled
Loading...
Searching...
No Matches
MultiApiJson_test.cpp
1#include <xrpl/beast/unit_test.h>
2#include <xrpl/protocol/MultiApiJson.h>
3
4#include <cstdint>
5#include <limits>
6#include <optional>
7#include <type_traits>
8#include <utility>
9
10namespace ripple {
11namespace test {
12
13namespace {
14
15// This needs to be in a namespace because of deduction guide
16template <typename... Ts>
17struct Overload : Ts...
18{
19 using Ts::operator()...;
20};
21template <typename... Ts>
22Overload(Ts...) -> Overload<Ts...>;
23
24} // namespace
25
27{
28 static auto
29 makeJson(char const* key, int val)
30 {
32 obj1[key] = val;
33 return obj1;
34 }
35
36 void
37 run() override
38 {
40
41 Json::Value const obj1 = makeJson("value", 1);
42 Json::Value const obj2 = makeJson("value", 2);
43 Json::Value const obj3 = makeJson("value", 3);
44 Json::Value const jsonNull{};
45
46 MultiApiJson<1, 3> subject{};
47 static_assert(sizeof(subject) == sizeof(subject.val));
48 static_assert(subject.size == subject.val.size());
49 static_assert(
50 std::is_same_v<decltype(subject.val), std::array<Json::Value, 3>>);
51
52 BEAST_EXPECT(subject.val.size() == 3);
53 BEAST_EXPECT(
54 (subject.val ==
55 std::array<Json::Value, 3>{jsonNull, jsonNull, jsonNull}));
56
57 subject.val[0] = obj1;
58 subject.val[1] = obj2;
59
60 {
61 testcase("forApiVersions, forAllApiVersions");
62
63 // Some static data for test inputs
64 static int const primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23,
65 29, 31, 37, 41, 43, 47, 53, 59, 61,
66 67, 71, 73, 79, 83, 89, 97};
67 static_assert(std::size(primes) > RPC::apiMaximumValidVersion);
68
70 static_assert(
71 s1.size ==
74
75 int productAllVersions = 1;
76 for (unsigned i = RPC::apiMinimumSupportedVersion;
78 ++i)
79 {
80 auto const index = i - RPC::apiMinimumSupportedVersion;
81 BEAST_EXPECT(index == s1.index(i));
82 BEAST_EXPECT(s1.valid(i));
83 s1.val[index] = makeJson("value", primes[i]);
84 productAllVersions *= primes[i];
85 }
86 BEAST_EXPECT(!s1.valid(0));
87 BEAST_EXPECT(!s1.valid(RPC::apiMaximumValidVersion + 1));
88 BEAST_EXPECT(
89 !s1.valid(std::numeric_limits<
90 decltype(RPC::apiMaximumValidVersion.value)>::max()));
91
92 int result = 1;
93 static_assert(
99 std::as_const(s1).visit(),
100 [this](
101 Json::Value const& json,
102 unsigned int version,
103 int* result) {
104 BEAST_EXPECT(
106 version <= RPC::apiMinimumSupportedVersion + 1);
107 if (BEAST_EXPECT(json.isMember("value")))
108 {
109 *result *= json["value"].asInt();
110 }
111 },
112 &result);
113 BEAST_EXPECT(
114 result ==
117
118 // Check all the values with mutable data
120 s1.visit(), [&s1, this](Json::Value& json, auto version) {
121 BEAST_EXPECT(s1.val[s1.index(version)] == json);
122 if (BEAST_EXPECT(json.isMember("value")))
123 {
124 BEAST_EXPECT(json["value"].asInt() == primes[version]);
125 }
126 });
127
128 result = 1;
130 std::as_const(s1).visit(),
131 [this](
132 Json::Value const& json,
133 unsigned int version,
134 int* result) {
135 BEAST_EXPECT(
137 version <= RPC::apiMaximumValidVersion);
138 if (BEAST_EXPECT(json.isMember("value")))
139 {
140 *result *= json["value"].asInt();
141 }
142 },
143 &result);
144
145 BEAST_EXPECT(result == productAllVersions);
146
147 // Several overloads we want to fail
148 static_assert([](auto&& v) {
149 return !requires {
151 std::forward<decltype(v)>(v).visit(), //
152 [](Json::Value&, auto) {}); // missing const
153 };
154 }(std::as_const(s1)));
155 static_assert([](auto&& v) {
156 return !requires {
158 std::forward<decltype(v)>(v).visit(), //
159 [](Json::Value&) {}); // missing const
160 };
161 }(std::as_const(s1)));
162 static_assert([](auto&& v) {
163 return !requires {
165 std::forward<decltype(v)>(v).visit(), //
166 []() {}); // missing parameters
167 };
168 }(std::as_const(s1)));
169 static_assert([](auto&& v) {
170 return !requires {
172 std::forward<decltype(v)>(v).visit(), //
173 [](auto) {},
174 1); // missing parameters
175 };
176 }(std::as_const(s1)));
177 static_assert([](auto&& v) {
178 return !requires {
180 std::forward<decltype(v)>(v).visit(), //
181 [](auto, auto) {},
182 1); // missing parameters
183 };
184 }(std::as_const(s1)));
185 static_assert([](auto&& v) {
186 return !requires {
188 std::forward<decltype(v)>(v).visit(), //
189 [](auto, auto, char const*) {},
190 1); // parameter type mismatch
191 };
192 }(std::as_const(s1)));
193
194 // Sanity checks
195 static_assert([](auto&& v) {
196 return requires {
198 std::forward<decltype(v)>(v).visit(), //
199 [](auto) {});
200 };
201 }(s1));
202 static_assert([](auto&& v) {
203 return requires {
205 std::forward<decltype(v)>(v).visit(), //
206 [](Json::Value const&) {});
207 };
208 }(std::as_const(s1)));
209 static_assert([](auto&& v) {
210 return requires {
212 std::forward<decltype(v)>(v).visit(), //
213 [](auto...) {});
214 };
215 }(s1));
216 static_assert([](auto&& v) {
217 return requires {
219 std::forward<decltype(v)>(v).visit(), //
220 [](Json::Value const&, auto...) {});
221 };
222 }(std::as_const(s1)));
223 static_assert([](auto&& v) {
224 return requires {
226 std::forward<decltype(v)>(v).visit(), //
227 [](Json::Value&, auto, auto, auto...) {},
228 0,
229 "");
230 };
231 }(s1));
232 static_assert([](auto&& v) {
233 return requires {
235 std::forward<decltype(v)>(v).visit(), //
236 []<unsigned int Version>(
237 Json::Value const&,
239 int,
240 char const*) {},
241 0,
242 "");
243 };
244 }(std::as_const(s1)));
245 static_assert([](auto&& v) {
246 return requires {
248 std::forward<decltype(v)>(v).visit(), //
249 [](auto...) {});
250 };
251 }(std::move(s1)));
252 static_assert([](auto&& v) {
253 return requires {
255 std::forward<decltype(v)>(v).visit(), //
256 [](auto...) {});
257 };
258 }(std::move(std::as_const(s1))));
259 }
260
261 {
262 testcase("default copy construction / assignment");
263
264 MultiApiJson<1, 3> x{subject};
265
266 BEAST_EXPECT(x.val.size() == subject.val.size());
267 BEAST_EXPECT(x.val[0] == subject.val[0]);
268 BEAST_EXPECT(x.val[1] == subject.val[1]);
269 BEAST_EXPECT(x.val[2] == subject.val[2]);
270 BEAST_EXPECT(x.val == subject.val);
271 BEAST_EXPECT(&x.val[0] != &subject.val[0]);
272 BEAST_EXPECT(&x.val[1] != &subject.val[1]);
273 BEAST_EXPECT(&x.val[2] != &subject.val[2]);
274
276 BEAST_EXPECT((y.val == std::array<Json::Value, 3>{}));
277 y = subject;
278 BEAST_EXPECT(y.val == subject.val);
279 BEAST_EXPECT(&y.val[0] != &subject.val[0]);
280 BEAST_EXPECT(&y.val[1] != &subject.val[1]);
281 BEAST_EXPECT(&y.val[2] != &subject.val[2]);
282
283 y = std::move(x);
284 BEAST_EXPECT(y.val == subject.val);
285 BEAST_EXPECT(&y.val[0] != &subject.val[0]);
286 BEAST_EXPECT(&y.val[1] != &subject.val[1]);
287 BEAST_EXPECT(&y.val[2] != &subject.val[2]);
288 }
289
290 {
291 testcase("set");
292
293 auto x = MultiApiJson<1, 2>{Json::objectValue};
294 x.set("name1", 42);
295 BEAST_EXPECT(x.val[0].isMember("name1"));
296 BEAST_EXPECT(x.val[1].isMember("name1"));
297 BEAST_EXPECT(x.val[0]["name1"].isInt());
298 BEAST_EXPECT(x.val[1]["name1"].isInt());
299 BEAST_EXPECT(x.val[0]["name1"].asInt() == 42);
300 BEAST_EXPECT(x.val[1]["name1"].asInt() == 42);
301
302 x.set("name2", "bar");
303 BEAST_EXPECT(x.val[0].isMember("name2"));
304 BEAST_EXPECT(x.val[1].isMember("name2"));
305 BEAST_EXPECT(x.val[0]["name2"].isString());
306 BEAST_EXPECT(x.val[1]["name2"].isString());
307 BEAST_EXPECT(x.val[0]["name2"].asString() == "bar");
308 BEAST_EXPECT(x.val[1]["name2"].asString() == "bar");
309
310 // Tests of requires clause - these are expected to match
311 static_assert([](auto&& v) {
312 return requires { v.set("name", Json::nullValue); };
313 }(x));
314 static_assert([](auto&& v) {
315 return requires { v.set("name", "value"); };
316 }(x));
317 static_assert(
318 [](auto&& v) { return requires { v.set("name", true); }; }(x));
319 static_assert(
320 [](auto&& v) { return requires { v.set("name", 42); }; }(x));
321
322 // Tests of requires clause - these are expected NOT to match
323 struct foo_t final
324 {
325 };
326 static_assert([](auto&& v) {
327 return !requires { v.set("name", foo_t{}); };
328 }(x));
329 static_assert([](auto&& v) {
330 return !requires { v.set("name", std::nullopt); };
331 }(x));
332 }
333
334 {
335 testcase("isMember");
336
337 // Well defined behaviour even if we have different types of members
338 BEAST_EXPECT(subject.isMember("foo") == decltype(subject)::none);
339
340 {
341 // All variants have element "One", none have element "Two"
342 MultiApiJson<1, 2> s1{};
343 s1.val[0] = makeJson("One", 12);
344 s1.val[1] = makeJson("One", 42);
345 BEAST_EXPECT(s1.isMember("One") == decltype(s1)::all);
346 BEAST_EXPECT(s1.isMember("Two") == decltype(s1)::none);
347 }
348
349 {
350 // Some variants have element "One" and some have "Two"
351 MultiApiJson<1, 2> s2{};
352 s2.val[0] = makeJson("One", 12);
353 s2.val[1] = makeJson("Two", 42);
354 BEAST_EXPECT(s2.isMember("One") == decltype(s2)::some);
355 BEAST_EXPECT(s2.isMember("Two") == decltype(s2)::some);
356 }
357
358 {
359 // Not all variants have element "One", because last one is null
360 MultiApiJson<1, 3> s3{};
361 s3.val[0] = makeJson("One", 12);
362 s3.val[1] = makeJson("One", 42);
363 BEAST_EXPECT(s3.isMember("One") == decltype(s3)::some);
364 BEAST_EXPECT(s3.isMember("Two") == decltype(s3)::none);
365 }
366 }
367
368 {
369 testcase("visitor");
370
371 MultiApiJson<1, 3> s1{};
372 s1.val[0] = makeJson("value", 2);
373 s1.val[1] = makeJson("value", 3);
374 s1.val[2] = makeJson("value", 5);
375
376 BEAST_EXPECT(not s1.valid(0));
377 BEAST_EXPECT(s1.index(0) == 0);
378
379 BEAST_EXPECT(s1.valid(1));
380 BEAST_EXPECT(s1.index(1) == 0);
381
382 BEAST_EXPECT(not s1.valid(4));
383
384 // Test different overloads
385 static_assert([](auto&& v) {
386 return requires {
387 v.visitor(
388 v,
391 });
392 };
393 }(s1));
394 BEAST_EXPECT(
395 s1.visitor(
396 s1,
398 Overload{
399 [](Json::Value& v,
400 std::integral_constant<unsigned, 1>) {
401 return v["value"].asInt();
402 },
403 [](Json::Value const&, auto) { return 0; },
404 [](auto, auto) { return 0; }}) == 2);
405
406 static_assert([](auto&& v) {
407 return requires {
408 v.visitor(
409 v,
411 [](Json::Value&) {});
412 };
413 }(s1));
414 BEAST_EXPECT(
415 s1.visitor(
416 s1,
418 Overload{
419 [](Json::Value& v) { return v["value"].asInt(); },
420 [](Json::Value const&) { return 0; },
421 [](auto...) { return 0; }}) == 2);
422
423 static_assert([](auto&& v) {
424 return requires {
425 v.visitor(
426 v,
428 [](Json::Value const&,
430 };
431 }(std::as_const(s1)));
432 BEAST_EXPECT(
433 s1.visitor(
434 std::as_const(s1),
436 Overload{
437 [](Json::Value const& v,
438 std::integral_constant<unsigned, 2>) {
439 return v["value"].asInt();
440 },
441 [](Json::Value&, auto) { return 0; },
442 [](auto, auto) { return 0; }}) == 3);
443
444 static_assert([](auto&& v) {
445 return requires {
446 v.visitor(
447 v,
449 [](Json::Value const&) {});
450 };
451 }(std::as_const(s1)));
452 BEAST_EXPECT(
453 s1.visitor(
454 std::as_const(s1),
456 Overload{
457 [](Json::Value const& v) { return v["value"].asInt(); },
458 [](Json::Value&) { return 0; },
459 [](auto...) { return 0; }}) == 3);
460
461 static_assert([](auto&& v) {
462 return requires {
463 v.visitor(v, 1, [](Json::Value&, unsigned) {});
464 };
465 }(s1));
466 BEAST_EXPECT(
467 s1.visitor(
468 s1, //
469 3u,
470 Overload{
471 [](Json::Value& v, unsigned) {
472 return v["value"].asInt();
473 },
474 [](Json::Value const&, unsigned) { return 0; },
475 [](auto, auto) { return 0; }}) == 5);
476
477 static_assert([](auto&& v) {
478 return requires { v.visitor(v, 1, [](Json::Value&) {}); };
479 }(s1));
480 BEAST_EXPECT(
481 s1.visitor(
482 s1, //
483 3,
484 Overload{
485 [](Json::Value& v) { return v["value"].asInt(); },
486 [](Json::Value const&) { return 0; },
487 [](auto...) { return 0; }}) == 5);
488
489 static_assert([](auto&& v) {
490 return requires {
491 v.visitor(v, 1, [](Json::Value const&, unsigned) {});
492 };
493 }(std::as_const(s1)));
494 BEAST_EXPECT(
495 s1.visitor(
496 std::as_const(s1), //
497 2u,
498 Overload{
499 [](Json::Value const& v, unsigned) {
500 return v["value"].asInt();
501 },
502 [](Json::Value const&, auto) { return 0; },
503 [](auto, auto) { return 0; }}) == 3);
504
505 static_assert([](auto&& v) {
506 return requires { v.visitor(v, 1, [](Json::Value const&) {}); };
507 }(std::as_const(s1)));
508 BEAST_EXPECT(
509 s1.visitor(
510 std::as_const(s1), //
511 2,
512 Overload{
513 [](Json::Value const& v) { return v["value"].asInt(); },
514 [](Json::Value&) { return 0; },
515 [](auto...) { return 0; }}) == 3);
516
517 // Test type conversions
518 BEAST_EXPECT(
519 s1.visitor(
520 s1,
522 [](Json::Value& v, unsigned) {
523 return v["value"].asInt();
524 }) == 2);
525 BEAST_EXPECT(
526 s1.visitor(
527 std::as_const(s1),
529 [](Json::Value const& v, unsigned) {
530 return v["value"].asInt();
531 }) == 3);
532 BEAST_EXPECT(
533 s1.visitor(
534 s1, // to const
536 [](Json::Value const& v, auto) {
537 return v["value"].asInt();
538 }) == 5);
539 BEAST_EXPECT(
540 s1.visitor(
541 s1, // to const
543 [](Json::Value const& v) { return v["value"].asInt(); }) ==
544 5);
545 BEAST_EXPECT(
546 s1.visitor(
547 s1,
548 3, // to long
549 [](Json::Value& v, long) { return v["value"].asInt(); }) ==
550 5);
551 BEAST_EXPECT(
552 s1.visitor(
553 std::as_const(s1),
554 1, // to long
555 [](Json::Value const& v, long) {
556 return v["value"].asInt();
557 }) == 2);
558 BEAST_EXPECT(
559 s1.visitor(
560 s1, // to const
561 2,
562 [](Json::Value const& v, auto) {
563 return v["value"].asInt();
564 }) == 3);
565 BEAST_EXPECT(
566 s1.visitor(
567 s1, // type deduction
568 2,
569 [](auto& v, auto) { return v["value"].asInt(); }) == 3);
570 BEAST_EXPECT(
571 s1.visitor(
572 s1, // to const, type deduction
573 2,
574 [](auto const& v, auto) { return v["value"].asInt(); }) ==
575 3);
576 BEAST_EXPECT(
577 s1.visitor(
578 s1, // type deduction
579 2,
580 [](auto& v) { return v["value"].asInt(); }) == 3);
581 BEAST_EXPECT(
582 s1.visitor(
583 s1, // to const, type deduction
584 2,
585 [](auto const& v) { return v["value"].asInt(); }) == 3);
586
587 // Test passing of additional arguments
588 BEAST_EXPECT(
589 s1.visitor(
590 s1,
592 [](Json::Value& v, auto ver, auto a1, auto a2) {
593 return ver * a1 * a2 * v["value"].asInt();
594 },
595 5,
596 7) == 2 * 5 * 7 * 3);
597 BEAST_EXPECT(
598 s1.visitor(
599 s1,
601 [](Json::Value& v, auto ver, auto... args) {
602 return ver * (1 * ... * args) * v["value"].asInt();
603 },
604 5,
605 7) == 2 * 5 * 7 * 3);
606
607 // Several overloads we want to fail
608 static_assert([](auto&& v) {
609 return !requires {
610 v.visitor(
611 v,
612 1, //
613 [](Json::Value&, auto) {}); // missing const
614 };
615 }(std::as_const(s1)));
616
617 static_assert([](auto&& v) {
618 return !requires {
619 v.visitor(
620 std::move(v), // cannot bind rvalue
621 1,
622 [](Json::Value&, auto) {});
623 };
624 }(s1));
625
626 static_assert([](auto&& v) {
627 return !requires {
628 v.visitor(
629 v,
630 1, //
631 []() {}); // missing parameter
632 };
633 }(s1));
634
635 static_assert([](auto&& v) {
636 return !requires {
637 v.visitor(
638 v,
639 1, //
640 [](Json::Value&, int, int) {}); // too many parameters
641 };
642 }(s1));
643
644 // Want these to be unambiguous
645 static_assert([](auto&& v) {
646 return requires { v.visitor(v, 1, [](auto) {}); };
647 }(s1));
648
649 static_assert([](auto&& v) {
650 return requires { v.visitor(v, 1, [](Json::Value&) {}); };
651 }(s1));
652
653 static_assert([](auto&& v) {
654 return requires {
655 v.visitor(v, 1, [](Json::Value&, auto...) {});
656 };
657 }(s1));
658
659 static_assert([](auto&& v) {
660 return requires { v.visitor(v, 1, [](Json::Value const&) {}); };
661 }(s1));
662
663 static_assert([](auto&& v) {
664 return requires {
665 v.visitor(v, 1, [](Json::Value const&, auto...) {});
666 };
667 }(s1));
668
669 static_assert([](auto&& v) {
670 return requires { v.visitor(v, 1, [](auto...) {}); };
671 }(s1));
672
673 static_assert([](auto&& v) {
674 return requires { v.visitor(v, 1, [](auto, auto...) {}); };
675 }(s1));
676
677 static_assert([](auto&& v) {
678 return requires {
679 v.visitor(v, 1, [](auto, auto, auto...) {});
680 };
681 }(s1));
682
683 static_assert([](auto&& v) {
684 return requires {
685 v.visitor(v, 1, [](auto, auto, auto...) {}, "");
686 };
687 }(s1));
688
689 static_assert([](auto&& v) {
690 return requires {
691 v.visitor(v, 1, [](auto, auto, auto, auto...) {}, "");
692 };
693 }(s1));
694 }
695
696 {
697 testcase("visit");
698
699 MultiApiJson<1, 3> s1{};
700 s1.val[0] = makeJson("value", 2);
701 s1.val[1] = makeJson("value", 3);
702 s1.val[2] = makeJson("value", 5);
703
704 // Test different overloads
705 static_assert([](auto&& v) {
706 return requires {
707 v.visit(
710 });
711 };
712 }(s1));
713 BEAST_EXPECT(
714 s1.visit(
716 Overload{
717 [](Json::Value& v,
718 std::integral_constant<unsigned, 1>) {
719 return v["value"].asInt();
720 },
721 [](Json::Value const&, auto) { return 0; },
722 [](auto, auto) { return 0; }}) == 2);
723 static_assert([](auto&& v) {
724 return requires {
725 v.visit()(
728 });
729 };
730 }(s1));
731 BEAST_EXPECT(
732 s1.visit()(
734 Overload{
735 [](Json::Value& v,
736 std::integral_constant<unsigned, 1>) {
737 return v["value"].asInt();
738 },
739 [](Json::Value const&, auto) { return 0; },
740 [](auto, auto) { return 0; }}) == 2);
741
742 static_assert([](auto&& v) {
743 return requires {
744 v.visit(
746 [](Json::Value&) {});
747 };
748 }(s1));
749 BEAST_EXPECT(
750 s1.visit(
752 Overload{
753 [](Json::Value& v) { return v["value"].asInt(); },
754 [](Json::Value const&) { return 0; },
755 [](auto...) { return 0; }}) == 2);
756 static_assert([](auto&& v) {
757 return requires {
758 v.visit()(
760 [](Json::Value&) {});
761 };
762 }(s1));
763 BEAST_EXPECT(
764 s1.visit()(
766 Overload{
767 [](Json::Value& v) { return v["value"].asInt(); },
768 [](Json::Value const&) { return 0; },
769 [](auto...) { return 0; }}) == 2);
770
771 static_assert([](auto&& v) {
772 return requires {
773 v.visit(
775 [](Json::Value const&,
777 };
778 }(std::as_const(s1)));
779 BEAST_EXPECT(
782 Overload{
783 [](Json::Value const& v,
785 return v["value"].asInt();
786 },
787 [](Json::Value&, auto) { return 0; },
788 [](auto, auto) { return 0; }}) == 3);
789 static_assert([](auto&& v) {
790 return requires {
791 v.visit()(
793 [](Json::Value const&,
795 };
796 }(std::as_const(s1)));
797 BEAST_EXPECT(
798 std::as_const(s1).visit()(
800 Overload{
801 [](Json::Value const& v,
803 return v["value"].asInt();
804 },
805 [](Json::Value&, auto) { return 0; },
806 [](auto, auto) { return 0; }}) == 3);
807
808 static_assert([](auto&& v) {
809 return requires {
810 v.visit(
812 [](Json::Value const&) {});
813 };
814 }(std::as_const(s1)));
815 BEAST_EXPECT(
818 Overload{
819 [](Json::Value const& v) { return v["value"].asInt(); },
820 [](Json::Value&) { return 0; },
821 [](auto...) { return 0; }}) == 3);
822 static_assert([](auto&& v) {
823 return requires {
824 v.visit()(
826 [](Json::Value const&) {});
827 };
828 }(std::as_const(s1)));
829 BEAST_EXPECT(
830 std::as_const(s1).visit()(
832 Overload{
833 [](Json::Value const& v) { return v["value"].asInt(); },
834 [](Json::Value&) { return 0; },
835 [](auto...) { return 0; }}) == 3);
836
837 static_assert([](auto&& v) {
838 return requires { v.visit(1, [](Json::Value&, unsigned) {}); };
839 }(s1));
840 BEAST_EXPECT(
841 s1.visit(
842 3u,
843 Overload{
844 [](Json::Value& v, unsigned) {
845 return v["value"].asInt();
846 },
847 [](Json::Value const&, unsigned) { return 0; },
848 [](Json::Value&, auto) { return 0; },
849 [](auto, auto) { return 0; }}) == 5);
850 static_assert([](auto&& v) {
851 return requires {
852 v.visit()(1, [](Json::Value&, unsigned) {});
853 };
854 }(s1));
855 BEAST_EXPECT(
856 s1.visit()(
857 3u,
858 Overload{
859 [](Json::Value& v, unsigned) {
860 return v["value"].asInt();
861 },
862 [](Json::Value const&, unsigned) { return 0; },
863 [](Json::Value&, auto) { return 0; },
864 [](auto, auto) { return 0; }}) == 5);
865
866 static_assert([](auto&& v) {
867 return requires { v.visit(1, [](Json::Value&) {}); };
868 }(s1));
869 BEAST_EXPECT(
870 s1.visit(
871 3,
872 Overload{
873 [](Json::Value& v) { return v["value"].asInt(); },
874 [](Json::Value const&) { return 0; },
875 [](auto...) { return 0; }}) == 5);
876 static_assert([](auto&& v) {
877 return requires { v.visit()(1, [](Json::Value&) {}); };
878 }(s1));
879 BEAST_EXPECT(
880 s1.visit()(
881 3,
882 Overload{
883 [](Json::Value& v) { return v["value"].asInt(); },
884 [](Json::Value const&) { return 0; },
885 [](auto...) { return 0; }}) == 5);
886
887 static_assert([](auto&& v) {
888 return requires {
889 v.visit(1, [](Json::Value const&, unsigned) {});
890 };
891 }(std::as_const(s1)));
892 BEAST_EXPECT(
894 2u,
895 Overload{
896 [](Json::Value const& v, unsigned) {
897 return v["value"].asInt();
898 },
899 [](Json::Value const&, auto) { return 0; },
900 [](Json::Value&, unsigned) { return 0; },
901 [](auto, auto) { return 0; }}) == 3);
902 static_assert([](auto&& v) {
903 return requires {
904 v.visit()(1, [](Json::Value const&, unsigned) {});
905 };
906 }(std::as_const(s1)));
907 BEAST_EXPECT(
908 std::as_const(s1).visit()(
909 2u,
910 Overload{
911 [](Json::Value const& v, unsigned) {
912 return v["value"].asInt();
913 },
914 [](Json::Value const&, auto) { return 0; },
915 [](Json::Value&, unsigned) { return 0; },
916 [](auto, auto) { return 0; }}) == 3);
917
918 static_assert([](auto&& v) {
919 return requires { v.visit(1, [](Json::Value const&) {}); };
920 }(std::as_const(s1)));
921 BEAST_EXPECT(
923 2,
924 Overload{
925 [](Json::Value const& v) { return v["value"].asInt(); },
926 [](Json::Value&) { return 0; },
927 [](auto...) { return 0; }}) == 3);
928 static_assert([](auto&& v) {
929 return requires { v.visit()(1, [](Json::Value const&) {}); };
930 }(std::as_const(s1)));
931 BEAST_EXPECT(
932 std::as_const(s1).visit()(
933 2,
934 Overload{
935 [](Json::Value const& v) { return v["value"].asInt(); },
936 [](Json::Value&) { return 0; },
937 [](auto...) { return 0; }}) == 3);
938
939 // Rvalue MultivarJson visitor only binds to regular reference
940 static_assert([](auto&& v) {
941 return !requires {
942 std::forward<decltype(v)>(v).visit(1, [](Json::Value&&) {});
943 };
944 }(std::move(s1)));
945 static_assert([](auto&& v) {
946 return !requires {
948 1, [](Json::Value const&&) {});
949 };
950 }(std::move(s1)));
951 static_assert([](auto&& v) {
952 return requires {
953 std::forward<decltype(v)>(v).visit(1, [](Json::Value&) {});
954 };
955 }(std::move(s1)));
956 static_assert([](auto&& v) {
957 return requires {
959 1, [](Json::Value const&) {});
960 };
961 }(std::move(s1)));
962 static_assert([](auto&& v) {
963 return !requires {
964 std::forward<decltype(v)>(v).visit()(
965 1, [](Json::Value&&) {});
966 };
967 }(std::move(s1)));
968 static_assert([](auto&& v) {
969 return !requires {
970 std::forward<decltype(v)>(v).visit()(
971 1, [](Json::Value const&&) {});
972 };
973 }(std::move(s1)));
974 static_assert([](auto&& v) {
975 return requires {
976 std::forward<decltype(v)>(v).visit()(
977 1, [](Json::Value&) {});
978 };
979 }(std::move(s1)));
980 static_assert([](auto&& v) {
981 return requires {
982 std::forward<decltype(v)>(v).visit()(
983 1, [](Json::Value const&) {});
984 };
985 }(std::move(s1)));
986 static_assert([](auto&& v) {
987 return !requires {
989 1, [](Json::Value const&&) {});
990 };
991 }(std::move(std::as_const(s1))));
992 static_assert([](auto&& v) {
993 return requires {
995 1, [](Json::Value const&) {});
996 };
997 }(std::move(std::as_const(s1))));
998 static_assert([](auto&& v) {
999 return !requires {
1000 std::forward<decltype(v)>(v).visit()(
1001 1, [](Json::Value const&&) {});
1002 };
1003 }(std::move(std::as_const(s1))));
1004 static_assert([](auto&& v) {
1005 return requires {
1006 std::forward<decltype(v)>(v).visit()(
1007 1, [](Json::Value const&) {});
1008 };
1009 }(std::move(std::as_const(s1))));
1010
1011 // Missing const
1012 static_assert([](auto&& v) {
1013 return !requires {
1015 1, [](Json::Value&, auto) {});
1016 };
1017 }(std::as_const(s1)));
1018 static_assert([](auto&& v) {
1019 return !requires {
1020 std::forward<decltype(v)>(v).visit()(
1021 1, [](Json::Value&, auto) {});
1022 };
1023 }(std::as_const(s1)));
1024
1025 // Missing parameter
1026 static_assert([](auto&& v) {
1027 return !requires {
1028 std::forward<decltype(v)>(v).visit(1, []() {});
1029 };
1030 }(s1));
1031 static_assert([](auto&& v) {
1032 return !requires {
1033 std::forward<decltype(v)>(v).visit()(1, []() {});
1034 };
1035 }(s1));
1036
1037 // Sanity checks
1038 static_assert([](auto&& v) {
1039 return requires {
1040 std::forward<decltype(v)>(v).visit(1, [](auto...) {});
1041 };
1042 }(std::as_const(s1)));
1043 static_assert([](auto&& v) {
1044 return requires {
1045 std::forward<decltype(v)>(v).visit()(1, [](auto...) {});
1046 };
1047 }(std::as_const(s1)));
1048 }
1049 }
1050};
1051
1052BEAST_DEFINE_TESTSUITE(MultiApiJson, protocol, ripple);
1053
1054} // namespace test
1055} // namespace ripple
T as_const(T... args)
Represents a JSON value.
Definition json_value.h:130
Int asInt() const
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:152
Inject raw JSON.
Definition jtx_json.h:14
T forward(T... args)
T is_same_v
@ nullValue
'null' value
Definition json_value.h:19
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
static constexpr auto apiMaximumValidVersion
Definition ApiVersion.h:48
static constexpr auto apiMinimumSupportedVersion
Definition ApiVersion.h:42
static none_t const none
Definition tags.h:15
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
void forAllApiVersions(Fn const &fn, Args &&... args)
Definition ApiVersion.h:158
void forApiVersions(Fn const &fn, Args &&... args)
Definition ApiVersion.h:136
T size(T... args)
std::array< Json::Value, size > val
void run() override
Runs the suite.
static auto makeJson(char const *key, int val)
T visit(T... args)