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 <string>
33#include <type_traits>
34#include <typeinfo>
35
36namespace beast {
37
38namespace detail {
39
40// These specializatons get called by the non-member functions to do the work
41template <class Out, class In>
43
44// conversion to std::string
45template <class In>
46struct LexicalCast<std::string, In>
47{
48 explicit LexicalCast() = default;
49
50 template <class Arithmetic = In>
52 operator()(std::string& out, Arithmetic in)
53 {
54 out = std::to_string(in);
55 return true;
56 }
57
58 template <class Enumeration = In>
60 operator()(std::string& out, Enumeration in)
61 {
62 out = std::to_string(
64 return true;
65 }
66};
67
68// Parse a std::string_view into a number
69template <typename Out>
70struct LexicalCast<Out, std::string_view>
71{
72 explicit LexicalCast() = default;
73
74 static_assert(
76 "beast::LexicalCast can only be used with integral types");
77
78 template <class Integral = Out>
81 bool>
82 operator()(Integral& out, std::string_view in) const
83 {
84 auto first = in.data();
85 auto last = in.data() + in.size();
86
87 if (first != last && *first == '+')
88 ++first;
89
90 auto ret = std::from_chars(first, last, out);
91
92 return ret.ec == std::errc() && ret.ptr == last;
93 }
94
95 bool
96 operator()(bool& out, std::string_view in) const
97 {
98 std::string result;
99
100 // Convert the input to lowercase
102 in.begin(), in.end(), std::back_inserter(result), [](auto c) {
103 return std::tolower(static_cast<unsigned char>(c));
104 });
105
106 if (result == "1" || result == "true")
107 {
108 out = true;
109 return true;
110 }
111
112 if (result == "0" || result == "false")
113 {
114 out = false;
115 return true;
116 }
117
118 return false;
119 }
120};
121//------------------------------------------------------------------------------
122
123// Parse boost library's string_view to number or boolean value
124// Note: As of Jan 2024, Boost contains three different types of string_view
125// (boost::core::basic_string_view<char>, boost::string_ref and
126// boost::string_view). The below template specialization is included because
127// it is used in the handshake.cpp file
128template <class Out>
129struct LexicalCast<Out, boost::core::basic_string_view<char>>
130{
131 explicit LexicalCast() = default;
132
133 bool
134 operator()(Out& out, boost::core::basic_string_view<char> in) const
135 {
136 return LexicalCast<Out, std::string_view>()(out, in);
137 }
138};
139
140// Parse std::string to number or boolean value
141template <class Out>
142struct LexicalCast<Out, std::string>
143{
144 explicit LexicalCast() = default;
145
146 bool
147 operator()(Out& out, std::string in) const
148 {
149 return LexicalCast<Out, std::string_view>()(out, in);
150 }
151};
152
153// Conversion from null terminated char const*
154template <class Out>
155struct LexicalCast<Out, char const*>
156{
157 explicit LexicalCast() = default;
158
159 bool
160 operator()(Out& out, char const* in) const
161 {
162 XRPL_ASSERT(
163 in, "beast::detail::LexicalCast(char const*) : non-null input");
164 return LexicalCast<Out, std::string_view>()(out, in);
165 }
166};
167
168// Conversion from null terminated char*
169// The string is not modified.
170template <class Out>
171struct LexicalCast<Out, char*>
172{
173 explicit LexicalCast() = default;
174
175 bool
176 operator()(Out& out, char* in) const
177 {
178 XRPL_ASSERT(in, "beast::detail::LexicalCast(char*) : non-null input");
179 return LexicalCast<Out, std::string_view>()(out, in);
180 }
181};
182
183} // namespace detail
184
185//------------------------------------------------------------------------------
186
191{
192 explicit BadLexicalCast() = default;
193};
194
198template <class Out, class In>
199bool
200lexicalCastChecked(Out& out, In in)
201{
202 return detail::LexicalCast<Out, In>()(out, in);
203}
204
211template <class Out, class In>
212Out
214{
215 if (Out out; lexicalCastChecked(out, in))
216 return out;
217
218 throw BadLexicalCast();
219}
220
226template <class Out, class In>
227Out
228lexicalCast(In in, Out defaultValue = Out())
229{
230 if (Out out; lexicalCastChecked(out, in))
231 return out;
232
233 return defaultValue;
234}
235
236} // namespace beast
237
238#endif
T back_inserter(T... args)
T from_chars(T... args)
T is_same_v
Out lexicalCastThrow(In in)
Convert from one type to another, throw on error.
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.
STL namespace.
Thrown when a conversion is not possible with LexicalCast.
bool operator()(Out &out, boost::core::basic_string_view< char > in) const
bool operator()(Out &out, char *in) const
bool operator()(Out &out, char const *in) const
bool operator()(Out &out, std::string in) const
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:82
bool operator()(bool &out, std::string_view in) const
Definition LexicalCast.h:96
std::enable_if_t< std::is_arithmetic_v< Arithmetic >, bool > operator()(std::string &out, Arithmetic in)
Definition LexicalCast.h:52
std::enable_if_t< std::is_enum_v< Enumeration >, bool > operator()(std::string &out, Enumeration in)
Definition LexicalCast.h:60
T to_string(T... args)
T transform(T... args)