15 #if __has_include(<charconv>)
20 #include <type_traits>
85 explicit Any(
const std::string& str)
89 explicit Any(
const char* str)
102 template <
typename T>
111 template <
typename T>
120 [[nodiscard]]
bool isNumber()
const;
130 template <
typename T>
141 template <
typename T>
142 nonstd::expected<T, std::string>
tryCast()
const;
145 template <
typename T>
148 if(
auto res = tryCast<T>())
154 throw std::runtime_error(res.error());
161 template <
typename T>
164 static_assert(!std::is_same_v<T, float>,
"The value has been casted internally to "
167 static_assert(!SafeAny::details::is_integer<T>() || std::is_same_v<T, uint64_t>,
"The"
196 [[nodiscard]]
const std::type_index&
type() const noexcept
202 [[nodiscard]]
const std::type_info&
castedType() const noexcept
207 [[nodiscard]]
bool empty() const noexcept
218 template <
typename DST>
221 template <
typename DST>
224 template <
typename DST>
227 template <
typename DST>
230 return nonstd::make_unexpected(errorMsg<DST>());
233 template <
typename T>
237 "] and [",
demangle(
typeid(T)),
"]");
245 template <
typename SRC,
typename TO>
248 return (val ==
static_cast<SRC
>(
static_cast<TO
>(val)));
251 template <
typename T>
254 if(type ==
typeid(T))
259 if(std::type_index(
typeid(uint8_t)) == type)
261 return ValidCast<T, uint8_t>(val);
263 if(std::type_index(
typeid(uint16_t)) == type)
265 return ValidCast<T, uint16_t>(val);
267 if(std::type_index(
typeid(uint32_t)) == type)
269 return ValidCast<T, uint32_t>(val);
271 if(std::type_index(
typeid(uint64_t)) == type)
273 return ValidCast<T, uint64_t>(val);
276 if(std::type_index(
typeid(int8_t)) == type)
278 return ValidCast<T, int8_t>(val);
280 if(std::type_index(
typeid(int16_t)) == type)
282 return ValidCast<T, int16_t>(val);
284 if(std::type_index(
typeid(int32_t)) == type)
286 return ValidCast<T, int32_t>(val);
288 if(std::type_index(
typeid(int64_t)) == type)
290 return ValidCast<T, int64_t>(val);
293 if(std::type_index(
typeid(
float)) == type)
295 return ValidCast<T, float>(val);
297 if(std::type_index(
typeid(
double)) == type)
299 return ValidCast<T, double>(val);
338 if(dst_type ==
typeid(int64_t))
340 dst.
_any = cast<int64_t>();
342 else if(dst_type ==
typeid(uint64_t))
344 dst.
_any = cast<uint64_t>();
346 else if(dst_type ==
typeid(
double))
348 dst.
_any = cast<double>();
352 throw std::runtime_error(
"Any::copyInto fails");
357 throw std::runtime_error(
"Any::copyInto fails");
361 template <
typename DST>
368 return linb::any_cast<SafeAny::SimpleString>(
_any).toStdString();
370 else if(
type ==
typeid(int64_t))
374 else if(
type ==
typeid(uint64_t))
378 else if(
type ==
typeid(
double))
383 return nonstd::make_unexpected(errorMsg<DST>());
386 template <
typename T>
389 static_assert(std::is_arithmetic_v<T> && !std::is_same_v<T, bool>,
"Expecting a "
392 const auto str = linb::any_cast<SafeAny::SimpleString>(
_any);
393 #if __cpp_lib_to_chars >= 201611L
395 auto [ptr, err] = std::from_chars(str.data(), str.data() + str.size(), out);
396 if(err == std::errc())
402 return nonstd::make_unexpected(
"Any failed string to number conversion");
407 if constexpr(std::is_same_v<T, uint16_t>)
409 return std::stoul(str.toStdString());
411 if constexpr(std::is_integral_v<T>)
413 const int64_t val = std::stol(str.toStdString());
417 if constexpr(std::is_floating_point_v<T>)
419 return std::stod(str.toStdString());
424 return nonstd::make_unexpected(
"Any failed string to number conversion");
427 return nonstd::make_unexpected(
"Any conversion from string failed");
430 template <
typename DST>
437 if(
type ==
typeid(int64_t))
439 auto out = linb::any_cast<int64_t>(
_any);
440 return static_cast<DST
>(out);
442 else if(
type ==
typeid(uint64_t))
444 auto out = linb::any_cast<uint64_t>(
_any);
445 return static_cast<DST
>(out);
448 return nonstd::make_unexpected(errorMsg<DST>());
451 template <
typename DST>
459 if(
type ==
typeid(int64_t))
461 convertNumber<int64_t, DST>(linb::any_cast<int64_t>(
_any), out);
463 else if(
type ==
typeid(uint64_t))
465 convertNumber<uint64_t, DST>(linb::any_cast<uint64_t>(
_any), out);
467 else if(
type ==
typeid(
double))
469 convertNumber<double, DST>(linb::any_cast<double>(
_any), out);
473 return nonstd::make_unexpected(errorMsg<DST>());
478 template <
typename T>
482 "can not cast to reference");
486 throw std::runtime_error(
"Any::cast failed because it is empty");
491 return linb::any_cast<T>(
_any);
496 if constexpr(std::is_enum_v<T>)
500 return static_cast<T
>(convert<int>().value());
504 if(
auto out = stringToNumber<int64_t>())
506 return static_cast<T
>(out.value());
509 return nonstd::make_unexpected(
"Any::cast failed to cast to enum type");
514 if constexpr(std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
516 if(
auto out = stringToNumber<T>())
527 if(
auto res = convert<T>())