Improve debug codegen

This commit is contained in:
Victor Zverovich 2024-09-08 07:48:27 -07:00
parent 9408c2ae8c
commit 6c90b31fbd
2 changed files with 33 additions and 94 deletions

View File

@ -2226,17 +2226,39 @@ template <typename Context> class value {
constexpr FMT_INLINE value() : no_value() {}
constexpr FMT_INLINE value(int val) : int_value(val) {}
constexpr FMT_INLINE value(unsigned val FMT_BUILTIN) : uint_value(val) {}
FMT_CONSTEXPR FMT_INLINE value(long val FMT_BUILTIN) {
if (sizeof(long) == sizeof(int))
int_value = static_cast<int>(val);
else
long_long_value = val;
}
FMT_CONSTEXPR FMT_INLINE value(unsigned long val FMT_BUILTIN) {
if (sizeof(long) == sizeof(int))
uint_value = static_cast<unsigned>(val);
else
ulong_long_value = val;
}
constexpr FMT_INLINE value(long long val FMT_BUILTIN)
: long_long_value(val) {}
constexpr FMT_INLINE value(unsigned long long val FMT_BUILTIN)
: ulong_long_value(val) {}
template <int N>
constexpr FMT_INLINE value(bitint<N> val FMT_BUILTIN)
: long_long_value(val) {}
template <int N>
constexpr FMT_INLINE value(ubitint<N> val FMT_BUILTIN)
: ulong_long_value(val) {}
FMT_INLINE value(int128_opt val FMT_BUILTIN) : int128_value(val) {}
FMT_INLINE value(uint128_opt val FMT_BUILTIN) : uint128_value(val) {}
constexpr FMT_INLINE value(float val FMT_BUILTIN) : float_value(val) {}
constexpr FMT_INLINE value(double val FMT_BUILTIN) : double_value(val) {}
FMT_INLINE value(long double val FMT_BUILTIN) : long_double_value(val) {}
constexpr FMT_INLINE value(bool val FMT_BUILTIN) : bool_value(val) {}
constexpr FMT_INLINE value(char_type val FMT_BUILTIN) : char_value(val) {}
template <typename T, FMT_ENABLE_IF(is_char<T>::value)>
constexpr FMT_INLINE value(T val FMT_BUILTIN) : char_value(val) {
static_assert(std::is_same<T, char_type>::value,
"mixing character types is disallowed");
}
FMT_CONSTEXPR FMT_INLINE value(const char_type* val FMT_BUILTIN) {
string.data = val;
if (is_constant_evaluated()) string.size = {};
@ -2248,16 +2270,20 @@ template <typename Context> class value {
FMT_INLINE value(const void* val FMT_BUILTIN) : pointer(val) {}
// We can't use mapped_t because of a bug in MSVC 2017.
template <typename T,
FMT_ENABLE_IF(!std::is_same<T, decltype(arg_mapper<char_type>::map(
std::declval<T&>()))>::value)>
template <
typename T,
typename M = decltype(arg_mapper<char_type>::map(std::declval<T&>())),
FMT_ENABLE_IF(!std::is_same<T, M>::value &&
!std::is_integral<remove_cvref_t<T>>::value)>
FMT_CONSTEXPR20 FMT_INLINE value(T&& val) {
*this = arg_mapper<char_type>::map(val);
}
template <typename T,
FMT_ENABLE_IF(std::is_same<T, decltype(arg_mapper<char_type>::map(
std::declval<T&>()))>::value)>
template <
typename T,
typename M = decltype(arg_mapper<char_type>::map(std::declval<T&>())),
FMT_ENABLE_IF(std::is_same<T, M>::value &&
!std::is_integral<remove_cvref_t<T>>::value)>
FMT_CONSTEXPR20 FMT_INLINE value(T&& val) {
// Use enum instead of constexpr because the latter may generate code.
enum { formattable_char = !std::is_same<T, unformattable_char>::value };

View File

@ -95,93 +95,6 @@ TEST(xchar_test, compile_time_string) {
#endif
}
#if FMT_CPLUSPLUS > 201103L
struct custom_char {
int value;
custom_char() = default;
template <typename T>
constexpr custom_char(T val) : value(static_cast<int>(val)) {}
constexpr operator char() const {
return value <= 0xff ? static_cast<char>(value) : '\0';
}
constexpr bool operator<(custom_char c) const { return value < c.value; }
};
namespace std {
template <> struct char_traits<custom_char> {
using char_type = custom_char;
using int_type = int;
using off_type = streamoff;
using pos_type = streampos;
using state_type = mbstate_t;
static constexpr void assign(char_type& r, const char_type& a) { r = a; }
static constexpr bool eq(char_type a, char_type b) { return a == b; }
static constexpr bool lt(char_type a, char_type b) { return a < b; }
static FMT_CONSTEXPR int compare(const char_type* s1, const char_type* s2,
size_t count) {
for (; count; count--, s1++, s2++) {
if (lt(*s1, *s2)) return -1;
if (lt(*s2, *s1)) return 1;
}
return 0;
}
static FMT_CONSTEXPR size_t length(const char_type* s) {
size_t count = 0;
while (!eq(*s++, custom_char(0))) count++;
return count;
}
static const char_type* find(const char_type*, size_t, const char_type&);
static FMT_CONSTEXPR char_type* move(char_type* dest, const char_type* src,
size_t count) {
if (count == 0) return dest;
char_type* ret = dest;
if (src < dest) {
dest += count;
src += count;
for (; count; count--) assign(*--dest, *--src);
} else if (src > dest)
copy(dest, src, count);
return ret;
}
static FMT_CONSTEXPR char_type* copy(char_type* dest, const char_type* src,
size_t count) {
char_type* ret = dest;
for (; count; count--) assign(*dest++, *src++);
return ret;
}
static FMT_CONSTEXPR char_type* assign(char_type* dest, std::size_t count,
char_type a) {
char_type* ret = dest;
for (; count; count--) assign(*dest++, a);
return ret;
}
static int_type not_eof(int_type);
static char_type to_char_type(int_type);
static int_type to_int_type(char_type);
static bool eq_int_type(int_type, int_type);
static int_type eof();
};
} // namespace std
auto to_ascii(custom_char c) -> char { return c; }
FMT_BEGIN_NAMESPACE
template <> struct is_char<custom_char> : std::true_type {};
FMT_END_NAMESPACE
TEST(xchar_test, format_custom_char) {
const custom_char format[] = {'{', '}', 0};
auto result = fmt::format(format, custom_char('x'));
EXPECT_EQ(result.size(), 1);
EXPECT_EQ(result[0], custom_char('x'));
}
#endif
TEST(xchar_test, format_to) {
auto buf = std::vector<wchar_t>();
fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0');