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
67
68 int productAllVersions = 1;
70 {
71 auto const index = i - RPC::apiMinimumSupportedVersion;
72 BEAST_EXPECT(index == s1.index(i));
73 BEAST_EXPECT(s1.valid(i));
74 s1.val[index] = makeJson("value", primes[i]);
75 productAllVersions *= primes[i];
76 }
77 BEAST_EXPECT(!s1.valid(0));
78 BEAST_EXPECT(!s1.valid(RPC::apiMaximumValidVersion + 1));
79 BEAST_EXPECT(!s1.valid(std::numeric_limits<decltype(RPC::apiMaximumValidVersion.value)>::max()));
80
81 int result = 1;
83 forApiVersions<RPC::apiMinimumSupportedVersion, RPC::apiMinimumSupportedVersion + 1>(
84 std::as_const(s1).visit(),
85 [this](Json::Value const& json, unsigned int version, int* result) {
86 BEAST_EXPECT(
88 if (BEAST_EXPECT(json.isMember("value")))
89 {
90 *result *= json["value"].asInt();
91 }
92 },
93 &result);
94 BEAST_EXPECT(
96
97 // Check all the values with mutable data
98 forAllApiVersions(s1.visit(), [&s1, this](Json::Value& json, auto version) {
99 BEAST_EXPECT(s1.val[s1.index(version)] == json);
100 if (BEAST_EXPECT(json.isMember("value")))
101 {
102 BEAST_EXPECT(json["value"].asInt() == primes[version]);
103 }
104 });
105
106 result = 1;
108 std::as_const(s1).visit(),
109 [this](Json::Value const& json, unsigned int version, int* result) {
110 BEAST_EXPECT(version >= RPC::apiMinimumSupportedVersion && version <= RPC::apiMaximumValidVersion);
111 if (BEAST_EXPECT(json.isMember("value")))
112 {
113 *result *= json["value"].asInt();
114 }
115 },
116 &result);
117
118 BEAST_EXPECT(result == productAllVersions);
119
120 // Several overloads we want to fail
121 static_assert([](auto&& v) {
122 return !requires {
124 std::forward<decltype(v)>(v).visit(), //
125 [](Json::Value&, auto) {}); // missing const
126 };
127 }(std::as_const(s1)));
128 static_assert([](auto&& v) {
129 return !requires {
131 std::forward<decltype(v)>(v).visit(), //
132 [](Json::Value&) {}); // missing const
133 };
134 }(std::as_const(s1)));
135 static_assert([](auto&& v) {
136 return !requires {
138 std::forward<decltype(v)>(v).visit(), //
139 []() {}); // missing parameters
140 };
141 }(std::as_const(s1)));
142 static_assert([](auto&& v) {
143 return !requires {
145 std::forward<decltype(v)>(v).visit(), //
146 [](auto) {},
147 1); // 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, 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, char const*) {},
163 1); // parameter type mismatch
164 };
165 }(std::as_const(s1)));
166
167 // Sanity checks
168 static_assert([](auto&& v) {
169 return requires {
171 std::forward<decltype(v)>(v).visit(), //
172 [](auto) {});
173 };
174 }(s1));
175 static_assert([](auto&& v) {
176 return requires {
178 std::forward<decltype(v)>(v).visit(), //
179 [](Json::Value const&) {});
180 };
181 }(std::as_const(s1)));
182 static_assert([](auto&& v) {
183 return requires {
185 std::forward<decltype(v)>(v).visit(), //
186 [](auto...) {});
187 };
188 }(s1));
189 static_assert([](auto&& v) {
190 return requires {
192 std::forward<decltype(v)>(v).visit(), //
193 [](Json::Value const&, auto...) {});
194 };
195 }(std::as_const(s1)));
196 static_assert([](auto&& v) {
197 return requires {
199 std::forward<decltype(v)>(v).visit(), //
200 [](Json::Value&, auto, auto, auto...) {},
201 0,
202 "");
203 };
204 }(s1));
205 static_assert([](auto&& v) {
206 return requires {
208 std::forward<decltype(v)>(v).visit(), //
209 []<unsigned int Version>(
211 0,
212 "");
213 };
214 }(std::as_const(s1)));
215 static_assert([](auto&& v) {
216 return requires {
218 std::forward<decltype(v)>(v).visit(), //
219 [](auto...) {});
220 };
221 }(std::move(s1)));
222 static_assert([](auto&& v) {
223 return requires {
225 std::forward<decltype(v)>(v).visit(), //
226 [](auto...) {});
227 };
228 }(std::move(std::as_const(s1))));
229 }
230
231 {
232 testcase("default copy construction / assignment");
233
234 MultiApiJson<1, 3> x{subject};
235
236 BEAST_EXPECT(x.val.size() == subject.val.size());
237 BEAST_EXPECT(x.val[0] == subject.val[0]);
238 BEAST_EXPECT(x.val[1] == subject.val[1]);
239 BEAST_EXPECT(x.val[2] == subject.val[2]);
240 BEAST_EXPECT(x.val == subject.val);
241 BEAST_EXPECT(&x.val[0] != &subject.val[0]);
242 BEAST_EXPECT(&x.val[1] != &subject.val[1]);
243 BEAST_EXPECT(&x.val[2] != &subject.val[2]);
244
246 BEAST_EXPECT((y.val == std::array<Json::Value, 3>{}));
247 y = subject;
248 BEAST_EXPECT(y.val == subject.val);
249 BEAST_EXPECT(&y.val[0] != &subject.val[0]);
250 BEAST_EXPECT(&y.val[1] != &subject.val[1]);
251 BEAST_EXPECT(&y.val[2] != &subject.val[2]);
252
253 y = std::move(x);
254 BEAST_EXPECT(y.val == subject.val);
255 BEAST_EXPECT(&y.val[0] != &subject.val[0]);
256 BEAST_EXPECT(&y.val[1] != &subject.val[1]);
257 BEAST_EXPECT(&y.val[2] != &subject.val[2]);
258 }
259
260 {
261 testcase("set");
262
263 auto x = MultiApiJson<1, 2>{Json::objectValue};
264 x.set("name1", 42);
265 BEAST_EXPECT(x.val[0].isMember("name1"));
266 BEAST_EXPECT(x.val[1].isMember("name1"));
267 BEAST_EXPECT(x.val[0]["name1"].isInt());
268 BEAST_EXPECT(x.val[1]["name1"].isInt());
269 BEAST_EXPECT(x.val[0]["name1"].asInt() == 42);
270 BEAST_EXPECT(x.val[1]["name1"].asInt() == 42);
271
272 x.set("name2", "bar");
273 BEAST_EXPECT(x.val[0].isMember("name2"));
274 BEAST_EXPECT(x.val[1].isMember("name2"));
275 BEAST_EXPECT(x.val[0]["name2"].isString());
276 BEAST_EXPECT(x.val[1]["name2"].isString());
277 BEAST_EXPECT(x.val[0]["name2"].asString() == "bar");
278 BEAST_EXPECT(x.val[1]["name2"].asString() == "bar");
279
280 // Tests of requires clause - these are expected to match
281 static_assert([](auto&& v) { return requires { v.set("name", Json::nullValue); }; }(x));
282 static_assert([](auto&& v) { return requires { v.set("name", "value"); }; }(x));
283 static_assert([](auto&& v) { return requires { v.set("name", true); }; }(x));
284 static_assert([](auto&& v) { return requires { v.set("name", 42); }; }(x));
285
286 // Tests of requires clause - these are expected NOT to match
287 struct foo_t final
288 {
289 };
290 static_assert([](auto&& v) { return !requires { v.set("name", foo_t{}); }; }(x));
291 static_assert([](auto&& v) { return !requires { v.set("name", std::nullopt); }; }(x));
292 }
293
294 {
295 testcase("isMember");
296
297 // Well defined behaviour even if we have different types of members
298 BEAST_EXPECT(subject.isMember("foo") == decltype(subject)::none);
299
300 {
301 // All variants have element "One", none have element "Two"
302 MultiApiJson<1, 2> s1{};
303 s1.val[0] = makeJson("One", 12);
304 s1.val[1] = makeJson("One", 42);
305 BEAST_EXPECT(s1.isMember("One") == decltype(s1)::all);
306 BEAST_EXPECT(s1.isMember("Two") == decltype(s1)::none);
307 }
308
309 {
310 // Some variants have element "One" and some have "Two"
311 MultiApiJson<1, 2> s2{};
312 s2.val[0] = makeJson("One", 12);
313 s2.val[1] = makeJson("Two", 42);
314 BEAST_EXPECT(s2.isMember("One") == decltype(s2)::some);
315 BEAST_EXPECT(s2.isMember("Two") == decltype(s2)::some);
316 }
317
318 {
319 // Not all variants have element "One", because last one is null
320 MultiApiJson<1, 3> s3{};
321 s3.val[0] = makeJson("One", 12);
322 s3.val[1] = makeJson("One", 42);
323 BEAST_EXPECT(s3.isMember("One") == decltype(s3)::some);
324 BEAST_EXPECT(s3.isMember("Two") == decltype(s3)::none);
325 }
326 }
327
328 {
329 testcase("visitor");
330
331 MultiApiJson<1, 3> s1{};
332 s1.val[0] = makeJson("value", 2);
333 s1.val[1] = makeJson("value", 3);
334 s1.val[2] = makeJson("value", 5);
335
336 BEAST_EXPECT(not s1.valid(0));
337 BEAST_EXPECT(s1.index(0) == 0);
338
339 BEAST_EXPECT(s1.valid(1));
340 BEAST_EXPECT(s1.index(1) == 0);
341
342 BEAST_EXPECT(not s1.valid(4));
343
344 // Test different overloads
345 static_assert([](auto&& v) {
346 return requires {
347 v.visitor(
348 v,
351 };
352 }(s1));
353 BEAST_EXPECT(
354 s1.visitor(
355 s1,
357 Overload{
358 [](Json::Value& v, std::integral_constant<unsigned, 1>) { return v["value"].asInt(); },
359 [](Json::Value const&, auto) { return 0; },
360 [](auto, auto) { return 0; }}) == 2);
361
362 static_assert([](auto&& v) {
363 return requires { v.visitor(v, std::integral_constant<unsigned, 1>{}, [](Json::Value&) {}); };
364 }(s1));
365 BEAST_EXPECT(
366 s1.visitor(
367 s1,
369 Overload{
370 [](Json::Value& v) { return v["value"].asInt(); },
371 [](Json::Value const&) { return 0; },
372 [](auto...) { return 0; }}) == 2);
373
374 static_assert([](auto&& v) {
375 return requires {
376 v.visitor(
377 v,
380 };
381 }(std::as_const(s1)));
382 BEAST_EXPECT(
383 s1.visitor(
384 std::as_const(s1),
386 Overload{
387 [](Json::Value const& v, std::integral_constant<unsigned, 2>) { return v["value"].asInt(); },
388 [](Json::Value&, auto) { return 0; },
389 [](auto, auto) { return 0; }}) == 3);
390
391 static_assert([](auto&& v) {
392 return requires { v.visitor(v, std::integral_constant<unsigned, 1>{}, [](Json::Value const&) {}); };
393 }(std::as_const(s1)));
394 BEAST_EXPECT(
395 s1.visitor(
396 std::as_const(s1),
398 Overload{
399 [](Json::Value const& v) { return v["value"].asInt(); },
400 [](Json::Value&) { return 0; },
401 [](auto...) { return 0; }}) == 3);
402
403 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](Json::Value&, unsigned) {}); }; }(s1));
404 BEAST_EXPECT(
405 s1.visitor(
406 s1, //
407 3u,
408 Overload{
409 [](Json::Value& v, unsigned) { return v["value"].asInt(); },
410 [](Json::Value const&, unsigned) { return 0; },
411 [](auto, auto) { return 0; }}) == 5);
412
413 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](Json::Value&) {}); }; }(s1));
414 BEAST_EXPECT(
415 s1.visitor(
416 s1, //
417 3,
418 Overload{
419 [](Json::Value& v) { return v["value"].asInt(); },
420 [](Json::Value const&) { return 0; },
421 [](auto...) { return 0; }}) == 5);
422
423 static_assert([](auto&& v) {
424 return requires { v.visitor(v, 1, [](Json::Value const&, unsigned) {}); };
425 }(std::as_const(s1)));
426 BEAST_EXPECT(
427 s1.visitor(
428 std::as_const(s1), //
429 2u,
430 Overload{
431 [](Json::Value const& v, unsigned) { return v["value"].asInt(); },
432 [](Json::Value const&, auto) { return 0; },
433 [](auto, auto) { return 0; }}) == 3);
434
435 static_assert(
436 [](auto&& v) { return requires { v.visitor(v, 1, [](Json::Value const&) {}); }; }(std::as_const(s1)));
437 BEAST_EXPECT(
438 s1.visitor(
439 std::as_const(s1), //
440 2,
441 Overload{
442 [](Json::Value const& v) { return v["value"].asInt(); },
443 [](Json::Value&) { return 0; },
444 [](auto...) { return 0; }}) == 3);
445
446 // Test type conversions
447 BEAST_EXPECT(
448 s1.visitor(
449 s1,
451 [](Json::Value& v, unsigned) { return v["value"].asInt(); }) == 2);
452 BEAST_EXPECT(
453 s1.visitor(
454 std::as_const(s1),
456 [](Json::Value const& v, unsigned) { return v["value"].asInt(); }) == 3);
457 BEAST_EXPECT(
458 s1.visitor(
459 s1, // to const
461 [](Json::Value const& v, auto) { return v["value"].asInt(); }) == 5);
462 BEAST_EXPECT(
463 s1.visitor(
464 s1, // to const
466 [](Json::Value const& v) { return v["value"].asInt(); }) == 5);
467 BEAST_EXPECT(
468 s1.visitor(
469 s1,
470 3, // to long
471 [](Json::Value& v, long) { return v["value"].asInt(); }) == 5);
472 BEAST_EXPECT(
473 s1.visitor(
474 std::as_const(s1),
475 1, // to long
476 [](Json::Value const& v, long) { return v["value"].asInt(); }) == 2);
477 BEAST_EXPECT(
478 s1.visitor(
479 s1, // to const
480 2,
481 [](Json::Value const& v, auto) { return v["value"].asInt(); }) == 3);
482 BEAST_EXPECT(
483 s1.visitor(
484 s1, // type deduction
485 2,
486 [](auto& v, auto) { return v["value"].asInt(); }) == 3);
487 BEAST_EXPECT(
488 s1.visitor(
489 s1, // to const, type deduction
490 2,
491 [](auto const& v, auto) { return v["value"].asInt(); }) == 3);
492 BEAST_EXPECT(
493 s1.visitor(
494 s1, // type deduction
495 2,
496 [](auto& v) { return v["value"].asInt(); }) == 3);
497 BEAST_EXPECT(
498 s1.visitor(
499 s1, // to const, type deduction
500 2,
501 [](auto const& v) { return v["value"].asInt(); }) == 3);
502
503 // Test passing of additional arguments
504 BEAST_EXPECT(
505 s1.visitor(
506 s1,
508 [](Json::Value& v, auto ver, auto a1, auto a2) { return ver * a1 * a2 * v["value"].asInt(); },
509 5,
510 7) == 2 * 5 * 7 * 3);
511 BEAST_EXPECT(
512 s1.visitor(
513 s1,
515 [](Json::Value& v, auto ver, auto... args) { return ver * (1 * ... * args) * v["value"].asInt(); },
516 5,
517 7) == 2 * 5 * 7 * 3);
518
519 // Several overloads we want to fail
520 static_assert([](auto&& v) {
521 return !requires {
522 v.visitor(
523 v,
524 1, //
525 [](Json::Value&, auto) {}); // missing const
526 };
527 }(std::as_const(s1)));
528
529 static_assert([](auto&& v) {
530 return !requires {
531 v.visitor(
532 std::move(v), // cannot bind rvalue
533 1,
534 [](Json::Value&, auto) {});
535 };
536 }(s1));
537
538 static_assert([](auto&& v) {
539 return !requires {
540 v.visitor(
541 v,
542 1, //
543 []() {}); // missing parameter
544 };
545 }(s1));
546
547 static_assert([](auto&& v) {
548 return !requires {
549 v.visitor(
550 v,
551 1, //
552 [](Json::Value&, int, int) {}); // too many parameters
553 };
554 }(s1));
555
556 // Want these to be unambiguous
557 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](auto) {}); }; }(s1));
558
559 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](Json::Value&) {}); }; }(s1));
560
561 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](Json::Value&, auto...) {}); }; }(s1));
562
563 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](Json::Value const&) {}); }; }(s1));
564
565 static_assert(
566 [](auto&& v) { return requires { v.visitor(v, 1, [](Json::Value const&, auto...) {}); }; }(s1));
567
568 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](auto...) {}); }; }(s1));
569
570 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](auto, auto...) {}); }; }(s1));
571
572 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](auto, auto, auto...) {}); }; }(s1));
573
574 static_assert([](auto&& v) { return requires { v.visitor(v, 1, [](auto, auto, auto...) {}, ""); }; }(s1));
575
576 static_assert(
577 [](auto&& v) { return requires { v.visitor(v, 1, [](auto, auto, auto, auto...) {}, ""); }; }(s1));
578 }
579
580 {
581 testcase("visit");
582
583 MultiApiJson<1, 3> s1{};
584 s1.val[0] = makeJson("value", 2);
585 s1.val[1] = makeJson("value", 3);
586 s1.val[2] = makeJson("value", 5);
587
588 // Test different overloads
589 static_assert([](auto&& v) {
590 return requires {
591 v.visit(
594 };
595 }(s1));
596 BEAST_EXPECT(
597 s1.visit(
599 Overload{
600 [](Json::Value& v, std::integral_constant<unsigned, 1>) { return v["value"].asInt(); },
601 [](Json::Value const&, auto) { return 0; },
602 [](auto, auto) { return 0; }}) == 2);
603 static_assert([](auto&& v) {
604 return requires {
605 v.visit()(
608 };
609 }(s1));
610 BEAST_EXPECT(
611 s1.visit()(
613 Overload{
614 [](Json::Value& v, std::integral_constant<unsigned, 1>) { return v["value"].asInt(); },
615 [](Json::Value const&, auto) { return 0; },
616 [](auto, auto) { return 0; }}) == 2);
617
618 static_assert([](auto&& v) {
619 return requires { v.visit(std::integral_constant<unsigned, 1>{}, [](Json::Value&) {}); };
620 }(s1));
621 BEAST_EXPECT(
622 s1.visit(
624 Overload{
625 [](Json::Value& v) { return v["value"].asInt(); },
626 [](Json::Value const&) { return 0; },
627 [](auto...) { return 0; }}) == 2);
628 static_assert([](auto&& v) {
629 return requires { v.visit()(std::integral_constant<unsigned, 1>{}, [](Json::Value&) {}); };
630 }(s1));
631 BEAST_EXPECT(
632 s1.visit()(
634 Overload{
635 [](Json::Value& v) { return v["value"].asInt(); },
636 [](Json::Value const&) { return 0; },
637 [](auto...) { return 0; }}) == 2);
638
639 static_assert([](auto&& v) {
640 return requires {
641 v.visit(
644 };
645 }(std::as_const(s1)));
646 BEAST_EXPECT(
649 Overload{
650 [](Json::Value const& v, std::integral_constant<unsigned, 2>) { return v["value"].asInt(); },
651 [](Json::Value&, auto) { return 0; },
652 [](auto, auto) { return 0; }}) == 3);
653 static_assert([](auto&& v) {
654 return requires {
655 v.visit()(
658 };
659 }(std::as_const(s1)));
660 BEAST_EXPECT(
661 std::as_const(s1).visit()(
663 Overload{
664 [](Json::Value const& v, std::integral_constant<unsigned, 2>) { return v["value"].asInt(); },
665 [](Json::Value&, auto) { return 0; },
666 [](auto, auto) { return 0; }}) == 3);
667
668 static_assert([](auto&& v) {
669 return requires { v.visit(std::integral_constant<unsigned, 1>{}, [](Json::Value const&) {}); };
670 }(std::as_const(s1)));
671 BEAST_EXPECT(
674 Overload{
675 [](Json::Value const& v) { return v["value"].asInt(); },
676 [](Json::Value&) { return 0; },
677 [](auto...) { return 0; }}) == 3);
678 static_assert([](auto&& v) {
679 return requires { v.visit()(std::integral_constant<unsigned, 1>{}, [](Json::Value const&) {}); };
680 }(std::as_const(s1)));
681 BEAST_EXPECT(
682 std::as_const(s1).visit()(
684 Overload{
685 [](Json::Value const& v) { return v["value"].asInt(); },
686 [](Json::Value&) { return 0; },
687 [](auto...) { return 0; }}) == 3);
688
689 static_assert([](auto&& v) { return requires { v.visit(1, [](Json::Value&, unsigned) {}); }; }(s1));
690 BEAST_EXPECT(
691 s1.visit(
692 3u,
693 Overload{
694 [](Json::Value& v, unsigned) { return v["value"].asInt(); },
695 [](Json::Value const&, unsigned) { return 0; },
696 [](Json::Value&, auto) { return 0; },
697 [](auto, auto) { return 0; }}) == 5);
698 static_assert([](auto&& v) { return requires { v.visit()(1, [](Json::Value&, unsigned) {}); }; }(s1));
699 BEAST_EXPECT(
700 s1.visit()(
701 3u,
702 Overload{
703 [](Json::Value& v, unsigned) { return v["value"].asInt(); },
704 [](Json::Value const&, unsigned) { return 0; },
705 [](Json::Value&, auto) { return 0; },
706 [](auto, auto) { return 0; }}) == 5);
707
708 static_assert([](auto&& v) { return requires { v.visit(1, [](Json::Value&) {}); }; }(s1));
709 BEAST_EXPECT(
710 s1.visit(
711 3,
712 Overload{
713 [](Json::Value& v) { return v["value"].asInt(); },
714 [](Json::Value const&) { return 0; },
715 [](auto...) { return 0; }}) == 5);
716 static_assert([](auto&& v) { return requires { v.visit()(1, [](Json::Value&) {}); }; }(s1));
717 BEAST_EXPECT(
718 s1.visit()(
719 3,
720 Overload{
721 [](Json::Value& v) { return v["value"].asInt(); },
722 [](Json::Value const&) { return 0; },
723 [](auto...) { return 0; }}) == 5);
724
725 static_assert([](auto&& v) {
726 return requires { v.visit(1, [](Json::Value const&, unsigned) {}); };
727 }(std::as_const(s1)));
728 BEAST_EXPECT(
730 2u,
731 Overload{
732 [](Json::Value const& v, unsigned) { return v["value"].asInt(); },
733 [](Json::Value const&, auto) { return 0; },
734 [](Json::Value&, unsigned) { return 0; },
735 [](auto, auto) { return 0; }}) == 3);
736 static_assert([](auto&& v) {
737 return requires { v.visit()(1, [](Json::Value const&, unsigned) {}); };
738 }(std::as_const(s1)));
739 BEAST_EXPECT(
740 std::as_const(s1).visit()(
741 2u,
742 Overload{
743 [](Json::Value const& v, unsigned) { return v["value"].asInt(); },
744 [](Json::Value const&, auto) { return 0; },
745 [](Json::Value&, unsigned) { return 0; },
746 [](auto, auto) { return 0; }}) == 3);
747
748 static_assert(
749 [](auto&& v) { return requires { v.visit(1, [](Json::Value const&) {}); }; }(std::as_const(s1)));
750 BEAST_EXPECT(
752 2,
753 Overload{
754 [](Json::Value const& v) { return v["value"].asInt(); },
755 [](Json::Value&) { return 0; },
756 [](auto...) { return 0; }}) == 3);
757 static_assert(
758 [](auto&& v) { return requires { v.visit()(1, [](Json::Value const&) {}); }; }(std::as_const(s1)));
759 BEAST_EXPECT(
760 std::as_const(s1).visit()(
761 2,
762 Overload{
763 [](Json::Value const& v) { return v["value"].asInt(); },
764 [](Json::Value&) { return 0; },
765 [](auto...) { return 0; }}) == 3);
766
767 // Rvalue MultivarJson visitor only binds to regular reference
768 static_assert([](auto&& v) {
769 return !requires { std::forward<decltype(v)>(v).visit(1, [](Json::Value&&) {}); };
770 }(std::move(s1)));
771 static_assert([](auto&& v) {
772 return !requires { std::forward<decltype(v)>(v).visit(1, [](Json::Value const&&) {}); };
773 }(std::move(s1)));
774 static_assert([](auto&& v) {
775 return requires { std::forward<decltype(v)>(v).visit(1, [](Json::Value&) {}); };
776 }(std::move(s1)));
777 static_assert([](auto&& v) {
778 return requires { std::forward<decltype(v)>(v).visit(1, [](Json::Value const&) {}); };
779 }(std::move(s1)));
780 static_assert([](auto&& v) {
781 return !requires { std::forward<decltype(v)>(v).visit()(1, [](Json::Value&&) {}); };
782 }(std::move(s1)));
783 static_assert([](auto&& v) {
784 return !requires { std::forward<decltype(v)>(v).visit()(1, [](Json::Value const&&) {}); };
785 }(std::move(s1)));
786 static_assert([](auto&& v) {
787 return requires { std::forward<decltype(v)>(v).visit()(1, [](Json::Value&) {}); };
788 }(std::move(s1)));
789 static_assert([](auto&& v) {
790 return requires { std::forward<decltype(v)>(v).visit()(1, [](Json::Value const&) {}); };
791 }(std::move(s1)));
792 static_assert([](auto&& v) {
793 return !requires { std::forward<decltype(v)>(v).visit(1, [](Json::Value const&&) {}); };
794 }(std::move(std::as_const(s1))));
795 static_assert([](auto&& v) {
796 return requires { std::forward<decltype(v)>(v).visit(1, [](Json::Value const&) {}); };
797 }(std::move(std::as_const(s1))));
798 static_assert([](auto&& v) {
799 return !requires { std::forward<decltype(v)>(v).visit()(1, [](Json::Value const&&) {}); };
800 }(std::move(std::as_const(s1))));
801 static_assert([](auto&& v) {
802 return requires { std::forward<decltype(v)>(v).visit()(1, [](Json::Value const&) {}); };
803 }(std::move(std::as_const(s1))));
804
805 // Missing const
806 static_assert([](auto&& v) {
807 return !requires { std::forward<decltype(v)>(v).visit(1, [](Json::Value&, auto) {}); };
808 }(std::as_const(s1)));
809 static_assert([](auto&& v) {
810 return !requires { std::forward<decltype(v)>(v).visit()(1, [](Json::Value&, auto) {}); };
811 }(std::as_const(s1)));
812
813 // Missing parameter
814 static_assert([](auto&& v) { return !requires { std::forward<decltype(v)>(v).visit(1, []() {}); }; }(s1));
815 static_assert([](auto&& v) { return !requires { std::forward<decltype(v)>(v).visit()(1, []() {}); }; }(s1));
816
817 // Sanity checks
818 static_assert([](auto&& v) {
819 return requires { std::forward<decltype(v)>(v).visit(1, [](auto...) {}); };
820 }(std::as_const(s1)));
821 static_assert([](auto&& v) {
822 return requires { std::forward<decltype(v)>(v).visit()(1, [](auto...) {}); };
823 }(std::as_const(s1)));
824 }
825 }
826};
827
828BEAST_DEFINE_TESTSUITE(MultiApiJson, protocol, xrpl);
829
830} // namespace test
831} // namespace xrpl
T as_const(T... args)
Represents a JSON value.
Definition json_value.h:131
Int asInt() const
A testsuite class.
Definition suite.h:52
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:148
Inject raw JSON.
Definition jtx_json.h:14
T forward(T... args)
T is_same_v
@ nullValue
'null' value
Definition json_value.h:20
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:27
static constexpr auto apiMinimumSupportedVersion
Definition ApiVersion.h:42
static constexpr auto apiMaximumValidVersion
Definition ApiVersion.h:47
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:145
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)