xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
protocol
MultiApiJson.h
1
#pragma once
2
3
#include <xrpl/beast/utility/instrumentation.h>
4
#include <xrpl/json/json_value.h>
5
#include <xrpl/protocol/ApiVersion.h>
6
7
#include <
array
>
8
#include <
concepts
>
9
#include <
cstdlib
>
10
#include <
functional
>
11
#include <
type_traits
>
12
#include <
utility
>
13
14
namespace
xrpl
{
15
16
namespace
detail
{
17
template
<
typename
T>
18
constexpr
bool
kIsIntegralConstant
=
false
;
19
template
<
typename
I, auto A>
20
constexpr
bool
kIsIntegralConstant<std::integral_constant<I, A>
&> =
true
;
21
template
<
typename
I, auto A>
22
constexpr
bool
kIsIntegralConstant<std::integral_constant<I, A>
const
&> =
true
;
23
24
template
<
typename
T>
25
concept
some_integral_constant
=
detail::kIsIntegralConstant<T&>
;
26
27
// This class is designed to wrap a collection of _almost_ identical json::Value
28
// objects, indexed by version (i.e. there is some mapping of version to object
29
// index). It is used e.g. when we need to publish JSON data to users supporting
30
// different API versions. We allow manipulation and inspection of all objects
31
// at once with `isMember` and `set`, and also individual inspection and updates
32
// of an object selected by the user by version, using `visitor_t` nested type.
33
template
<
unsigned
MinVer,
unsigned
MaxVer>
34
struct
MultiApiJson
35
{
36
static_assert
(MinVer <= MaxVer);
37
38
static
constexpr
auto
39
valid
(
unsigned
int
v)
noexcept
->
bool
40
{
41
return
v >= MinVer && v <= MaxVer;
42
}
43
44
static
constexpr
auto
45
index
(
unsigned
int
v)
noexcept
->
std::size_t
46
{
47
return
(v < MinVer) ? 0 :
static_cast<
std::size_t
>
(v - MinVer);
48
}
49
50
static
constexpr
std::size_t
kSize
= MaxVer + 1 - MinVer;
51
std::array<json::Value, kSize>
val
= {};
52
53
explicit
MultiApiJson
(
json::Value
const
& init = {})
54
{
55
if
(init ==
json::Value
{})
56
return
;
// All elements are already default-initialized
57
for
(
auto
& v :
val
)
58
v = init;
59
}
60
61
void
62
set
(
char
const
* key,
auto
const
& v)
63
requires
std::constructible_from<
json::Value
,
decltype
(v)>
64
{
65
for
(
auto
& a : this->val)
66
a[key] = v;
67
}
68
69
enum class
IsMemberResult
:
int
{
None
= 0,
Some
,
All
};
70
71
[[nodiscard]]
IsMemberResult
72
isMember
(
char
const
* key)
const
73
{
74
int
count = 0;
75
for
(
auto
& a : this->val)
76
{
77
if
(a.isMember(key))
78
count += 1;
79
}
80
81
if
(count == 0)
82
return
IsMemberResult::None
;
83
return
count <
kSize
?
IsMemberResult::Some
:
IsMemberResult::All
;
84
}
85
86
static
constexpr
struct
VisitorT
final
87
{
88
// integral_constant version, extra arguments
89
template
<
typename
Json,
unsigned
int
Version,
typename
... Args,
typename
Fn>
90
requires
std::same_as<std::remove_cvref_t<Json>,
MultiApiJson
>
91
auto
92
operator()
(
93
Json&
json
,
94
std::integral_constant<unsigned int, Version>
const
version,
95
Fn fn,
96
Args&&... args)
const
97
->
std::invoke_result_t
<
98
Fn,
99
decltype
(
json
.val[0]),
100
std::integral_constant<unsigned int, Version>
,
101
Args&&...>
102
{
103
static_assert
(
valid
(Version) &&
index
(Version) >= 0 &&
index
(Version) <
kSize
);
104
return
std::invoke
(fn,
json
.val[
index
(Version)], version,
std::forward<Args>
(args)...);
105
}
106
107
// integral_constant version, Json only
108
template
<
typename
Json,
unsigned
int
Version,
typename
Fn>
109
requires
std::same_as<std::remove_cvref_t<Json>,
MultiApiJson
>
110
auto
111
operator()
(Json&
json
,
std::integral_constant<unsigned int, Version>
const
, Fn fn)
const
112
->
std::invoke_result_t
<Fn,
decltype
(
json
.val[0])>
113
{
114
static_assert
(
valid
(Version) &&
index
(Version) >= 0 &&
index
(Version) <
kSize
);
115
return
std::invoke
(fn,
json
.val[
index
(Version)]);
116
}
117
118
// unsigned int version, extra arguments
119
template
<
typename
Json,
typename
Version,
typename
... Args,
typename
Fn>
120
requires
(!
some_integral_constant<Version>
) && std::convertible_to<Version, unsigned> &&
121
std::same_as<
std::remove_cvref_t<Json>
,
MultiApiJson
>
122
auto
123
operator
()(Json&
json
, Version version, Fn fn, Args&&... args)
const
124
->
std::invoke_result_t
<Fn,
decltype
(
json
.val[0]), Version, Args&&...>
125
{
126
XRPL_ASSERT(
127
valid
(version) &&
index
(version) >= 0 &&
index
(version) <
kSize
,
128
"xrpl::detail::MultiApijson::operator<Args...>() : valid "
129
"version"
);
130
return
std::invoke
(fn,
json
.val[
index
(version)], version,
std::forward<Args>
(args)...);
131
}
132
133
// unsigned int version, Json only
134
template
<
typename
Json,
typename
Version,
typename
Fn>
135
requires
(!
some_integral_constant<Version>
) && std::convertible_to<Version, unsigned> &&
136
std::same_as<
std::remove_cvref_t<Json>
,
MultiApiJson
>
137
auto
138
operator
()(Json&
json
, Version version, Fn fn)
const
139
->
std::invoke_result_t
<Fn,
decltype
(
json
.val[0])>
140
{
141
XRPL_ASSERT(
142
valid
(version) &&
index
(version) >= 0 &&
index
(version) <
kSize
,
143
"xrpl::detail::MultiApijson::operator() : valid version"
);
144
return
std::invoke
(fn,
json
.val[
index
(version)]);
145
}
146
}
kVisitor
= {};
147
148
auto
149
visit
()
150
{
151
return
[self =
this
](
auto
... args)
152
requires
requires
{
153
kVisitor
(
std::declval<MultiApiJson&>
(),
std::declval
<
decltype
(args)>()...);
154
}
155
{
return
kVisitor
(*self,
std::forward
<
decltype
(args)>(args)...); };
156
}
157
158
[[nodiscard]]
auto
159
visit
()
const
160
{
161
return
[self =
this
](
auto
... args)
162
requires
requires
{
163
kVisitor
(
std::declval<MultiApiJson const&>
(),
std::declval
<
decltype
(args)>()...);
164
}
165
{
return
kVisitor
(*self,
std::forward
<
decltype
(args)>(args)...); };
166
}
167
168
template
<
typename
... Args>
169
auto
170
visit
(Args... args) ->
std::invoke_result_t
<VisitorT,
MultiApiJson
&, Args...>
171
requires
(
sizeof
...(args) > 0) &&
172
requires
{
kVisitor
(*
this
,
std::forward
<
decltype
(args)>(args)...); }
173
{
174
return
kVisitor
(*
this
,
std::forward
<
decltype
(args)>(args)...);
175
}
176
177
template
<
typename
... Args>
178
[[nodiscard]]
auto
179
visit
(Args... args)
const
->
std::invoke_result_t
<VisitorT,
MultiApiJson
const
&, Args...>
180
requires
(
sizeof
...(args) > 0) &&
181
requires
{
kVisitor
(*
this
,
std::forward
<
decltype
(args)>(args)...); }
182
{
183
return
kVisitor
(*
this
,
std::forward
<
decltype
(args)>(args)...);
184
}
185
};
186
187
}
// namespace detail
188
189
// Wrapper for Json for all supported API versions.
190
using
MultiApiJson
=
191
detail::MultiApiJson<rpc::kApiMinimumSupportedVersion, rpc::kApiMaximumValidVersion>
;
192
193
}
// namespace xrpl
array
json::Value
Represents a JSON value.
Definition
json_value.h:117
concepts
xrpl::detail::some_integral_constant
Definition
MultiApiJson.h:25
cstdlib
std::declval
T declval(T... args)
std::forward
T forward(T... args)
functional
std::integral_constant
std::invoke
T invoke(T... args)
json
JSON (JavaScript Object Notation).
Definition
json_errors.h:5
xrpl::detail
Definition
base_uint.h:37
xrpl::detail::kIsIntegralConstant
constexpr bool kIsIntegralConstant
Definition
MultiApiJson.h:18
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::MultiApiJson
detail::MultiApiJson< rpc::kApiMinimumSupportedVersion, rpc::kApiMaximumValidVersion > MultiApiJson
Definition
MultiApiJson.h:190
std::remove_cvref_t
std::invoke_result_t
std::size_t
xrpl::detail::MultiApiJson::VisitorT
Definition
MultiApiJson.h:87
xrpl::detail::MultiApiJson::VisitorT::operator()
auto operator()(Json &json, std::integral_constant< unsigned int, Version > const, Fn fn) const -> std::invoke_result_t< Fn, decltype(json.val[0])>
Definition
MultiApiJson.h:111
xrpl::detail::MultiApiJson::VisitorT::operator()
auto operator()(Json &json, std::integral_constant< unsigned int, Version > const version, Fn fn, Args &&... args) const -> std::invoke_result_t< Fn, decltype(json.val[0]), std::integral_constant< unsigned int, Version >, Args &&... >
Definition
MultiApiJson.h:92
xrpl::detail::MultiApiJson
Definition
MultiApiJson.h:35
xrpl::detail::MultiApiJson::visit
auto visit(Args... args) const -> std::invoke_result_t< VisitorT, MultiApiJson const &, Args... > requires(sizeof...(args) > 0) &&
Definition
MultiApiJson.h:179
xrpl::detail::MultiApiJson::set
void set(char const *key, auto const &v)
Definition
MultiApiJson.h:62
xrpl::detail::MultiApiJson::isMember
IsMemberResult isMember(char const *key) const
Definition
MultiApiJson.h:72
xrpl::detail::MultiApiJson::kVisitor
static constexpr struct xrpl::detail::MultiApiJson::VisitorT kVisitor
xrpl::detail::MultiApiJson::visit
auto visit()
Definition
MultiApiJson.h:149
xrpl::detail::MultiApiJson< rpc::kApiMinimumSupportedVersion, rpc::kApiMaximumValidVersion >::val
std::array< json::Value, kSize > val
Definition
MultiApiJson.h:51
xrpl::detail::MultiApiJson::valid
static constexpr auto valid(unsigned int v) noexcept -> bool
Definition
MultiApiJson.h:39
xrpl::detail::MultiApiJson::visit
auto visit() const
Definition
MultiApiJson.h:159
xrpl::detail::MultiApiJson::index
static constexpr auto index(unsigned int v) noexcept -> std::size_t
Definition
MultiApiJson.h:45
xrpl::detail::MultiApiJson::visit
auto visit(Args... args) -> std::invoke_result_t< VisitorT, MultiApiJson &, Args... > requires(sizeof...(args) > 0) &&
Definition
MultiApiJson.h:170
xrpl::detail::MultiApiJson< rpc::kApiMinimumSupportedVersion, rpc::kApiMaximumValidVersion >::kSize
static constexpr std::size_t kSize
Definition
MultiApiJson.h:50
xrpl::detail::MultiApiJson::MultiApiJson
MultiApiJson(json::Value const &init={})
Definition
MultiApiJson.h:53
xrpl::detail::MultiApiJson::IsMemberResult
IsMemberResult
Definition
MultiApiJson.h:69
xrpl::detail::MultiApiJson::IsMemberResult::Some
@ Some
Definition
MultiApiJson.h:69
xrpl::detail::MultiApiJson::IsMemberResult::None
@ None
Definition
MultiApiJson.h:69
xrpl::detail::MultiApiJson::IsMemberResult::All
@ All
Definition
MultiApiJson.h:69
type_traits
utility
Generated by
1.17.0