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