24 #ifdef LEXICAL_CAST_DEBUG 25 #undef LEXICAL_CAST_HPP_INCLUDED 28 #ifndef LEXICAL_CAST_HPP_INCLUDED 29 #define LEXICAL_CAST_HPP_INCLUDED 31 #ifdef LEXICAL_CAST_DEBUG 41 #define DEBUG_THROW(id) throw id; 45 #define __LONG_LONG_SUPPORTED 55 #include <type_traits> 57 #define DEBUG_THROW(id) 70 ,
typename ToEnable = void
71 ,
typename FromEnable =
void 89 template<
typename To,
typename From>
106 template<
typename To,
typename From>
115 const char*
what() const noexcept
117 return "bad_lexical_cast";
138 ,
typename FromEnable
140 struct lexical_caster
147 std::stringstream sstr;
149 if(!(sstr << value && sstr >> result)) {
150 if(fallback) {
return *fallback; }
165 template <
typename From>
170 , std::enable_if_t<std::is_integral_v<std::remove_pointer_t<From>>>
173 std::string
operator()(From value, std::optional<std::string>)
const 175 DEBUG_THROW(
"specialized - To std::string - From integral (pointer)");
177 std::stringstream sstr;
190 template <
class From>
195 ,
std::enable_if_t<std::is_same_v<From, const char*> || std::is_same_v<From, char*>>
198 long long operator()(From value, std::optional<long long> fallback)
const 200 DEBUG_THROW(
"specialized - To long long - From (const) char*");
203 return lexical_cast_default<long long>(std::string(value), *fallback);
223 long long operator()(
const std::string& value, std::optional<long long> fallback)
const 225 DEBUG_THROW(
"specialized - To long long - From std::string");
228 return std::stoll(value);
229 }
catch(
const std::invalid_argument&) {
230 }
catch(
const std::out_of_range&) {
246 template <
class To,
class From>
250 ,
std::enable_if_t<std::is_integral_v<To> && std::is_signed_v<To> && !std::is_same_v<To, long long>>
251 , std::enable_if_t<std::is_same_v<From, const char*> || std::is_same_v<From, char*>>
256 DEBUG_THROW(
"specialized - To signed - From (const) char*");
259 return lexical_cast_default<To>(std::string(value), *fallback);
275 , std::enable_if_t<std::is_integral_v<To> && std::is_signed_v<To> && !std::is_same_v<To, long long>>
278 To
operator()(
const std::string& value, std::optional<To> fallback)
const 280 DEBUG_THROW(
"specialized - To signed - From std::string");
283 long res = std::stol(value);
284 if(std::numeric_limits<To>::lowest() <= res && std::numeric_limits<To>::max() >= res) {
285 return static_cast<To
>(res);
287 }
catch(
const std::invalid_argument&) {
288 }
catch(
const std::out_of_range&) {
304 template <
class To,
class From>
308 ,
std::enable_if_t<std::is_floating_point_v<To>>
309 , std::enable_if_t<std::is_same_v<From, const char*> || std::is_same_v<From, char*>>
314 DEBUG_THROW(
"specialized - To floating point - From (const) char*");
317 return lexical_cast_default<To>(std::string(value), *fallback);
333 , std::enable_if_t<std::is_floating_point_v<To>>
336 To
operator()(
const std::string& value, std::optional<To> fallback)
const 338 DEBUG_THROW(
"specialized - To floating point - From std::string");
341 if(value.find_first_of(
"Xx") != std::string::npos) {
350 long double res = std::stold(value);
351 if((static_cast<long double>(std::numeric_limits<To>::lowest()) <= res) && (static_cast<long double>(std::numeric_limits<To>::max()) >= res)) {
352 return static_cast<To
>(res);
354 }
catch(
const std::invalid_argument&) {
355 }
catch(
const std::out_of_range&) {
373 template <
class From>
378 ,
std::enable_if_t<std::is_same_v<From, const char*> || std::is_same_v<From, char*>>
381 unsigned long long operator()(From value, std::optional<unsigned long long> fallback)
const 384 "specialized - To unsigned long long - From (const) char*");
387 return lexical_cast_default<unsigned long long>(std::string(value), *fallback);
389 return lexical_cast<
unsigned long long>(std::string(value));
407 unsigned long long operator()(
const std::string& value, std::optional<unsigned long long> fallback)
const 409 DEBUG_THROW(
"specialized - To unsigned long long - From std::string");
412 return std::stoull(value);
413 }
catch(
const std::invalid_argument&) {
414 }
catch(
const std::out_of_range&) {
430 template <
class To,
class From>
434 ,
std::enable_if_t<std::is_unsigned_v<To> && !std::is_same_v<To, unsigned long long>>
435 , std::enable_if_t<std::is_same_v<From, const char*> || std::is_same_v<From, char*>>
440 DEBUG_THROW(
"specialized - To unsigned - From (const) char*");
443 return lexical_cast_default<To>(std::string(value), *fallback);
459 , std::enable_if_t<std::is_unsigned_v<To>>
462 To
operator()(
const std::string& value, std::optional<To> fallback)
const 464 DEBUG_THROW(
"specialized - To unsigned - From std::string");
467 unsigned long res = std::stoul(value);
469 if(std::numeric_limits<To>::max() >= res) {
470 return static_cast<To
>(res);
472 }
catch(
const std::invalid_argument&) {
473 }
catch(
const std::out_of_range&) {
unsigned long long operator()(const std::string &value, std::optional< unsigned long long > fallback) const
To operator()(From value, std::optional< To > fallback) const
To operator()(From value, std::optional< To > fallback) const
To lexical_cast_default(From value, To fallback=To())
Lexical cast converts one type to another with a fallback.
#define DEBUG_THROW(id)
Throws an exception for debugging.
long long operator()(From value, std::optional< long long > fallback) const
Base class for the conversion.
To lexical_cast(From value)
Lexical cast converts one type to another.
To operator()(From value, std::optional< To > fallback) const
long long operator()(const std::string &value, std::optional< long long > fallback) const
To operator()(const std::string &value, std::optional< To > fallback) const
To operator()(From value, std::optional< To > fallback) const
unsigned long long operator()(From value, std::optional< unsigned long long > fallback) const
const char * what() const noexcept
std::string operator()(From value, std::optional< std::string >) const
To operator()(const std::string &value, std::optional< To > fallback) const
To operator()(const std::string &value, std::optional< To > fallback) const
Thrown when a lexical_cast fails.
Contains the implementation details for lexical_cast and shouldn't be used directly.