2024-02-25 15:46:47 +01:00
|
|
|
#pragma once
|
2023-06-20 14:33:09 +10:00
|
|
|
|
2023-06-27 19:24:35 +10:00
|
|
|
#include "StarFormat.hpp"
|
2023-06-20 14:33:09 +10:00
|
|
|
#include "StarString.hpp"
|
2023-06-26 01:42:18 +10:00
|
|
|
#include "StarStringView.hpp"
|
2023-06-20 14:33:09 +10:00
|
|
|
#include "StarMaybe.hpp"
|
|
|
|
|
2024-09-16 23:02:22 +10:00
|
|
|
#include "fast_float.h"
|
2023-06-20 14:33:09 +10:00
|
|
|
|
|
|
|
namespace Star {
|
|
|
|
|
|
|
|
STAR_EXCEPTION(BadLexicalCast, StarException);
|
|
|
|
|
2024-09-16 23:02:22 +10:00
|
|
|
void throwLexicalCastError(std::errc ec, const char* first, const char* last);
|
|
|
|
|
2023-06-20 14:33:09 +10:00
|
|
|
template <typename Type>
|
2024-09-16 23:02:22 +10:00
|
|
|
bool tryLexicalCast(Type& result, const char* first, const char* last) {
|
|
|
|
auto res = fast_float::from_chars(first, last, result);
|
|
|
|
return res.ptr == last && (res.ec == std::errc() || res.ec == std::errc::result_out_of_range);
|
|
|
|
}
|
2023-06-20 14:33:09 +10:00
|
|
|
|
2024-09-22 16:24:20 +10:00
|
|
|
template <>
|
|
|
|
bool tryLexicalCast(bool& result, const char* first, const char* last);
|
|
|
|
|
2024-09-16 23:02:22 +10:00
|
|
|
template <typename Type>
|
|
|
|
bool tryLexicalCast(Type& result, String const& s) {
|
2024-12-31 15:27:32 +11:00
|
|
|
return tryLexicalCast<Type>(result, s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
|
2024-09-16 23:02:22 +10:00
|
|
|
}
|
2023-06-20 14:33:09 +10:00
|
|
|
|
2024-09-16 23:02:22 +10:00
|
|
|
template <typename Type>
|
|
|
|
bool tryLexicalCast(Type& result, StringView s) {
|
2024-12-31 15:27:32 +11:00
|
|
|
return tryLexicalCast<Type>(result, s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
|
2024-09-16 23:02:22 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Type>
|
|
|
|
Maybe<Type> maybeLexicalCast(const char* first, const char* last) {
|
|
|
|
Type result{};
|
|
|
|
if (tryLexicalCast(result, first, last))
|
|
|
|
return result;
|
|
|
|
else
|
2023-06-20 14:33:09 +10:00
|
|
|
return {};
|
2024-09-16 23:02:22 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Type>
|
|
|
|
Maybe<Type> maybeLexicalCast(StringView s) {
|
|
|
|
return maybeLexicalCast<Type>(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Type>
|
|
|
|
Type lexicalCast(const char* first, const char* last) {
|
|
|
|
Type result{};
|
|
|
|
auto res = fast_float::from_chars(first, last, result);
|
|
|
|
if ((res.ec != std::errc() && res.ec != std::errc::result_out_of_range) || res.ptr != last)
|
|
|
|
throwLexicalCastError(res.ec, first, last);
|
|
|
|
|
2024-02-19 18:39:01 +01:00
|
|
|
return result;
|
2023-06-20 14:33:09 +10:00
|
|
|
}
|
|
|
|
|
2024-09-22 16:24:20 +10:00
|
|
|
template <>
|
|
|
|
bool lexicalCast(const char* first, const char* last);
|
|
|
|
|
2023-06-20 14:33:09 +10:00
|
|
|
template <typename Type>
|
2024-09-16 23:02:22 +10:00
|
|
|
Type lexicalCast(StringView s) {
|
|
|
|
return lexicalCast<Type>(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
|
2023-06-20 14:33:09 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|