osb/source/core/StarLexicalCast.hpp

63 lines
1.6 KiB
C++
Raw Normal View History

#pragma once
2023-06-20 14:33:09 +10:00
#include "StarFormat.hpp"
2023-06-20 14:33:09 +10:00
#include "StarString.hpp"
#include "StarStringView.hpp"
2023-06-20 14:33:09 +10:00
#include "StarMaybe.hpp"
#include "fast_float.h"
2023-06-20 14:33:09 +10:00
namespace Star {
STAR_EXCEPTION(BadLexicalCast, StarException);
void throwLexicalCastError(std::errc ec, const char* first, const char* last);
2023-06-20 14:33:09 +10:00
template <typename Type>
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
template <typename Type>
bool tryLexicalCast(Type& result, String const& s) {
return tryLexicalCast<Type>(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
}
2023-06-20 14:33:09 +10:00
template <typename Type>
bool tryLexicalCast(Type& result, StringView s) {
return tryLexicalCast<Type>(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
}
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 {};
}
template <typename Type>
Maybe<Type> maybeLexicalCast(StringView s) {
return maybeLexicalCast<Type>(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
}
2023-06-20 14:33:09 +10:00
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);
return result;
2023-06-20 14:33:09 +10:00
}
template <typename Type>
Type lexicalCast(StringView s) {
return lexicalCast<Type>(s.utf8Ptr(), s.utf8Ptr() + s.utf8Size());
2023-06-20 14:33:09 +10:00
}
}