rippled
Loading...
Searching...
No Matches
LexicalCast.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of Beast: https://github.com/vinniefalco/Beast
4 Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
21#define BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
22
23#include <xrpl/beast/utility/instrumentation.h>
24
25#include <boost/core/detail/string_view.hpp>
26
27#include <algorithm>
28#include <cerrno>
29#include <charconv>
30#include <cstdlib>
31#include <iterator>
32#include <limits>
33#include <string>
34#include <type_traits>
35#include <typeinfo>
36#include <utility>
37
38namespace beast {
39
40namespace detail {
41
42// These specializatons get called by the non-member functions to do the work
43template <class Out, class In>
45
46// conversion to std::string
47template <class In>
48struct LexicalCast<std::string, In>
49{
50 explicit LexicalCast() = default;
51
52 template <class Arithmetic = In>
54 operator()(std::string& out, Arithmetic in)
55 {
56 out = std::to_string(in);
57 return true;
58 }
59
60 template <class Enumeration = In>
62 operator()(std::string& out, Enumeration in)
63 {
64 out = std::to_string(
66 return true;
67 }
68};
69
70// Parse a std::string_view into a number
71template <typename Out>
72struct LexicalCast<Out, std::string_view>
73{
74 explicit LexicalCast() = default;
75
76 static_assert(
77 std::is_integral_v<Out>,
78 "beast::LexicalCast can only be used with integral types");
79
80 template <class Integral = Out>
82 std::is_integral_v<Integral> && !std::is_same_v<Integral, bool>,
83 bool>
84 operator()(Integral& out, std::string_view in) const
85 {
86 auto first = in.data();
87 auto last = in.data() + in.size();
88
89 if (first != last && *first == '+')
90 ++first;
91
92 auto ret = std::from_chars(first, last, out);
93
94 return ret.ec == std::errc() && ret.ptr == last;
95 }
96
97 bool
98 operator()(bool& out, std::string_view in) const
99 {
100 std::string result;
101
102 // Convert the input to lowercase
104 in.begin(), in.end(), std::back_inserter(result), [](auto c) {
105 return std::tolower(static_cast<unsigned char>(c));
106 });
107
108 if (result == "1" || result == "true")
109 {
110 out = true;
111 return true;
112 }
113
114 if (result == "0" || result == "false")
115 {
116 out = false;
117 return true;
118 }
119
120 return false;
121 }
122};
123//------------------------------------------------------------------------------
124
125// Parse boost library's string_view to number or boolean value
126// Note: As of Jan 2024, Boost contains three different types of string_view
127// (boost::core::basic_string_view<char>, boost::string_ref and
128// boost::string_view). The below template specialization is included because
129// it is used in the handshake.cpp file
130template <class Out>
131struct LexicalCast<Out, boost::core::basic_string_view<char>>
132{
133 explicit LexicalCast() = default;
134
135 bool
136 operator()(Out& out, boost::core::basic_string_view<char> in) const
137 {
138 return LexicalCast<Out, std::string_view>()(out, in);
139 }
140};
141
142// Parse std::string to number or boolean value
143template <class Out>
144struct LexicalCast<Out, std::string>
145{
146 explicit LexicalCast() = default;
147
148 bool
149 operator()(Out& out, std::string in) const
150 {
151 return LexicalCast<Out, std::string_view>()(out, in);
152 }
153};
154
155// Conversion from null terminated char const*
156template <class Out>
157struct LexicalCast<Out, char const*>
158{
159 explicit LexicalCast() = default;
160
161 bool
162 operator()(Out& out, char const* in) const
163 {
164 XRPL_ASSERT(
165 in, "beast::detail::LexicalCast(char const*) : non-null input");
166 return LexicalCast<Out, std::string_view>()(out, in);
167 }
168};
169
170// Conversion from null terminated char*
171// The string is not modified.
172template <class Out>
173struct LexicalCast<Out, char*>
174{
175 explicit LexicalCast() = default;
176
177 bool
178 operator()(Out& out, char* in) const
179 {
180 XRPL_ASSERT(in, "beast::detail::LexicalCast(char*) : non-null input");
181 return LexicalCast<Out, std::string_view>()(out, in);
182 }
183};
184
185} // namespace detail
186
187//------------------------------------------------------------------------------
188
193{
194 explicit BadLexicalCast() = default;
195};
196
200template <class Out, class In>
201bool
202lexicalCastChecked(Out& out, In in)
203{
204 return detail::LexicalCast<Out, In>()(out, in);
205}
206
213template <class Out, class In>
214Out
216{
217 if (Out out; lexicalCastChecked(out, in))
218 return out;
219
220 throw BadLexicalCast();
221}
222
228template <class Out, class In>
229Out
230lexicalCast(In in, Out defaultValue = Out())
231{
232 if (Out out; lexicalCastChecked(out, in))
233 return out;
234
235 return defaultValue;
236}
237
238} // namespace beast
239
240#endif
T back_inserter(T... args)
T from_chars(T... args)
Out lexicalCastThrow(In in)
Convert from one type to another, throw on error.
Definition: LexicalCast.h:215
Out lexicalCast(In in, Out defaultValue=Out())
Convert from one type to another.
Definition: LexicalCast.h:230
bool lexicalCastChecked(Out &out, In in)
Intelligently convert from one type to another.
Definition: LexicalCast.h:202
STL namespace.
Thrown when a conversion is not possible with LexicalCast.
Definition: LexicalCast.h:193
bool operator()(Out &out, boost::core::basic_string_view< char > in) const
Definition: LexicalCast.h:136
bool operator()(Out &out, char *in) const
Definition: LexicalCast.h:178
bool operator()(Out &out, char const *in) const
Definition: LexicalCast.h:162
bool operator()(Out &out, std::string in) const
Definition: LexicalCast.h:149
std::enable_if_t< std::is_integral_v< Integral > &&!std::is_same_v< Integral, bool >, bool > operator()(Integral &out, std::string_view in) const
Definition: LexicalCast.h:84
bool operator()(bool &out, std::string_view in) const
Definition: LexicalCast.h:98
std::enable_if_t< std::is_arithmetic_v< Arithmetic >, bool > operator()(std::string &out, Arithmetic in)
Definition: LexicalCast.h:54
std::enable_if_t< std::is_enum_v< Enumeration >, bool > operator()(std::string &out, Enumeration in)
Definition: LexicalCast.h:62
T to_string(T... args)
T transform(T... args)