diff options
author | crupest <crupest@outlook.com> | 2024-06-24 00:06:25 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2024-08-18 16:50:20 +0800 |
commit | 1b30150ab79ff1338f209a8ddb54b3dc60cfb599 (patch) | |
tree | 97e183587b293ecf768476da0edf3fdcf86e4543 /include/cru/common/Format.h | |
parent | b756bf519cda0684ec46d0d9404cbc59741ec0cb (diff) | |
download | cru-1b30150ab79ff1338f209a8ddb54b3dc60cfb599.tar.gz cru-1b30150ab79ff1338f209a8ddb54b3dc60cfb599.tar.bz2 cru-1b30150ab79ff1338f209a8ddb54b3dc60cfb599.zip |
fix(SubProcess): fix pipe fs close, add tests.
NEED TEST: BufferStream, AutoReadStream, SubProcess.
Diffstat (limited to 'include/cru/common/Format.h')
-rw-r--r-- | include/cru/common/Format.h | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/include/cru/common/Format.h b/include/cru/common/Format.h index e6935343..d5c5ed99 100644 --- a/include/cru/common/Format.h +++ b/include/cru/common/Format.h @@ -3,8 +3,10 @@ #include "Exception.h" #include "String.h" -#include <double-conversion/double-conversion.h> -#include <charconv> +#include <cassert> +#include <cstdio> +#include <type_traits> +#include <vector> namespace cru { inline String ToString(bool value) { @@ -12,31 +14,40 @@ inline String ToString(bool value) { } template <typename T> -std::enable_if_t<std::is_integral_v<T>, String> ToString(T value) { - std::array<char, 50> buffer; - auto result = - std::to_chars(buffer.data(), buffer.data() + buffer.size(), value); - - if (result.ec == std::errc{}) { - } else { - throw std::invalid_argument("Failed to convert value to chars."); - } +inline constexpr std::nullptr_t kPrintfFormatSpecifierOfType = nullptr; + +#define CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(type, specifier) \ + template <> \ + inline constexpr const char* kPrintfFormatSpecifierOfType<type> = specifier; + +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(signed char, "%c") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(unsigned char, "%c") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(signed short, "%hd") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(unsigned short, "%hu") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(signed int, "%d") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(unsigned int, "%u") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(signed long, "%ld") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(unsigned long, "%lu") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(signed long long, "%lld") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(unsigned long long, "%llu") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(float, "%f") +CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE(double, "%f") + +#undef CRU_DEFINE_PRINTF_FORMAT_SPECIFIER_OF_TYPE - auto size = result.ptr - buffer.data(); - auto b = new char16_t[size + 1]; - b[size] = 0; - std::copy(buffer.data(), result.ptr, b); - return String::FromBuffer(b, size, size); +template <typename T> +std::enable_if_t< + !std::is_null_pointer_v<decltype(kPrintfFormatSpecifierOfType<T>)>, String> +ToString(T value) { + auto size = std::snprintf(nullptr, 0, kPrintfFormatSpecifierOfType<T>, value); + assert(size > 0); + std::vector<char> buffer(size + 1); + size = std::snprintf(buffer.data(), size + 1, kPrintfFormatSpecifierOfType<T>, + value); + assert(size > 0); + return String::FromUtf8(buffer.data(), size); } -extern double_conversion::DoubleToStringConverter - kDefaultDoubleToStringConverter; - -String CRU_BASE_API ToString(float value, StringView option); -String CRU_BASE_API ToString(double value, StringView option); -inline String ToString(float value) { return ToString(value, u""); } -inline String ToString(double value) { return ToString(value, u""); } - template <typename T> String ToString(const T& value, StringView option) { CRU_UNUSED(option) |