rippled
Loading...
Searching...
No Matches
LexicalCast_test.cpp
1#include <xrpl/beast/core/LexicalCast.h>
2#include <xrpl/beast/unit_test.h>
3#include <xrpl/beast/xor_shift_engine.h>
4
5namespace beast {
6
8{
9public:
10 template <class IntType>
11 static IntType
13 {
14 return static_cast<IntType>(r());
15 }
16
17 template <class IntType>
18 void
19 testInteger(IntType in)
20 {
22 IntType out(in + 1);
23
26 expect(out == in);
27 }
28
29 template <class IntType>
30 void
32 {
33 {
35 ss << "random " << typeid(IntType).name();
36 testcase(ss.str());
37
38 for (int i = 0; i < 1000; ++i)
39 {
40 IntType const value(nextRandomInt<IntType>(r));
41 testInteger(value);
42 }
43 }
44
45 {
47 ss << "numeric_limits <" << typeid(IntType).name() << ">";
48 testcase(ss.str());
49
52 }
53 }
54
55 void
57 {
58 testcase("pathologies");
59 try
60 {
61 lexicalCastThrow<int>("\xef\xbc\x91\xef\xbc\x90"); // utf-8 encoded
62 }
63 catch (BadLexicalCast const&)
64 {
65 pass();
66 }
67 }
68
69 template <class T>
70 void
72 {
73 T out;
74 expect(!lexicalCastChecked(out, s), s);
75 }
76
77 void
79 {
80 testcase("conversion overflows");
81
82 tryBadConvert<std::uint64_t>("99999999999999999999");
83 tryBadConvert<std::uint32_t>("4294967300");
84 tryBadConvert<std::uint16_t>("75821");
85 }
86
87 void
89 {
90 testcase("conversion underflows");
91
92 tryBadConvert<std::uint32_t>("-1");
93
94 tryBadConvert<std::int64_t>("-99999999999999999999");
95 tryBadConvert<std::int32_t>("-4294967300");
96 tryBadConvert<std::int16_t>("-75821");
97 }
98
99 template <class T>
100 bool
102 {
103 T ret;
104
105 bool const result = lexicalCastChecked(ret, s);
106
107 if (!result)
108 return false;
109
110 return s == std::to_string(ret);
111 }
112
113 void
115 {
116 testcase("conversion edge cases");
117
118 expect(tryEdgeCase<std::uint64_t>("18446744073709551614"));
119 expect(tryEdgeCase<std::uint64_t>("18446744073709551615"));
120 expect(!tryEdgeCase<std::uint64_t>("18446744073709551616"));
121
122 expect(tryEdgeCase<std::int64_t>("9223372036854775806"));
123 expect(tryEdgeCase<std::int64_t>("9223372036854775807"));
124 expect(!tryEdgeCase<std::int64_t>("9223372036854775808"));
125
126 expect(tryEdgeCase<std::int64_t>("-9223372036854775807"));
127 expect(tryEdgeCase<std::int64_t>("-9223372036854775808"));
128 expect(!tryEdgeCase<std::int64_t>("-9223372036854775809"));
129
130 expect(tryEdgeCase<std::uint32_t>("4294967294"));
131 expect(tryEdgeCase<std::uint32_t>("4294967295"));
132 expect(!tryEdgeCase<std::uint32_t>("4294967296"));
133
134 expect(tryEdgeCase<std::int32_t>("2147483646"));
135 expect(tryEdgeCase<std::int32_t>("2147483647"));
136 expect(!tryEdgeCase<std::int32_t>("2147483648"));
137
138 expect(tryEdgeCase<std::int32_t>("-2147483647"));
139 expect(tryEdgeCase<std::int32_t>("-2147483648"));
140 expect(!tryEdgeCase<std::int32_t>("-2147483649"));
141
142 expect(tryEdgeCase<std::uint16_t>("65534"));
143 expect(tryEdgeCase<std::uint16_t>("65535"));
144 expect(!tryEdgeCase<std::uint16_t>("65536"));
145
146 expect(tryEdgeCase<std::int16_t>("32766"));
147 expect(tryEdgeCase<std::int16_t>("32767"));
148 expect(!tryEdgeCase<std::int16_t>("32768"));
149
150 expect(tryEdgeCase<std::int16_t>("-32767"));
151 expect(tryEdgeCase<std::int16_t>("-32768"));
152 expect(!tryEdgeCase<std::int16_t>("-32769"));
153 }
154
155 template <class T>
156 void
157 testThrowConvert(std::string const& s, bool success)
158 {
159 bool result = !success;
160 T out;
161
162 try
163 {
164 out = lexicalCastThrow<T>(s);
165 result = true;
166 }
167 catch (BadLexicalCast const&)
168 {
169 result = false;
170 }
171
172 expect(result == success, s);
173 }
174
175 void
177 {
178 testcase("throwing conversion");
179
180 testThrowConvert<std::uint64_t>("99999999999999999999", false);
181 testThrowConvert<std::uint64_t>("9223372036854775806", true);
182
183 testThrowConvert<std::uint32_t>("4294967290", true);
184 testThrowConvert<std::uint32_t>("42949672900", false);
185 testThrowConvert<std::uint32_t>("429496729000", false);
186 testThrowConvert<std::uint32_t>("4294967290000", false);
187
188 testThrowConvert<std::int32_t>("5294967295", false);
189 testThrowConvert<std::int32_t>("-2147483644", true);
190
191 testThrowConvert<std::int16_t>("66666", false);
192 testThrowConvert<std::int16_t>("-5711", true);
193 }
194
195 void
197 {
198 testcase("zero conversion");
199
200 {
201 std::int32_t out;
202
203 expect(lexicalCastChecked(out, "-0"), "0");
204 expect(lexicalCastChecked(out, "0"), "0");
205 expect(lexicalCastChecked(out, "+0"), "0");
206 }
207
208 {
209 std::uint32_t out;
210
211 expect(!lexicalCastChecked(out, "-0"), "0");
212 expect(lexicalCastChecked(out, "0"), "0");
213 expect(lexicalCastChecked(out, "+0"), "0");
214 }
215 }
216
217 void
219 {
220 testcase("entire range");
221
223 std::string const empty("");
224
226 {
227 std::int16_t j = static_cast<std::int16_t>(i);
228
229 auto actual = std::to_string(j);
230
231 auto result = lexicalCast(j, empty);
232
233 expect(result == actual, actual + " (string to integer)");
234
235 if (result == actual)
236 {
237 auto number = lexicalCast<std::int16_t>(result);
238
239 if (number != j)
240 expect(false, actual + " (integer to string)");
241 }
242
243 i++;
244 }
245 }
246
247 void
248 run() override
249 {
250 std::int64_t const seedValue = 50;
251
252 xor_shift_engine r(seedValue);
253
254 testIntegers<int>(r);
255 testIntegers<unsigned int>(r);
256 testIntegers<short>(r);
257 testIntegers<unsigned short>(r);
258 testIntegers<std::int32_t>(r);
259 testIntegers<std::uint32_t>(r);
260 testIntegers<std::int64_t>(r);
261 testIntegers<std::uint64_t>(r);
262
267 testZero();
270 }
271};
272
273BEAST_DEFINE_TESTSUITE(LexicalCast, beast, beast);
274
275} // namespace beast
static IntType nextRandomInt(xor_shift_engine &r)
void testIntegers(xor_shift_engine &r)
void run() override
Runs the suite.
bool tryEdgeCase(std::string const &s)
void testThrowConvert(std::string const &s, bool success)
void tryBadConvert(std::string const &s)
A testsuite class.
Definition suite.h:52
void pass()
Record a successful test condition.
Definition suite.h:508
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:152
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition suite.h:226
T min(T... args)
Out lexicalCast(In in, Out defaultValue=Out())
Convert from one type to another.
bool lexicalCastChecked(Out &out, In in)
Intelligently convert from one type to another.
T str(T... args)
Thrown when a conversion is not possible with LexicalCast.
T to_string(T... args)