diff options
Diffstat (limited to 'include/fud_format.hpp')
-rw-r--r-- | include/fud_format.hpp | 171 |
1 files changed, 75 insertions, 96 deletions
diff --git a/include/fud_format.hpp b/include/fud_format.hpp index 4536d69..bd44d26 100644 --- a/include/fud_format.hpp +++ b/include/fud_format.hpp @@ -20,8 +20,8 @@ // #include "fud_assert.hpp" #include "dragonbox/dragonbox.h" -#include "fud_drain.hpp" #include "fud_array.hpp" +#include "fud_drain.hpp" #include "fud_option.hpp" #include "fud_result.hpp" #include "fud_status.hpp" @@ -31,9 +31,9 @@ #include "fud_utf8.hpp" #include <cstdint> +#include <cstdio> #include <limits> #include <variant> -#include <cstdio> namespace fud { @@ -44,7 +44,7 @@ constexpr size_t maxIntCharCount = (bitsPerOctal * sizeof(uint64_t)) + 4; struct FormatString { template <size_t N> // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) - consteval FormatString(const utf8 (&input)[N]) : m_size{N - 1}, m_data{input} + consteval FormatString(const utf8 (&input)[N]) : m_size{N - 1}, m_data{input} { static_assert(N > 0); } @@ -279,86 +279,82 @@ using FormatResult = DrainResult; /* TODO : require concept of a sink that takes pushBack() -> FudStatus */ /* TODO : sink concept also requires drain() -> FudStatus */ -template <typename Sink> requires Drainable<Sink, StringView> -FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt); +template <typename Sink> + requires Drainable<Sink, StringView> +FormatResult format(Sink& sink, FormatString fmt); -template <typename Sink, typename... Args> requires Drainable<Sink, StringView> -FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Args&&... args); +template <typename Sink, typename... Args> + requires Drainable<Sink, StringView> +FormatResult format(Sink& sink, FormatString fmt, Args&&... args); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, bool arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, bool arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, char arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, char arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, utf8 arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, utf8 arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, int32_t arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, int32_t arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, uint32_t arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, uint32_t arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, int64_t arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, int64_t arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, uint64_t arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, uint64_t arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, float arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, float arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, double arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, double arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, long double arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, long double arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, const utf8* arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, const utf8* arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, const char* arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, const char* arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, StringView arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, StringView arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, const void* arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, const void* arg); template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, impl::FormatHandle arg); +FormatResult format(Sink& sink, const FormatSpec& formatSpec, impl::FormatHandle arg); namespace impl { template <typename Sink, size_t Size> -FormatResult vFormat(Sink& sink, FormatCharMode formatMode, FormatString fmt, const FormatArguments<Size>& args); +FormatResult vFormat(Sink& sink, FormatString fmt, const FormatArguments<Size>& args); size_t findSpec(StringView scanView); } // namespace impl -template <typename Sink, typename... Args> requires Drainable<Sink, StringView> -FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Args&&... args) +template <typename Sink, typename... Args> + requires Drainable<Sink, StringView> +FormatResult format(Sink& sink, FormatString fmt, Args&&... args) { - if (formatMode != FormatCharMode::Unchecked) { - return {0, FudStatus::NotImplemented}; - } - constexpr size_t numArgs = sizeof...(args); auto formatArguments{FormatArguments<numArgs>::makeFormatArguments(std::forward<Args>(args)...)}; - return impl::vFormat(sink, formatMode, fmt, formatArguments); + return impl::vFormat(sink, fmt, formatArguments); } -template <typename Sink> requires Drainable<Sink, StringView> -FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt) +template <typename Sink> + requires Drainable<Sink, StringView> +FormatResult format(Sink& sink, FormatString fmt) { - if (formatMode != FormatCharMode::Unchecked) { - return {0, FudStatus::NotImplemented}; - } - auto scanView = fmt.view(); auto specIndex = impl::findSpec(scanView); if (specIndex < scanView.length()) { @@ -398,7 +394,7 @@ FudStatus vFormatPrepareNonPositionalSpec( const uint32_t& argIndex); template <typename Sink, size_t Size> -FormatResult vFormat(Sink& sink, FormatCharMode formatMode, FormatString fmt, const FormatArguments<Size>& args) +FormatResult vFormat(Sink& sink, FormatString fmt, const FormatArguments<Size>& args) { FormatResult result{0, FudStatus::Success}; auto scanView = fmt.view(); @@ -448,7 +444,7 @@ FormatResult vFormat(Sink& sink, FormatCharMode formatMode, FormatString fmt, co return result; } auto argResult{std::visit( - [&](const auto& arg) -> FormatResult { return format(sink, formatMode, formatSpec, arg); }, + [&](const auto& arg) -> FormatResult { return format(sink, formatSpec, arg); }, args[formatArgIndex])}; if (argResult.status != FudStatus::Success) { result.status = argResult.status; @@ -801,9 +797,8 @@ StringView getSign(FormatSign formatSign, T arg) template <typename Sink, typename T> requires std::is_integral_v<T> and std::is_scalar_v<T> -[[nodiscard]] FormatResult formatIntegral(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, T arg) +[[nodiscard]] FormatResult formatIntegral(Sink& sink, const FormatSpec& formatSpec, T arg) { - static_cast<void>(formatMode); FormatResult result{0, FudStatus::Success}; if (formatSpec.takesPrecision || formatSpec.precision != FormatSpec::precisionUnspecified) { result.status = FudStatus::FormatInvalid; @@ -862,7 +857,6 @@ FudStatus fillIntegralBuffer( } } if (formatType == FormatType::Character) { - // return format(sink, formatMode, formatSpec, static_cast<utf8>(arg)); if constexpr (std::is_signed_v<T>) { if (arg < 0) { return FudStatus::FormatInvalid; @@ -1024,7 +1018,7 @@ FormatResult rightPad(Sink& sink, FormatAlign::Value align, size_t width, utf8 f [[nodiscard]] Result<bool, FudStatus> validateFloatFormatType(FormatType formatType); template <typename Sink> -[[nodiscard]] FormatResult formatNAN(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, bool negative) +[[nodiscard]] FormatResult formatNAN(Sink& sink, const FormatSpec& formatSpec, bool negative) { auto uppercaseResult = validateFloatFormatType(formatSpec.formatType); if (uppercaseResult.isError()) { @@ -1050,11 +1044,11 @@ template <typename Sink> FormatSpec newSpec{}; newSpec.width = formatSpec.width; newSpec.fill = formatSpec.fill; - return format(sink, formatMode, newSpec, output); + return format(sink, newSpec, output); } template <typename Sink> -[[nodiscard]] FormatResult formatINF(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, bool negative) +[[nodiscard]] FormatResult formatINF(Sink& sink, const FormatSpec& formatSpec, bool negative) { auto uppercaseResult = validateFloatFormatType(formatSpec.formatType); if (uppercaseResult.isError()) { @@ -1080,18 +1074,13 @@ template <typename Sink> FormatSpec newSpec{}; newSpec.width = formatSpec.width; newSpec.fill = formatSpec.fill; - return format(sink, formatMode, newSpec, output); + return format(sink, newSpec, output); } template <typename Sink> -[[nodiscard]] FormatResult formatZero( - Sink& sink, - FormatCharMode formatMode, - const FormatSpec& formatSpec, - bool negative) +[[nodiscard]] FormatResult formatZero(Sink& sink, const FormatSpec& formatSpec, bool negative) { FormatResult result{0, FudStatus::NotImplemented}; - static_cast<void>(formatMode); static_cast<void>(sink); static_cast<void>(formatSpec); static_cast<void>(negative); @@ -1135,9 +1124,7 @@ void fillScientificBuffer(IntCharArray& buffer, Significand significand, uint8_t } } - forEach(Span<utf8>{buffer.data(), bufferLength}, [&](uint8_t digit) { - return static_cast<uint8_t>(digit + '0'); - }); + forEach(Span<utf8>{buffer.data(), bufferLength}, [&](uint8_t digit) { return static_cast<uint8_t>(digit + '0'); }); for (size_t idx = 0; idx < bufferLength / 2; ++idx) { auto rhsIndex = bufferLength - idx - 1; @@ -1256,15 +1243,15 @@ template <typename Sink, typename DecimalRepr> template <typename Sink, typename T> requires std::is_floating_point_v<T> and std::is_scalar_v<T> -[[nodiscard]] FormatResult formatFloat(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, T arg) +[[nodiscard]] FormatResult formatFloat(Sink& sink, const FormatSpec& formatSpec, T arg) { switch (std::fpclassify(arg)) { case FP_INFINITE: - return formatINF(sink, formatMode, formatSpec, std::signbit(arg)); + return formatINF(sink, formatSpec, std::signbit(arg)); case FP_NAN: - return formatNAN(sink, formatMode, formatSpec, std::signbit(arg)); + return formatNAN(sink, formatSpec, std::signbit(arg)); case FP_ZERO: - return formatZero(sink, formatMode, formatSpec, std::signbit(arg)); + return formatZero(sink, formatSpec, std::signbit(arg)); default: break; } @@ -1320,7 +1307,7 @@ template <typename Sink, typename T> } // namespace impl template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, bool arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, bool arg) { FormatSpec boolSpec = formatSpec; if (formatSpec.formatType == FormatType::Unspecified || formatSpec.formatType == FormatType::String) { @@ -1328,65 +1315,64 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for if (not arg) { view = StringView{"false"}; } - return format(sink, formatMode, boolSpec, view); + return format(sink, boolSpec, view); } boolSpec.formatType = FormatType::Unspecified; - return impl::formatIntegral(sink, formatMode, boolSpec, static_cast<uint8_t>(arg)); + return impl::formatIntegral(sink, boolSpec, static_cast<uint8_t>(arg)); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, utf8 arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, utf8 arg) { - return impl::formatIntegral(sink, formatMode, formatSpec, arg); + return impl::formatIntegral(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, char arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, char arg) { - return impl::formatIntegral(sink, formatMode, formatSpec, arg); + return impl::formatIntegral(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, int32_t arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, int32_t arg) { - return impl::formatIntegral(sink, formatMode, formatSpec, arg); + return impl::formatIntegral(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, uint32_t arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, uint32_t arg) { - return impl::formatIntegral(sink, formatMode, formatSpec, arg); + return impl::formatIntegral(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, int64_t arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, int64_t arg) { - return impl::formatIntegral(sink, formatMode, formatSpec, arg); + return impl::formatIntegral(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, uint64_t arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, uint64_t arg) { - return impl::formatIntegral(sink, formatMode, formatSpec, arg); + return impl::formatIntegral(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, float arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, float arg) { - return impl::formatFloat(sink, formatMode, formatSpec, arg); + return impl::formatFloat(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, double arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, double arg) { - return impl::formatFloat(sink, formatMode, formatSpec, arg); + return impl::formatFloat(sink, formatSpec, arg); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, long double arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, long double arg) { FormatResult result{0, FudStatus::NotImplemented}; - static_cast<void>(formatMode); static_cast<void>(sink); static_cast<void>(formatSpec); static_cast<void>(arg); @@ -1394,13 +1380,13 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, const utf8* arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, const utf8* arg) { - return format(sink, formatMode, formatSpec, std::bit_cast<const char*>(arg)); + return format(sink, formatSpec, std::bit_cast<const char*>(arg)); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, const char* arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, const char* arg) { if (arg == nullptr) { return {0, FudStatus::NullPointer}; @@ -1410,19 +1396,15 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for return {0, FudStatus::StringInvalid}; } auto stringLength = static_cast<size_t>(stringLengthResult); - return format(sink, formatMode, formatSpec, StringView{stringLength, arg}); + return format(sink, formatSpec, StringView{stringLength, arg}); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, StringView arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, StringView arg) { /* TODO: implement unicode points, check with formatMode */ FormatResult result{0, FudStatus::Success}; - if (formatMode != FormatCharMode::Unchecked) { - result.status = FudStatus::NotSupported; - return result; - } if (formatSpec.formatType != FormatType::Unspecified && formatSpec.formatType != FormatType::String && formatSpec.formatType != FormatType::Escaped) { @@ -1457,8 +1439,6 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for return result; } - // printf("From format(sink, mode, spec, stringview arg): Arg contents are %p %zu?\n\n", arg.c_str(), arg.length()); - // printf("From format(sink, mode, spec, stringview arg): What?\n%s\n", std::format("{}", std::string_view{arg.c_str(), arg.length()}).c_str()); auto drainViewResult = sink.drain(arg); result.bytesDrained += drainViewResult.bytesDrained; result.status = drainViewResult.status; @@ -1475,10 +1455,10 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, const void* arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, const void* arg) { auto pointerFormatSpec = formatSpec; - if (pointerFormatSpec.formatType == FormatType::Unspecified || + if (pointerFormatSpec.formatType == FormatType::Unspecified || pointerFormatSpec.formatType == FormatType::PointerLower) { pointerFormatSpec.formatType = FormatType::HexLower; } else if (pointerFormatSpec.formatType == FormatType::PointerUpper) { @@ -1492,19 +1472,18 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for return DrainResult{0, FudStatus::FormatInvalid}; } pointerFormatSpec.alternateForm = true; - return impl::formatIntegral(sink, formatMode, pointerFormatSpec, std::bit_cast<uintptr_t>(arg)); + return impl::formatIntegral(sink, pointerFormatSpec, std::bit_cast<uintptr_t>(arg)); } template <typename Sink> -FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& formatSpec, impl::FormatHandle arg) +FormatResult format(Sink& sink, const FormatSpec& formatSpec, impl::FormatHandle arg) { // FormatResult result{0, FudStatus::NotImplemented}; static_cast<void>(sink); - static_cast<void>(formatMode); static_cast<void>(formatSpec); static_cast<void>(arg); - return format(sink, formatMode, formatSpec, "not implemented"); + return format(sink, formatSpec, "not implemented"); } } // namespace fud |