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>
249 if constexpr(std::is_arithmetic_v<SRC> && std::is_arithmetic_v<TO>)
252 if constexpr(std::is_floating_point_v<TO>)
254 if constexpr(std::is_integral_v<SRC>)
257 TO as_float =
static_cast<TO
>(val);
258 SRC back_conv =
static_cast<SRC
>(as_float);
259 return back_conv == val;
263 else if constexpr(std::is_integral_v<TO>)
265 if(val >
static_cast<SRC
>(std::numeric_limits<TO>::max()) ||
266 val <
static_cast<SRC
>(std::numeric_limits<TO>::lowest()))
273 TO as_target =
static_cast<TO
>(val);
274 SRC back_to_source =
static_cast<SRC
>(as_target);
275 return val == back_to_source;
278 template <
typename T>
281 if(type ==
typeid(T))
286 if(std::type_index(
typeid(uint8_t)) == type)
288 return ValidCast<T, uint8_t>(val);
290 if(std::type_index(
typeid(uint16_t)) == type)
292 return ValidCast<T, uint16_t>(val);
294 if(std::type_index(
typeid(uint32_t)) == type)
296 return ValidCast<T, uint32_t>(val);
298 if(std::type_index(
typeid(uint64_t)) == type)
300 return ValidCast<T, uint64_t>(val);
303 if(std::type_index(
typeid(int8_t)) == type)
305 return ValidCast<T, int8_t>(val);
307 if(std::type_index(
typeid(int16_t)) == type)
309 return ValidCast<T, int16_t>(val);
311 if(std::type_index(
typeid(int32_t)) == type)
313 return ValidCast<T, int32_t>(val);
315 if(std::type_index(
typeid(int64_t)) == type)
317 return ValidCast<T, int64_t>(val);
320 if(std::type_index(
typeid(
float)) == type)
322 return ValidCast<T, float>(val);
324 if(std::type_index(
typeid(
double)) == type)
326 return ValidCast<T, double>(val);
365 if(dst_type ==
typeid(int64_t))
367 dst.
_any = cast<int64_t>();
369 else if(dst_type ==
typeid(uint64_t))
371 dst.
_any = cast<uint64_t>();
373 else if(dst_type ==
typeid(
double))
375 dst.
_any = cast<double>();
379 throw std::runtime_error(
"Any::copyInto fails");
384 throw std::runtime_error(
"Any::copyInto fails");
388 template <
typename DST>
395 return linb::any_cast<SafeAny::SimpleString>(
_any).toStdString();
397 else if(
type ==
typeid(int64_t))
401 else if(
type ==
typeid(uint64_t))
405 else if(
type ==
typeid(
double))
410 return nonstd::make_unexpected(errorMsg<DST>());
413 template <
typename T>
416 static_assert(std::is_arithmetic_v<T> && !std::is_same_v<T, bool>,
"Expecting a "
419 const auto str = linb::any_cast<SafeAny::SimpleString>(
_any);
420 #if __cpp_lib_to_chars >= 201611L
422 auto [ptr, err] = std::from_chars(str.data(), str.data() + str.size(), out);
423 if(err == std::errc())
429 return nonstd::make_unexpected(
"Any failed string to number conversion");
434 if constexpr(std::is_same_v<T, uint16_t>)
436 return std::stoul(str.toStdString());
438 if constexpr(std::is_integral_v<T>)
440 const int64_t val = std::stol(str.toStdString());
444 if constexpr(std::is_floating_point_v<T>)
446 return std::stod(str.toStdString());
451 return nonstd::make_unexpected(
"Any failed string to number conversion");
454 return nonstd::make_unexpected(
"Any conversion from string failed");
457 template <
typename DST>
464 if(
type ==
typeid(int64_t))
466 auto out = linb::any_cast<int64_t>(
_any);
467 return static_cast<DST
>(out);
469 else if(
type ==
typeid(uint64_t))
471 auto out = linb::any_cast<uint64_t>(
_any);
472 return static_cast<DST
>(out);
475 return nonstd::make_unexpected(errorMsg<DST>());
478 template <
typename DST>
486 if(
type ==
typeid(int64_t))
488 convertNumber<int64_t, DST>(linb::any_cast<int64_t>(
_any), out);
490 else if(
type ==
typeid(uint64_t))
492 convertNumber<uint64_t, DST>(linb::any_cast<uint64_t>(
_any), out);
494 else if(
type ==
typeid(
double))
496 convertNumber<double, DST>(linb::any_cast<double>(
_any), out);
500 return nonstd::make_unexpected(errorMsg<DST>());
505 template <
typename T>
509 "can not cast to reference");
513 throw std::runtime_error(
"Any::cast failed because it is empty");
518 return linb::any_cast<T>(
_any);
523 if constexpr(std::is_enum_v<T>)
527 return static_cast<T
>(convert<int>().value());
531 if(
auto out = stringToNumber<int64_t>())
533 return static_cast<T
>(out.value());
536 return nonstd::make_unexpected(
"Any::cast failed to cast to enum type");
541 if constexpr(std::is_arithmetic_v<T> && !std::is_same_v<T, bool>)
543 if(
auto out = stringToNumber<T>())
554 if(
auto res = convert<T>())