Skip to content

Commit

Permalink
char formatters for utf string/views (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
arturbac authored Jul 5, 2024
1 parent 2cb57fa commit b945856
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 1 deletion.
24 changes: 24 additions & 0 deletions include/stralgo/utf/detail/foramtters.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <stralgo/utf/utf.h>
#include <format>
#include <ranges>

namespace stralgo::utf::detail
{
template<typename input_range, typename output_iterator>
inline auto tansform_to_conetxt(input_range const & str, output_iterator oit)
{
stralgo::utf::utf_input_view_t source{str};
stralgo::utf::utf_explicit_output_iterator_t<char>::iterator utf_oit{oit};
return std::ranges::copy(source, utf_oit).out.base();
}
} // namespace stralgo::utf::detail

namespace stralgo::concepts
{
template<typename char_type>
concept format_char_type
= std::same_as<char_type, wchar_t> or std::same_as<char_type, char16_t> or std::same_as<char_type, char32_t>;
}

24 changes: 24 additions & 0 deletions include/stralgo/utf/foramtters/small_vectors/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <stralgo/utf/utf.h>
#include <stralgo/utf/detail/foramtters.h>
#include <small_vectors/basic_string.h>
#include <format>
#include <ranges>

template<stralgo::concepts::format_char_type char_type, uint64_t capacity, typename tag>
struct std::formatter<small_vectors::basic_string_t<char_type, capacity, tag>, char>
{
template<typename ParseContext>
constexpr auto parse(ParseContext & ctx) -> decltype(ctx.begin())
{
return ctx.begin();
}

template<typename FormatContext>
auto format(small_vectors::basic_string_t<char_type, capacity, tag> const & str, FormatContext & ctx) const
-> decltype(ctx.out())
{
return stralgo::utf::detail::tansform_to_conetxt(str, ctx.out());
}
};
23 changes: 23 additions & 0 deletions include/stralgo/utf/foramtters/std/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <stralgo/utf/utf.h>
#include <stralgo/utf/detail/foramtters.h>
#include <format>
#include <ranges>

template<stralgo::concepts::format_char_type char_type>
struct std::formatter<std::basic_string<char_type>, char>
{
template<typename ParseContext>
constexpr auto parse(ParseContext & ctx) -> decltype(ctx.begin())
{
return ctx.begin();
}

template<typename FormatContext>
auto format(std::basic_string<char_type> const & str, FormatContext & ctx) const -> decltype(ctx.out())
{
return stralgo::utf::detail::tansform_to_conetxt(str, ctx.out());
}
};

23 changes: 23 additions & 0 deletions include/stralgo/utf/foramtters/std/string_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <stralgo/utf/utf.h>
#include <stralgo/utf/detail/foramtters.h>
#include <format>
#include <ranges>

template<stralgo::concepts::format_char_type char_type>
struct std::formatter<std::basic_string_view<char_type>, char>
{
template<typename ParseContext>
constexpr auto parse(ParseContext & ctx) -> decltype(ctx.begin())
{
return ctx.begin();
}

template<typename FormatContext>
auto format(std::basic_string_view<char_type> str, FormatContext & ctx) const -> decltype(ctx.out())
{
return stralgo::utf::detail::tansform_to_conetxt(str, ctx.out());
}
};

5 changes: 5 additions & 0 deletions include/stralgo/utf/utf.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ struct utf_output_iterator_t

inline constexpr explicit utf_output_iterator_t(target_iterator src) noexcept : iter_{src} {}

inline constexpr auto base() const noexcept -> target_iterator { return iter_; }

inline constexpr utf_output_iterator_t & operator=(std::same_as<char32_t> auto cp) noexcept
{
iter_ = detail::append(cp, iter_);
Expand Down Expand Up @@ -199,6 +201,8 @@ struct utf_explicit_output_iterator_t

inline constexpr explicit iterator(target_iterator src) noexcept : iter_{src} {}

inline constexpr auto base() const noexcept -> target_iterator { return iter_; }

inline constexpr iterator & operator=(std::same_as<char32_t> auto cp) noexcept
{
iter_ = detail::explicit_append<char_type>(cp, iter_);
Expand All @@ -215,6 +219,7 @@ struct utf_explicit_output_iterator_t
return *this;
}
};

template<std::output_iterator<char_type> TargetIter>
iterator(TargetIter src) -> iterator<TargetIter>;
};
Expand Down
31 changes: 30 additions & 1 deletion unittests/utf_.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <unit_test_core.h>
#include <stralgo/utf/utf.h>
#include <stralgo/utf/foramtters/std/string.h>
#include <stralgo/utf/foramtters/std/string_view.h>
#include <stralgo/utf/foramtters/small_vectors/string.h>
#include <codecvt>
#include <cstdint>

Expand Down Expand Up @@ -512,5 +515,31 @@ int main()
result |= run_constexpr_test(fn_tmpl);
result |= run_consteval_test(fn_tmpl);
};
}

"formatters"_test = [&]
{
using namespace std::string_view_literals;
using namespace std::string_literals;
using boost::ut::expect;
using boost::ut::eq;
{
auto res{std::format(
"{}-{}-{}-גראַדזשאַווייטיד", U"𐂀𐂁𐂂𐂃𐂄𐂅𐂆𐂇𐂈𐂉𐂊𐂋𐂌𐂍𐂎𐂏𐂐𐂑𐂒𐂓𐂔𐂕𐂖𐂗"sv, u"бакалавра"sv, L"𐀀𐀁𐀂𐀃𐀄𐀅𐀆"sv, L"גראַדזשאַווייטיד"s
)};
expect(eq(res, "𐂀𐂁𐂂𐂃𐂄𐂅𐂆𐂇𐂈𐂉𐂊𐂋𐂌𐂍𐂎𐂏𐂐𐂑𐂒𐂓𐂔𐂕𐂖𐂗-бакалавра-𐀀𐀁𐀂𐀃𐀄𐀅𐀆-גראַדזשאַווייטיד"sv));
}
{
using namespace small_vectors;
auto res{std::format(
"{}-{}-{} {}-{}-{}",
small_vectors::u16string{u"бакалавра"sv},
small_vectors::u32string{U"томатами"sv},
small_vectors::wstring{L"бакалавра"sv},
small_vectors::static_u16string<16>{u"томатами"sv},
small_vectors::static_u32string<16>{U"бакалавра"sv},
small_vectors::static_wstring<16>{L"томатами"sv}
)};
expect(eq(res, "бакалавра-томатами-бакалавра томатами-бакалавра-томатами"sv));
}
};
}

0 comments on commit b945856

Please sign in to comment.