From 9758c3e42534238e24ee5dd715bf7427bdd303b7 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Thu, 4 Aug 2022 16:05:49 +0200 Subject: [PATCH] Util: Use C++20 concepts for integral and floating-point types --- src/util/format/builder.cpp | 13 -------- src/util/format/builder.h | 7 ++--- src/util/format/formatter.cpp | 50 ----------------------------- src/util/format/formatter.h | 59 ++++++++++++++++++++++------------- src/util/meta/concepts.h | 22 +++++++++++++ 5 files changed, 62 insertions(+), 89 deletions(-) create mode 100644 src/util/meta/concepts.h diff --git a/src/util/format/builder.cpp b/src/util/format/builder.cpp index 1bab4ca..85ddc62 100644 --- a/src/util/format/builder.cpp +++ b/src/util/format/builder.cpp @@ -28,19 +28,6 @@ void Builder::putLiteral(std::string_view literal) } } -void Builder::putF32(float number, uint8_t precision) const -{ - precision = std::min(precision, static_cast(std::numeric_limits::digits10)); - - std::stringstream stream; - stream - << std::fixed << std::setprecision(precision) - << number - << std::defaultfloat << std::setprecision(6); - std::string string = stream.str(); - m_builder << string; -} - void Builder::putF64(double number, uint8_t precision) const { precision = std::min(precision, static_cast(std::numeric_limits::digits10)); diff --git a/src/util/format/builder.h b/src/util/format/builder.h index fd80fbb..aaeded3 100644 --- a/src/util/format/builder.h +++ b/src/util/format/builder.h @@ -36,11 +36,8 @@ public: void putLiteral(std::string_view literal); - void putI32(int32_t number) const { m_builder << number; } // int - void putU32(uint32_t number) const { m_builder << number; } // unsigned int - void putI64(int64_t number) const { m_builder << number; } // long int - void putU64(size_t number) const { m_builder << number; } // long unsigned int - void putF32(float number, uint8_t precision = 6) const; + void putI64(int64_t number) const { m_builder << number; } // long int + void putU64(size_t number) const { m_builder << number; } // long unsigned int void putF64(double number, uint8_t precision = 6) const; void putCharacter(char character) const { m_builder.write(&character, 1); } void putString(std::string_view string, size_t width = 0, Align align = Align::Left, char fill = ' ') const; diff --git a/src/util/format/formatter.cpp b/src/util/format/formatter.cpp index 268e5b9..5652991 100644 --- a/src/util/format/formatter.cpp +++ b/src/util/format/formatter.cpp @@ -16,56 +16,6 @@ namespace Util::Format { -// Integral - -template<> -void Formatter::format(Builder& builder, int32_t value) const -{ - builder.putI32(value); -} - -template<> -void Formatter::format(Builder& builder, uint32_t value) const -{ - builder.putU32(value); -} - -template<> -void Formatter::format(Builder& builder, int64_t value) const -{ - builder.putI64(value); -} - -template<> -void Formatter::format(Builder& builder, size_t value) const -{ - builder.putU64(value); -} - -// Floating point - -template<> -void Formatter::format(Builder& builder, float value) const -{ - if (specifier.precision < 0) { - builder.putF32(value); - } - else { - builder.putF32(value, specifier.precision); - } -} - -template<> -void Formatter::format(Builder& builder, double value) const -{ - if (specifier.precision < 0) { - builder.putF64(value); - return; - } - - builder.putF64(value, specifier.precision); -} - // Char template<> diff --git a/src/util/format/formatter.h b/src/util/format/formatter.h index e7ca0f9..8c602c3 100644 --- a/src/util/format/formatter.h +++ b/src/util/format/formatter.h @@ -17,6 +17,7 @@ #include "util/format/builder.h" #include "util/format/parser.h" +#include "util/meta/concepts.h" namespace Util::Format { @@ -66,13 +67,7 @@ struct Formatter { constexpr void parse(Parser& parser) { - if (std::is_integral_v) { - parser.parseSpecifier(specifier, Parser::ParameterType::Integral); - } - else if (std::is_floating_point_v) { - parser.parseSpecifier(specifier, Parser::ParameterType::FloatingPoint); - } - else if (std::is_same_v) { + if (std::is_same_v) { parser.parseSpecifier(specifier, Parser::ParameterType::Char); } else if (std::is_same_v) { @@ -80,30 +75,52 @@ struct Formatter { } } - void format(Builder& builder, T value) const { (void)builder, (void)value; } + void format(Builder&, T) const {} }; // Integral -template<> -void Formatter::format(Builder& builder, int32_t value) const; - -template<> -void Formatter::format(Builder& builder, uint32_t value) const; +template +struct Formatter { + Specifier specifier; -template<> -void Formatter::format(Builder& builder, int64_t value) const; + void parse(Parser& parser) + { + parser.parseSpecifier(specifier, Parser::ParameterType::Integral); + } -template<> -void Formatter::format(Builder& builder, size_t value) const; // uint64_t + void format(Builder& builder, T value) const + { + if (std::is_signed_v) { + builder.putI64(value); + } + if (std::is_unsigned_v) { + builder.putU64(value); + } + } +}; // Floating point -template<> -void Formatter::format(Builder& builder, float value) const; +template +struct Formatter { + Specifier specifier; -template<> -void Formatter::format(Builder& builder, double value) const; + void parse(Parser& parser) + { + parser.parseSpecifier(specifier, Parser::ParameterType::FloatingPoint); + } + + void format(Builder& builder, T value) const + { + if (specifier.precision < 0) { + builder.putF64(value); + return; + } + + builder.putF64(value, specifier.precision); + } +}; // Char diff --git a/src/util/meta/concepts.h b/src/util/meta/concepts.h new file mode 100644 index 0000000..7c84869 --- /dev/null +++ b/src/util/meta/concepts.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2022 Riyyi + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include // is_integral_v, floating_point_v + +namespace Util::Concepts { + +template +concept Integral = std::is_integral_v; + +template +concept FloatingPoint = std::is_floating_point_v; + +} // namespace Util::Concepts + +using Util::Concepts::FloatingPoint; +using Util::Concepts::Integral;