util/AllocatedString: rename to BasicAllocatedString

To make things simpler, AllocatedString is now a non-template class.
This commit is contained in:
Max Kellermann 2021-01-14 12:39:45 +01:00 committed by Max Kellermann
parent 8d80280ab9
commit cfb7f8ab84
20 changed files with 73 additions and 64 deletions

View File

@ -456,7 +456,7 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
} while (cmd != DecoderCommand::STOP); } while (cmd != DecoderCommand::STOP);
} }
static AllocatedString<char> static AllocatedString
Windows1252ToUTF8(const char *s) noexcept Windows1252ToUTF8(const char *s) noexcept
{ {
#ifdef HAVE_ICU_CONVERTER #ifdef HAVE_ICU_CONVERTER
@ -469,9 +469,9 @@ Windows1252ToUTF8(const char *s) noexcept
* Fallback to not transcoding windows-1252 to utf-8, that may result * Fallback to not transcoding windows-1252 to utf-8, that may result
* in invalid utf-8 unless nonprintable characters are replaced. * in invalid utf-8 unless nonprintable characters are replaced.
*/ */
auto t = AllocatedString<char>::Duplicate(s); auto t = AllocatedString::Duplicate(s);
for (size_t i = 0; t[i] != AllocatedString<char>::SENTINEL; i++) for (size_t i = 0; t[i] != AllocatedString::SENTINEL; i++)
if (!IsPrintableASCII(t[i])) if (!IsPrintableASCII(t[i]))
t[i] = '?'; t[i] = '?';
@ -479,7 +479,7 @@ Windows1252ToUTF8(const char *s) noexcept
} }
gcc_pure gcc_pure
static AllocatedString<char> static AllocatedString
GetInfoString(const SidTuneInfo &info, unsigned i) noexcept GetInfoString(const SidTuneInfo &info, unsigned i) noexcept
{ {
#ifdef HAVE_SIDPLAYFP #ifdef HAVE_SIDPLAYFP
@ -496,7 +496,7 @@ GetInfoString(const SidTuneInfo &info, unsigned i) noexcept
} }
gcc_pure gcc_pure
static AllocatedString<char> static AllocatedString
GetDateString(const SidTuneInfo &info) noexcept GetDateString(const SidTuneInfo &info) noexcept
{ {
/* /*
@ -507,12 +507,12 @@ GetDateString(const SidTuneInfo &info) noexcept
* author or group> may be for example Rob Hubbard. A full field * author or group> may be for example Rob Hubbard. A full field
* may be for example "1987 Rob Hubbard". * may be for example "1987 Rob Hubbard".
*/ */
AllocatedString<char> release = GetInfoString(info, 2); AllocatedString release = GetInfoString(info, 2);
/* Keep the <year> part only for the date. */ /* Keep the <year> part only for the date. */
for (size_t i = 0; release[i] != AllocatedString<char>::SENTINEL; i++) for (size_t i = 0; release[i] != AllocatedString::SENTINEL; i++)
if (std::isspace(release[i])) { if (std::isspace(release[i])) {
release[i] = AllocatedString<char>::SENTINEL; release[i] = AllocatedString::SENTINEL;
break; break;
} }

View File

@ -36,7 +36,7 @@
*/ */
class NarrowPath { class NarrowPath {
#ifdef _UNICODE #ifdef _UNICODE
using Value = AllocatedString<>; using Value = AllocatedString;
#else #else
using Value = StringPointer<>; using Value = StringPointer<>;
#endif #endif

View File

@ -38,13 +38,13 @@
#include <string.h> #include <string.h>
AllocatedString<> AllocatedString
IcuCaseFold(std::string_view src) noexcept IcuCaseFold(std::string_view src) noexcept
try { try {
#ifdef HAVE_ICU #ifdef HAVE_ICU
const auto u = UCharFromUTF8(src); const auto u = UCharFromUTF8(src);
if (u.IsNull()) if (u.IsNull())
return AllocatedString<>::Duplicate(src); return AllocatedString::Duplicate(src);
AllocatedArray<UChar> folded(u.size() * 2U); AllocatedArray<UChar> folded(u.size() * 2U);
@ -54,7 +54,7 @@ try {
U_FOLD_CASE_DEFAULT, U_FOLD_CASE_DEFAULT,
&error_code); &error_code);
if (folded_length == 0 || error_code != U_ZERO_ERROR) if (folded_length == 0 || error_code != U_ZERO_ERROR)
return AllocatedString<>::Duplicate(src); return AllocatedString::Duplicate(src);
folded.SetSize(folded_length); folded.SetSize(folded_length);
return UCharToUTF8({folded.begin(), folded.size()}); return UCharToUTF8({folded.begin(), folded.size()});
@ -63,7 +63,7 @@ try {
#error not implemented #error not implemented
#endif #endif
} catch (...) { } catch (...) {
return AllocatedString<>::Duplicate(src); return AllocatedString::Duplicate(src);
} }
#endif /* HAVE_ICU_CASE_FOLD */ #endif /* HAVE_ICU_CASE_FOLD */

View File

@ -27,9 +27,9 @@
#include <string_view> #include <string_view>
template<typename T> class AllocatedString; class AllocatedString;
AllocatedString<char> AllocatedString
IcuCaseFold(std::string_view src) noexcept; IcuCaseFold(std::string_view src) noexcept;
#endif #endif

View File

@ -88,7 +88,7 @@ IcuCollate(std::string_view a, std::string_view b) noexcept
b.data(), b.size(), &code); b.data(), b.size(), &code);
#elif defined(_WIN32) #elif defined(_WIN32)
AllocatedString<wchar_t> wa = nullptr, wb = nullptr; BasicAllocatedString<wchar_t> wa = nullptr, wb = nullptr;
try { try {
wa = MultiByteToWideChar(CP_UTF8, a); wa = MultiByteToWideChar(CP_UTF8, a);

View File

@ -46,7 +46,7 @@ IcuCompare::IcuCompare(std::string_view _needle) noexcept
#else #else
IcuCompare::IcuCompare(std::string_view _needle) noexcept IcuCompare::IcuCompare(std::string_view _needle) noexcept
:needle(AllocatedString<>::Duplicate(_needle)) {} :needle(AllocatedString::Duplicate(_needle)) {}
#endif #endif

View File

@ -38,9 +38,9 @@ class IcuCompare {
#ifdef _WIN32 #ifdef _WIN32
/* Windows API functions work with wchar_t strings, so let's /* Windows API functions work with wchar_t strings, so let's
cache the MultiByteToWideChar() result for performance */ cache the MultiByteToWideChar() result for performance */
AllocatedString<wchar_t> needle; BasicAllocatedString<wchar_t> needle;
#else #else
AllocatedString<> needle; AllocatedString needle;
#endif #endif
public: public:

View File

@ -77,7 +77,7 @@ IcuConverter::Create(const char *charset)
#ifdef HAVE_ICU #ifdef HAVE_ICU
#elif defined(HAVE_ICONV) #elif defined(HAVE_ICONV)
static AllocatedString<char> static AllocatedString
DoConvert(iconv_t conv, std::string_view src) DoConvert(iconv_t conv, std::string_view src)
{ {
// TODO: dynamic buffer? // TODO: dynamic buffer?
@ -95,12 +95,12 @@ DoConvert(iconv_t conv, std::string_view src)
if (in_left > 0) if (in_left > 0)
throw std::runtime_error("Charset conversion failed"); throw std::runtime_error("Charset conversion failed");
return AllocatedString<>::Duplicate({buffer, sizeof(buffer) - out_left}); return AllocatedString::Duplicate({buffer, sizeof(buffer) - out_left});
} }
#endif #endif
AllocatedString<char> AllocatedString
IcuConverter::ToUTF8(std::string_view s) const IcuConverter::ToUTF8(std::string_view s) const
{ {
#ifdef HAVE_ICU #ifdef HAVE_ICU
@ -128,7 +128,7 @@ IcuConverter::ToUTF8(std::string_view s) const
#endif #endif
} }
AllocatedString<char> AllocatedString
IcuConverter::FromUTF8(std::string_view s) const IcuConverter::FromUTF8(std::string_view s) const
{ {
#ifdef HAVE_ICU #ifdef HAVE_ICU
@ -151,7 +151,7 @@ IcuConverter::FromUTF8(std::string_view s) const
throw std::runtime_error(FormatString("Failed to convert from Unicode: %s", throw std::runtime_error(FormatString("Failed to convert from Unicode: %s",
u_errorName(code)).c_str()); u_errorName(code)).c_str());
return AllocatedString<>::Duplicate({buffer, size_t(target - buffer)}); return AllocatedString::Duplicate({buffer, size_t(target - buffer)});
#elif defined(HAVE_ICONV) #elif defined(HAVE_ICONV)
return DoConvert(from_utf8, s); return DoConvert(from_utf8, s);

View File

@ -40,7 +40,7 @@
struct UConverter; struct UConverter;
#endif #endif
template<typename T> class AllocatedString; class AllocatedString;
/** /**
* This class can convert strings with a certain character set to and * This class can convert strings with a certain character set to and
@ -85,7 +85,7 @@ public:
* Throws std::runtime_error on error. * Throws std::runtime_error on error.
*/ */
gcc_nonnull_all gcc_nonnull_all
AllocatedString<char> ToUTF8(std::string_view s) const; AllocatedString ToUTF8(std::string_view s) const;
/** /**
* Convert the string from UTF-8. * Convert the string from UTF-8.
@ -93,7 +93,7 @@ public:
* Throws std::runtime_error on error. * Throws std::runtime_error on error.
*/ */
gcc_nonnull_all gcc_nonnull_all
AllocatedString<char> FromUTF8(std::string_view s) const; AllocatedString FromUTF8(std::string_view s) const;
}; };
#endif #endif

View File

@ -48,7 +48,7 @@ UCharFromUTF8(std::string_view src)
return dest; return dest;
} }
AllocatedString<> AllocatedString
UCharToUTF8(std::basic_string_view<UChar> src) UCharToUTF8(std::basic_string_view<UChar> src)
{ {
/* worst-case estimate */ /* worst-case estimate */
@ -65,5 +65,5 @@ UCharToUTF8(std::basic_string_view<UChar> src)
throw std::runtime_error(u_errorName(error_code)); throw std::runtime_error(u_errorName(error_code));
dest[dest_length] = 0; dest[dest_length] = 0;
return AllocatedString<>::Donate(dest.release()); return AllocatedString::Donate(dest.release());
} }

View File

@ -25,7 +25,7 @@
#include <string_view> #include <string_view>
template<typename T> class AllocatedArray; template<typename T> class AllocatedArray;
template<typename T> class AllocatedString; class AllocatedString;
/** /**
* Wrapper for u_strFromUTF8(). * Wrapper for u_strFromUTF8().
@ -40,7 +40,7 @@ UCharFromUTF8(std::string_view src);
* *
* Throws std::runtime_error on error. * Throws std::runtime_error on error.
*/ */
AllocatedString<char> AllocatedString
UCharToUTF8(std::basic_string_view<UChar> src); UCharToUTF8(std::basic_string_view<UChar> src);
#endif #endif

View File

@ -25,7 +25,7 @@
#include <windows.h> #include <windows.h>
AllocatedString<char> AllocatedString
WideCharToMultiByte(unsigned code_page, std::wstring_view src) WideCharToMultiByte(unsigned code_page, std::wstring_view src)
{ {
int length = WideCharToMultiByte(code_page, 0, src.data(), src.size(), int length = WideCharToMultiByte(code_page, 0, src.data(), src.size(),
@ -42,10 +42,10 @@ WideCharToMultiByte(unsigned code_page, std::wstring_view src)
throw MakeLastError("Failed to convert from Unicode"); throw MakeLastError("Failed to convert from Unicode");
buffer[length] = '\0'; buffer[length] = '\0';
return AllocatedString<char>::Donate(buffer.release()); return AllocatedString::Donate(buffer.release());
} }
AllocatedString<wchar_t> BasicAllocatedString<wchar_t>
MultiByteToWideChar(unsigned code_page, std::string_view src) MultiByteToWideChar(unsigned code_page, std::string_view src)
{ {
int length = MultiByteToWideChar(code_page, 0, src.data(), src.size(), int length = MultiByteToWideChar(code_page, 0, src.data(), src.size(),
@ -60,5 +60,5 @@ MultiByteToWideChar(unsigned code_page, std::string_view src)
throw MakeLastError("Failed to convert to Unicode"); throw MakeLastError("Failed to convert to Unicode");
buffer[length] = L'\0'; buffer[length] = L'\0';
return AllocatedString<wchar_t>::Donate(buffer.release()); return BasicAllocatedString<wchar_t>::Donate(buffer.release());
} }

View File

@ -24,20 +24,21 @@
#include <string_view> #include <string_view>
template<typename T> class AllocatedString; class AllocatedString;
template<typename T> class BasicAllocatedString;
/** /**
* Throws std::system_error on error. * Throws std::system_error on error.
*/ */
gcc_pure gcc_nonnull_all gcc_pure gcc_nonnull_all
AllocatedString<char> AllocatedString
WideCharToMultiByte(unsigned code_page, std::wstring_view src); WideCharToMultiByte(unsigned code_page, std::wstring_view src);
/** /**
* Throws std::system_error on error. * Throws std::system_error on error.
*/ */
gcc_pure gcc_nonnull_all gcc_pure gcc_nonnull_all
AllocatedString<wchar_t> BasicAllocatedString<wchar_t>
MultiByteToWideChar(unsigned code_page, std::string_view src); MultiByteToWideChar(unsigned code_page, std::string_view src);
#endif #endif

View File

@ -194,7 +194,7 @@ private:
bool is_exclusive; bool is_exclusive;
bool enumerate_devices; bool enumerate_devices;
std::string device_config; std::string device_config;
std::vector<std::pair<unsigned int, AllocatedString<char>>> device_desc; std::vector<std::pair<unsigned int, AllocatedString>> device_desc;
std::shared_ptr<WinEvent> event; std::shared_ptr<WinEvent> event;
std::optional<COM> com; std::optional<COM> com;
ComPtr<IMMDeviceEnumerator> enumerator; ComPtr<IMMDeviceEnumerator> enumerator;

View File

@ -136,7 +136,7 @@ bool
HttpdClient::SendResponse() noexcept HttpdClient::SendResponse() noexcept
{ {
char buffer[1024]; char buffer[1024];
AllocatedString<> allocated = nullptr; AllocatedString allocated = nullptr;
const char *response; const char *response;
assert(state == State::RESPONSE); assert(state == State::RESPONSE);

View File

@ -27,7 +27,7 @@
#include <string.h> #include <string.h>
AllocatedString<> AllocatedString
icy_server_metadata_header(const char *name, icy_server_metadata_header(const char *name,
const char *genre, const char *url, const char *genre, const char *url,
const char *content_type, int metaint) noexcept const char *content_type, int metaint) noexcept
@ -54,7 +54,7 @@ icy_server_metadata_header(const char *name,
content_type); content_type);
} }
static AllocatedString<> static AllocatedString
icy_server_metadata_string(const char *stream_title, icy_server_metadata_string(const char *stream_title,
const char* stream_url) noexcept const char* stream_url) noexcept
{ {

View File

@ -24,9 +24,9 @@
#include "tag/Type.h" #include "tag/Type.h"
struct Tag; struct Tag;
template<typename T> class AllocatedString; class AllocatedString;
AllocatedString<char> AllocatedString
icy_server_metadata_header(const char *name, icy_server_metadata_header(const char *name,
const char *genre, const char *url, const char *genre, const char *url,
const char *content_type, int metaint) noexcept; const char *content_type, int metaint) noexcept;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2015-2020 Max Kellermann <max.kellermann@gmail.com> * Copyright 2015-2021 Max Kellermann <max.kellermann@gmail.com>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -41,8 +41,8 @@
* *
* Unlike std::string, this object can hold a "nullptr" special value. * Unlike std::string, this object can hold a "nullptr" special value.
*/ */
template<typename T=char> template<typename T>
class AllocatedString { class BasicAllocatedString {
public: public:
using value_type = typename StringPointer<T>::value_type; using value_type = typename StringPointer<T>::value_type;
using reference = typename StringPointer<T>::reference; using reference = typename StringPointer<T>::reference;
@ -57,41 +57,41 @@ public:
private: private:
pointer value; pointer value;
explicit AllocatedString(pointer _value) noexcept explicit BasicAllocatedString(pointer _value) noexcept
:value(_value) {} :value(_value) {}
public: public:
AllocatedString(std::nullptr_t n) noexcept BasicAllocatedString(std::nullptr_t n) noexcept
:value(n) {} :value(n) {}
AllocatedString(AllocatedString &&src) noexcept BasicAllocatedString(BasicAllocatedString &&src) noexcept
:value(src.Steal()) {} :value(src.Steal()) {}
~AllocatedString() noexcept { ~BasicAllocatedString() noexcept {
delete[] value; delete[] value;
} }
static AllocatedString Donate(pointer value) noexcept { static BasicAllocatedString Donate(pointer value) noexcept {
return AllocatedString(value); return BasicAllocatedString(value);
} }
static AllocatedString Null() noexcept { static BasicAllocatedString Null() noexcept {
return nullptr; return nullptr;
} }
static AllocatedString Empty() { static BasicAllocatedString Empty() {
auto p = new value_type[1]; auto p = new value_type[1];
p[0] = SENTINEL; p[0] = SENTINEL;
return Donate(p); return Donate(p);
} }
static AllocatedString Duplicate(string_view src) { static BasicAllocatedString Duplicate(string_view src) {
auto p = new value_type[src.size() + 1]; auto p = new value_type[src.size() + 1];
*std::copy_n(src.data(), src.size(), p) = SENTINEL; *std::copy_n(src.data(), src.size(), p) = SENTINEL;
return Donate(p); return Donate(p);
} }
AllocatedString &operator=(AllocatedString &&src) noexcept { BasicAllocatedString &operator=(BasicAllocatedString &&src) noexcept {
std::swap(value, src.value); std::swap(value, src.value);
return *this; return *this;
} }
@ -136,9 +136,17 @@ public:
return std::exchange(value, nullptr); return std::exchange(value, nullptr);
} }
AllocatedString Clone() const { BasicAllocatedString Clone() const {
return Duplicate(*this); return Duplicate(*this);
} }
}; };
class AllocatedString : public BasicAllocatedString<char> {
public:
using BasicAllocatedString::BasicAllocatedString;
AllocatedString(BasicAllocatedString<value_type> &&src) noexcept
:BasicAllocatedString(std::move(src)) {}
};
#endif #endif

View File

@ -23,7 +23,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
AllocatedString<> AllocatedString
FormatStringV(const char *fmt, std::va_list args) noexcept FormatStringV(const char *fmt, std::va_list args) noexcept
{ {
std::va_list tmp; std::va_list tmp;
@ -37,10 +37,10 @@ FormatStringV(const char *fmt, std::va_list args) noexcept
char *buffer = new char[length + 1]; char *buffer = new char[length + 1];
vsnprintf(buffer, length + 1, fmt, args); vsnprintf(buffer, length + 1, fmt, args);
return AllocatedString<>::Donate(buffer); return AllocatedString::Donate(buffer);
} }
AllocatedString<> AllocatedString
FormatString(const char *fmt, ...) noexcept FormatString(const char *fmt, ...) noexcept
{ {
std::va_list args; std::va_list args;

View File

@ -24,20 +24,20 @@
#include <cstdarg> #include <cstdarg>
template<typename T> class AllocatedString; class AllocatedString;
/** /**
* Format into an #AllocatedString. * Format into an #AllocatedString.
*/ */
gcc_nonnull_all gcc_nonnull_all
AllocatedString<char> AllocatedString
FormatStringV(const char *fmt, std::va_list args) noexcept; FormatStringV(const char *fmt, std::va_list args) noexcept;
/** /**
* Format into an #AllocatedString. * Format into an #AllocatedString.
*/ */
gcc_nonnull(1) gcc_printf(1,2) gcc_nonnull(1) gcc_printf(1,2)
AllocatedString<char> AllocatedString
FormatString(const char *fmt, ...) noexcept; FormatString(const char *fmt, ...) noexcept;
#endif #endif