mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-21 18:20:04 +00:00
Improve debug codegen
This commit is contained in:
parent
9408c2ae8c
commit
6c90b31fbd
@ -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 };
|
||||
|
@ -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');
|
||||
|
Loading…
Reference in New Issue
Block a user