summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <egor@tensin.name>2026-06-04 21:38:49 +0200
committerEgor Tensin <egor@tensin.name>2026-06-04 21:38:49 +0200
commit514216d54a7ec218d089964dca48fed25b795ea8 (patch)
tree67fa7dc9fbdf97ad837a7e30801f6c1a41d4e8f2
parentupgrade to std::format (diff)
downloadwinapi-utf8-514216d54a7ec218d089964dca48fed25b795ea8.tar.gz
winapi-utf8-514216d54a7ec218d089964dca48fed25b795ea8.zip
upgrade to concepts and string views
-rw-r--r--include/winapi/utf8.hpp24
-rw-r--r--src/convert.cpp18
2 files changed, 24 insertions, 18 deletions
diff --git a/include/winapi/utf8.hpp b/include/winapi/utf8.hpp
index 2e87f75..0307507 100644
--- a/include/winapi/utf8.hpp
+++ b/include/winapi/utf8.hpp
@@ -10,9 +10,11 @@
#pragma once
+#include <concepts>
#include <cstddef>
#include <memory>
#include <string>
+#include <string_view>
#include <vector>
namespace winapi {
@@ -21,10 +23,8 @@ namespace winapi {
static_assert(sizeof(wchar_t) == 2, "This is Windows, right?");
/** Convert UTF-8 string to UTF-16. */
-std::wstring widen(const std::string&);
-#ifdef __cpp_lib_char8_t
-std::wstring widen(const std::u8string&);
-#endif
+std::wstring widen(std::string_view);
+std::wstring widen(std::u8string_view);
/**
* Convert UTF-8 string to UTF-16.
@@ -33,20 +33,24 @@ std::wstring widen(const std::u8string&);
*/
std::wstring widen(const void* src, std::size_t nb);
+template <typename T>
+concept CanBeWidened =
+ std::same_as<T, char> || std::same_as<T, char8_t> || std::same_as<T, unsigned char>;
+
/**
* Convert UTF-8 string to UTF-16.
* \param src Buffer holding a UTF-8 string.
*/
-template <typename T, typename Alloc = std::allocator<T>>
+template <CanBeWidened T, typename Alloc = std::allocator<T>>
std::wstring widen(const std::vector<T, Alloc>& src) {
return widen(src.data(), src.size() * sizeof(T));
}
/** Convert UTF-16 string to UTF-8. */
-std::string narrow(const std::wstring&);
+std::string narrow(std::wstring_view);
/** Convert UTF-16 string to UTF-8. */
-std::string narrow(const std::u16string&);
+std::string narrow(std::u16string_view);
/**
* Convert UTF-16 string to UTF-8.
@@ -55,11 +59,15 @@ std::string narrow(const std::u16string&);
*/
std::string narrow(const void* src, std::size_t nb);
+template <typename T>
+concept CanBeNarrowed =
+ std::same_as<T, wchar_t> || std::same_as<T, char16_t> || std::same_as<T, unsigned char>;
+
/**
* Convert UTF-16 string to UTF-8.
* \param src Buffer holding a UTF-16 string.
*/
-template <typename T, typename Alloc = std::allocator<T>>
+template <CanBeNarrowed T, typename Alloc = std::allocator<T>>
std::string narrow(const std::vector<T, Alloc>& src) {
return narrow(src.data(), src.size() * sizeof(T));
}
diff --git a/src/convert.cpp b/src/convert.cpp
index 0f96767..675d244 100644
--- a/src/convert.cpp
+++ b/src/convert.cpp
@@ -80,15 +80,13 @@ void verify_output(const std::vector<CharT>& expected, int32_t _actual_size) {
} // namespace
-std::wstring widen(const std::string& src) {
- return widen(src.c_str(), src.size());
+std::wstring widen(std::string_view src) {
+ return widen(src.data(), src.length());
}
-#ifdef __cpp_lib_char8_t
-std::wstring widen(const std::u8string& src) {
- return widen(src.c_str(), src.size());
+std::wstring widen(std::u8string_view src) {
+ return widen(src.data(), src.length());
}
-#endif
std::wstring widen(const void* src, std::size_t in_nb) {
const DWORD flags = MB_ERR_INVALID_CHARS;
@@ -115,13 +113,13 @@ std::wstring widen(const void* src, std::size_t in_nb) {
return {out.data(), out.size()};
}
-std::string narrow(const std::wstring& src) {
+std::string narrow(std::wstring_view src) {
static_assert(sizeof(wchar_t) == sizeof(WCHAR), "wchar_t != WCHAR");
- return narrow(src.c_str(), src.size() * sizeof(std::wstring::value_type));
+ return narrow(src.data(), src.length() * sizeof(std::wstring_view::value_type));
}
-std::string narrow(const std::u16string& src) {
- return narrow(src.c_str(), src.size() * sizeof(std::u16string::value_type));
+std::string narrow(std::u16string_view src) {
+ return narrow(src.data(), src.length() * sizeof(std::u16string_view::value_type));
}
std::string narrow(const void* src, std::size_t in_nb) {