Skip to content

Commit

Permalink
Pattern: reduce code duplication for writing strings
Browse files Browse the repository at this point in the history
Signed-off-by: Pavel Artsishevsky <polter.rnd@gmail.com>
  • Loading branch information
polter-rnd committed Dec 17, 2024
1 parent fb9b0d1 commit 7793dd7
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 23 deletions.
33 changes: 15 additions & 18 deletions include/slimlog/pattern-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ auto Pattern<Char>::format(auto& out, Record<Char, StringType>& record) -> void
Util::Types::Overloaded{
[&out, &value = item.value](std::reference_wrapper<StringType> arg) {
if constexpr (Detail::HasConvertString<Char, StringType>) {
format_string(out, value, ConvertString<Char, StringType>{}(arg.get()));
format_string(
out,
value,
RecordStringView{ConvertString<Char, StringType>{}(arg.get())});
} else {
(void)out;
(void)value;
Expand Down Expand Up @@ -255,22 +258,16 @@ void Pattern<Char>::compile(StringViewType pattern)

template<typename Char>
template<typename StringView>
requires(
std::same_as<std::remove_cvref_t<StringView>, RecordStringView<Char>>
|| std::same_as<std::remove_cvref_t<StringView>, RecordStringView<char>>)
void Pattern<Char>::format_string(auto& out, const auto& item, StringView&& data)
{
constexpr auto CountCodepoints = [](StringView& src) {
if constexpr (std::is_same_v<StringView, StringViewType>) {
return Util::Unicode::count_codepoints(src.data(), src.size());
} else {
return src.codepoints();
}
};
const auto codepoints = CountCodepoints(data);

if (auto& specs = std::get<typename Placeholder::StringSpecs>(item); specs.width > 0)
[[unlikely]] {
write_string_padded(out, std::forward<StringView>(data), specs, codepoints);
write_string_padded(out, std::forward<StringView>(data), specs);
} else {
write_string(out, std::forward<StringView>(data), codepoints);
write_string(out, std::forward<StringView>(data));
}
}

Expand Down Expand Up @@ -429,15 +426,14 @@ auto Pattern<Char>::get_string_specs(StringViewType value) -> Placeholder::Strin

template<typename Char>
template<typename StringView>
constexpr void Pattern<Char>::write_string(auto& dst, StringView&& src, std::size_t codepoints)
constexpr void Pattern<Char>::write_string(auto& dst, StringView&& src)
{
using DataChar = typename std::remove_cvref_t<StringView>::value_type;
if constexpr (std::is_same_v<DataChar, char> && !std::is_same_v<Char, char>) {
const auto codepoints = src.codepoints();
dst.reserve(dst.size() + codepoints + 1); // Take into account null terminator
const std::size_t written = Util::Unicode::from_multibyte(
dst.end(),
std::forward<StringView>(src), // NOLINT(cppcoreguidelines-slicing)
codepoints + 1);
dst.end(), std::forward<StringView>(src), codepoints + 1);
dst.resize(dst.size() + written - 1); // Trim null terminator
} else {
dst.append(std::forward<StringView>(src));
Expand All @@ -447,9 +443,10 @@ constexpr void Pattern<Char>::write_string(auto& dst, StringView&& src, std::siz
template<typename Char>
template<typename StringView>
constexpr void Pattern<Char>::write_string_padded(
auto& dst, StringView&& src, const Placeholder::StringSpecs& specs, std::size_t codepoints)
auto& dst, StringView&& src, const Placeholder::StringSpecs& specs)
{
const auto spec_width = Util::Types::to_unsigned(specs.width);
const auto codepoints = src.codepoints();
const auto padding = spec_width > codepoints ? spec_width - codepoints : 0;

// Shifts are encoded as string literals because constexpr is not
Expand Down Expand Up @@ -497,7 +494,7 @@ constexpr void Pattern<Char>::write_string_padded(
}

// Fill data
write_string(dst, std::forward<StringView>(src), codepoints);
write_string(dst, std::forward<StringView>(src));

// Fill right padding
if (right_padding != 0) {
Expand Down
13 changes: 8 additions & 5 deletions include/slimlog/pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@

#include <array>
#include <chrono>
#include <concepts>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
Expand Down Expand Up @@ -265,6 +267,9 @@ class Pattern {
* @param data Source string to be formatted.
*/
template<typename StringView>
requires(
std::same_as<std::remove_cvref_t<StringView>, RecordStringView<Char>>
|| std::same_as<std::remove_cvref_t<StringView>, RecordStringView<char>>)
static void format_string(auto& out, const auto& item, StringView&& data);

/**
Expand Down Expand Up @@ -339,10 +344,9 @@ class Pattern {
* @tparam StringView String view type, convertible to `std::basic_string_view`.
* @param dst Destination buffer where the string will be written.
* @param src Source string view to be written.
* @param codepoints Number of codepoints the source string contains.
*/
template<typename StringView>
constexpr static void write_string(auto& dst, StringView&& src, std::size_t codepoints);
constexpr static void write_string(auto& dst, StringView&& src);

/**
* @brief Writes the source string to the destination buffer with specific alignment.
Expand All @@ -354,11 +358,10 @@ class Pattern {
* @param dst Destination buffer where the string will be written.
* @param src Source string view to be written.
* @param specs String specifications, including alignment and fill character.
* @param codepoints Number of codepoints the source string contains.
*/
template<typename StringView>
constexpr static void write_string_padded(
auto& dst, StringView&& src, const Placeholder::StringSpecs& specs, std::size_t codepoints);
constexpr static void
write_string_padded(auto& dst, StringView&& src, const Placeholder::StringSpecs& specs);

std::basic_string<Char> m_pattern;
std::vector<Placeholder> m_placeholders;
Expand Down

0 comments on commit 7793dd7

Please sign in to comment.