Deprecate fmt::char8_t
This commit is contained in:
parent
6f01b6ebb6
commit
678341275b
@ -315,6 +315,12 @@ FMT_CONSTEXPR typename std::make_unsigned<Int>::type to_unsigned(Int value) {
|
|||||||
FMT_ASSERT(value >= 0, "negative value");
|
FMT_ASSERT(value >= 0, "negative value");
|
||||||
return static_cast<typename std::make_unsigned<Int>::type>(value);
|
return static_cast<typename std::make_unsigned<Int>::type>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __cpp_char8_t
|
||||||
|
using char8_type = char8_t;
|
||||||
|
#else
|
||||||
|
enum char8_type : unsigned char {};
|
||||||
|
#endif
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
@ -415,15 +421,15 @@ using string_view = basic_string_view<char>;
|
|||||||
using wstring_view = basic_string_view<wchar_t>;
|
using wstring_view = basic_string_view<wchar_t>;
|
||||||
|
|
||||||
#ifndef __cpp_char8_t
|
#ifndef __cpp_char8_t
|
||||||
// A UTF-8 code unit type.
|
// char8_t is deprecated; use char instead.
|
||||||
enum char8_t : unsigned char {};
|
using char8_t FMT_DEPRECATED_ALIAS = internal::char8_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Specifies if ``T`` is a character type. Can be specialized by users. */
|
/** Specifies if ``T`` is a character type. Can be specialized by users. */
|
||||||
template <typename T> struct is_char : std::false_type {};
|
template <typename T> struct is_char : std::false_type {};
|
||||||
template <> struct is_char<char> : std::true_type {};
|
template <> struct is_char<char> : std::true_type {};
|
||||||
template <> struct is_char<wchar_t> : std::true_type {};
|
template <> struct is_char<wchar_t> : std::true_type {};
|
||||||
template <> struct is_char<char8_t> : std::true_type {};
|
template <> struct is_char<internal::char8_type> : std::true_type {};
|
||||||
template <> struct is_char<char16_t> : std::true_type {};
|
template <> struct is_char<char16_t> : std::true_type {};
|
||||||
template <> struct is_char<char32_t> : std::true_type {};
|
template <> struct is_char<char32_t> : std::true_type {};
|
||||||
|
|
||||||
|
@ -482,7 +482,7 @@ inline size_t count_code_points(basic_string_view<char> s) {
|
|||||||
return num_code_points;
|
return num_code_points;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t count_code_points(basic_string_view<char8_t> s) {
|
inline size_t count_code_points(basic_string_view<char8_type> s) {
|
||||||
return count_code_points(basic_string_view<char>(
|
return count_code_points(basic_string_view<char>(
|
||||||
reinterpret_cast<const char*>(s.data()), s.size()));
|
reinterpret_cast<const char*>(s.data()), s.size()));
|
||||||
}
|
}
|
||||||
@ -494,8 +494,8 @@ inline size_t code_point_index(basic_string_view<Char> s, size_t n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the index of the nth code point in a UTF-8 string.
|
// Calculates the index of the nth code point in a UTF-8 string.
|
||||||
inline size_t code_point_index(basic_string_view<char8_t> s, size_t n) {
|
inline size_t code_point_index(basic_string_view<char8_type> s, size_t n) {
|
||||||
const char8_t* data = s.data();
|
const char8_type* data = s.data();
|
||||||
size_t num_code_points = 0;
|
size_t num_code_points = 0;
|
||||||
for (size_t i = 0, size = s.size(); i != size; ++i) {
|
for (size_t i = 0, size = s.size(); i != size; ++i) {
|
||||||
if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) {
|
if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) {
|
||||||
@ -505,13 +505,13 @@ inline size_t code_point_index(basic_string_view<char8_t> s, size_t n) {
|
|||||||
return s.size();
|
return s.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char8_t to_char8_t(char c) { return static_cast<char8_t>(c); }
|
inline char8_type to_char8_t(char c) { return static_cast<char8_type>(c); }
|
||||||
|
|
||||||
template <typename InputIt, typename OutChar>
|
template <typename InputIt, typename OutChar>
|
||||||
using needs_conversion = bool_constant<
|
using needs_conversion = bool_constant<
|
||||||
std::is_same<typename std::iterator_traits<InputIt>::value_type,
|
std::is_same<typename std::iterator_traits<InputIt>::value_type,
|
||||||
char>::value &&
|
char>::value &&
|
||||||
std::is_same<OutChar, char8_t>::value>;
|
std::is_same<OutChar, char8_type>::value>;
|
||||||
|
|
||||||
template <typename OutChar, typename InputIt, typename OutputIt,
|
template <typename OutChar, typename InputIt, typename OutputIt,
|
||||||
FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)>
|
FMT_ENABLE_IF(!needs_conversion<InputIt, OutChar>::value)>
|
||||||
@ -555,20 +555,22 @@ class buffer_range : public internal::output_range<
|
|||||||
: internal::output_range<iterator, T>(std::back_inserter(buf)) {}
|
: internal::output_range<iterator, T>(std::back_inserter(buf)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FMT_DEPRECATED u8string_view : public basic_string_view<char8_t> {
|
class FMT_DEPRECATED u8string_view
|
||||||
|
: public basic_string_view<internal::char8_type> {
|
||||||
public:
|
public:
|
||||||
u8string_view(const char* s)
|
u8string_view(const char* s)
|
||||||
: basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s)) {}
|
: basic_string_view<internal::char8_type>(
|
||||||
|
reinterpret_cast<const internal::char8_type*>(s)) {}
|
||||||
u8string_view(const char* s, size_t count) FMT_NOEXCEPT
|
u8string_view(const char* s, size_t count) FMT_NOEXCEPT
|
||||||
: basic_string_view<char8_t>(reinterpret_cast<const char8_t*>(s), count) {
|
: basic_string_view<internal::char8_type>(
|
||||||
}
|
reinterpret_cast<const internal::char8_type*>(s), count) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if FMT_USE_USER_DEFINED_LITERALS
|
#if FMT_USE_USER_DEFINED_LITERALS
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
FMT_DEPRECATED inline basic_string_view<char8_t> operator"" _u(const char* s,
|
FMT_DEPRECATED inline basic_string_view<internal::char8_type> operator"" _u(
|
||||||
std::size_t n) {
|
const char* s, std::size_t n) {
|
||||||
return {reinterpret_cast<const char8_t*>(s), n};
|
return {reinterpret_cast<const internal::char8_type*>(s), n};
|
||||||
}
|
}
|
||||||
} // namespace literals
|
} // namespace literals
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,12 +10,11 @@
|
|||||||
#include "test-assert.h"
|
#include "test-assert.h"
|
||||||
|
|
||||||
// Include format.cc instead of format.h to test implementation.
|
// Include format.cc instead of format.h to test implementation.
|
||||||
#include "../src/format.cc"
|
|
||||||
#include "fmt/printf.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "../src/format.cc"
|
||||||
|
#include "fmt/printf.h"
|
||||||
#include "gmock.h"
|
#include "gmock.h"
|
||||||
#include "gtest-extra.h"
|
#include "gtest-extra.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -430,8 +429,10 @@ TEST(FormatTest, CountCodePoints) {
|
|||||||
#ifndef __cpp_char8_t
|
#ifndef __cpp_char8_t
|
||||||
using fmt::char8_t;
|
using fmt::char8_t;
|
||||||
#endif
|
#endif
|
||||||
EXPECT_EQ(4, fmt::internal::count_code_points(
|
EXPECT_EQ(
|
||||||
fmt::basic_string_view<char8_t>(reinterpret_cast<const char8_t*>("ёжик"))));
|
4, fmt::internal::count_code_points(
|
||||||
|
fmt::basic_string_view<fmt::internal::char8_type>(
|
||||||
|
reinterpret_cast<const fmt::internal::char8_type*>("ёжик"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests fmt::internal::count_digits for integer type Int.
|
// Tests fmt::internal::count_digits for integer type Int.
|
||||||
|
@ -2504,25 +2504,6 @@ TEST(FormatTest, FmtStringInTemplate) {
|
|||||||
|
|
||||||
#endif // FMT_USE_CONSTEXPR
|
#endif // FMT_USE_CONSTEXPR
|
||||||
|
|
||||||
// C++20 feature test, since r346892 Clang considers char8_t a fundamental
|
|
||||||
// type in this mode. If this is the case __cpp_char8_t will be defined.
|
|
||||||
#ifndef __cpp_char8_t
|
|
||||||
// Locally provide type char8_t defined in format.h
|
|
||||||
using fmt::char8_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Convert 'char8_t' character sequences to 'char' sequences
|
|
||||||
// Otherwise GTest will insist on inserting 'char8_t' NTBS into a 'char' stream,
|
|
||||||
// but basic_ostream<char>::operator<< overloads taking 'char8_t' arguments
|
|
||||||
// are defined as deleted by P1423.
|
|
||||||
// Handling individual 'char8_t's is done inline.
|
|
||||||
std::string from_u8str(const std::basic_string<char8_t>& str) {
|
|
||||||
return std::string(str.begin(), str.end());
|
|
||||||
}
|
|
||||||
std::string from_u8str(const fmt::basic_string_view<char8_t>& str) {
|
|
||||||
return std::string(str.begin(), str.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FormatTest, EmphasisNonHeaderOnly) {
|
TEST(FormatTest, EmphasisNonHeaderOnly) {
|
||||||
// Ensure this compiles even if FMT_HEADER_ONLY is not defined.
|
// Ensure this compiles even if FMT_HEADER_ONLY is not defined.
|
||||||
EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold error"),
|
EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold error"),
|
||||||
@ -2561,10 +2542,18 @@ TEST(FormatTest, FormatCustomChar) {
|
|||||||
EXPECT_EQ(result[0], mychar('x'));
|
EXPECT_EQ(result[0], mychar('x'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a char8_t string to std::string. Otherwise GTest will insist on
|
||||||
|
// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423.
|
||||||
|
template <typename S> std::string from_u8str(const S& str) {
|
||||||
|
return std::string(str.begin(), str.end());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FormatTest, FormatUTF8Precision) {
|
TEST(FormatTest, FormatUTF8Precision) {
|
||||||
using str_type = std::basic_string<char8_t>;
|
using str_type = std::basic_string<fmt::internal::char8_type>;
|
||||||
str_type format(reinterpret_cast<const char8_t*>(u8"{:.4}"));
|
str_type format(
|
||||||
str_type str(reinterpret_cast<const char8_t*>(u8"caf\u00e9s")); // cafés
|
reinterpret_cast<const fmt::internal::char8_type*>(u8"{:.4}"));
|
||||||
|
str_type str(reinterpret_cast<const fmt::internal::char8_type*>(
|
||||||
|
u8"caf\u00e9s")); // cafés
|
||||||
auto result = fmt::format(format, str);
|
auto result = fmt::format(format, str);
|
||||||
EXPECT_EQ(fmt::internal::count_code_points(result), 4);
|
EXPECT_EQ(fmt::internal::count_code_points(result), 4);
|
||||||
EXPECT_EQ(result.size(), 5);
|
EXPECT_EQ(result.size(), 5);
|
||||||
|
Loading…
Reference in New Issue
Block a user