mirror of
https://github.com/fmtlib/fmt.git
synced 2024-10-06 06:50:00 +00:00
Supporting ? as a string presentation type (#2674)
* Supporting ? as a string presentation type. * Supporting ? as a char presentation type. * Adding iterator_category to counting_iterator.
This commit is contained in:
parent
ae1aaaee5f
commit
a34a97cc1d
@ -13,45 +13,6 @@
|
|||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
// An output iterator that counts the number of objects written to it and
|
|
||||||
// discards them.
|
|
||||||
class counting_iterator {
|
|
||||||
private:
|
|
||||||
size_t count_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using iterator_category = std::output_iterator_tag;
|
|
||||||
using difference_type = std::ptrdiff_t;
|
|
||||||
using pointer = void;
|
|
||||||
using reference = void;
|
|
||||||
using _Unchecked_type = counting_iterator; // Mark iterator as checked.
|
|
||||||
|
|
||||||
struct value_type {
|
|
||||||
template <typename T> void operator=(const T&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
counting_iterator() : count_(0) {}
|
|
||||||
|
|
||||||
size_t count() const { return count_; }
|
|
||||||
|
|
||||||
counting_iterator& operator++() {
|
|
||||||
++count_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
counting_iterator operator++(int) {
|
|
||||||
auto it = *this;
|
|
||||||
++*this;
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend counting_iterator operator+(counting_iterator it, difference_type n) {
|
|
||||||
it.count_ += static_cast<size_t>(n);
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type operator*() const { return {}; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Char, typename InputIt>
|
template <typename Char, typename InputIt>
|
||||||
inline counting_iterator copy_str(InputIt begin, InputIt end,
|
inline counting_iterator copy_str(InputIt begin, InputIt end,
|
||||||
counting_iterator it) {
|
counting_iterator it) {
|
||||||
|
@ -2059,7 +2059,8 @@ enum class presentation_type : unsigned char {
|
|||||||
general_upper, // 'G'
|
general_upper, // 'G'
|
||||||
chr, // 'c'
|
chr, // 'c'
|
||||||
string, // 's'
|
string, // 's'
|
||||||
pointer // 'p'
|
pointer, // 'p'
|
||||||
|
debug // '?'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Format specifiers for built-in and string types.
|
// Format specifiers for built-in and string types.
|
||||||
@ -2475,6 +2476,8 @@ FMT_CONSTEXPR auto parse_presentation_type(Char type) -> presentation_type {
|
|||||||
return presentation_type::string;
|
return presentation_type::string;
|
||||||
case 'p':
|
case 'p':
|
||||||
return presentation_type::pointer;
|
return presentation_type::pointer;
|
||||||
|
case '?':
|
||||||
|
return presentation_type::debug;
|
||||||
default:
|
default:
|
||||||
return presentation_type::none;
|
return presentation_type::none;
|
||||||
}
|
}
|
||||||
@ -2704,7 +2707,8 @@ template <typename Char, typename ErrorHandler = error_handler>
|
|||||||
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs<Char>& specs,
|
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs<Char>& specs,
|
||||||
ErrorHandler&& eh = {}) -> bool {
|
ErrorHandler&& eh = {}) -> bool {
|
||||||
if (specs.type != presentation_type::none &&
|
if (specs.type != presentation_type::none &&
|
||||||
specs.type != presentation_type::chr) {
|
specs.type != presentation_type::chr &&
|
||||||
|
specs.type != presentation_type::debug) {
|
||||||
check_int_type_spec(specs.type, eh);
|
check_int_type_spec(specs.type, eh);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2788,7 +2792,8 @@ FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type,
|
|||||||
template <typename ErrorHandler = error_handler>
|
template <typename ErrorHandler = error_handler>
|
||||||
FMT_CONSTEXPR void check_string_type_spec(presentation_type type,
|
FMT_CONSTEXPR void check_string_type_spec(presentation_type type,
|
||||||
ErrorHandler&& eh = {}) {
|
ErrorHandler&& eh = {}) {
|
||||||
if (type != presentation_type::none && type != presentation_type::string)
|
if (type != presentation_type::none && type != presentation_type::string &&
|
||||||
|
type != presentation_type::debug)
|
||||||
eh.on_error("invalid type specifier");
|
eh.on_error("invalid type specifier");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2570,6 +2570,197 @@ FMT_FUNC void vprint(string_view format_str, format_args args) {
|
|||||||
vprint(stdout, format_str, args);
|
vprint(stdout, format_str, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
struct singleton {
|
||||||
|
unsigned char upper;
|
||||||
|
unsigned char lower_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline auto is_printable(uint16_t x, const singleton* singletons,
|
||||||
|
size_t singletons_size,
|
||||||
|
const unsigned char* singleton_lowers,
|
||||||
|
const unsigned char* normal, size_t normal_size)
|
||||||
|
-> bool {
|
||||||
|
auto upper = x >> 8;
|
||||||
|
auto lower_start = 0;
|
||||||
|
for (size_t i = 0; i < singletons_size; ++i) {
|
||||||
|
auto s = singletons[i];
|
||||||
|
auto lower_end = lower_start + s.lower_count;
|
||||||
|
if (upper < s.upper) break;
|
||||||
|
if (upper == s.upper) {
|
||||||
|
for (auto j = lower_start; j < lower_end; ++j) {
|
||||||
|
if (singleton_lowers[j] == (x & 0xff)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lower_start = lower_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto xsigned = static_cast<int>(x);
|
||||||
|
auto current = true;
|
||||||
|
for (size_t i = 0; i < normal_size; ++i) {
|
||||||
|
auto v = static_cast<int>(normal[i]);
|
||||||
|
auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v;
|
||||||
|
xsigned -= len;
|
||||||
|
if (xsigned < 0) break;
|
||||||
|
current = !current;
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This code is generated by support/printable.py.
|
||||||
|
FMT_FUNC auto is_printable(uint32_t cp) -> bool {
|
||||||
|
static constexpr singleton singletons0[] = {
|
||||||
|
{0x00, 1}, {0x03, 5}, {0x05, 6}, {0x06, 3}, {0x07, 6}, {0x08, 8},
|
||||||
|
{0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13},
|
||||||
|
{0x0f, 4}, {0x10, 3}, {0x12, 18}, {0x13, 9}, {0x16, 1}, {0x17, 5},
|
||||||
|
{0x18, 2}, {0x19, 3}, {0x1a, 7}, {0x1c, 2}, {0x1d, 1}, {0x1f, 22},
|
||||||
|
{0x20, 3}, {0x2b, 3}, {0x2c, 2}, {0x2d, 11}, {0x2e, 1}, {0x30, 3},
|
||||||
|
{0x31, 2}, {0x32, 1}, {0xa7, 2}, {0xa9, 2}, {0xaa, 4}, {0xab, 8},
|
||||||
|
{0xfa, 2}, {0xfb, 5}, {0xfd, 4}, {0xfe, 3}, {0xff, 9},
|
||||||
|
};
|
||||||
|
static constexpr unsigned char singletons0_lower[] = {
|
||||||
|
0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90,
|
||||||
|
0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
|
||||||
|
0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1,
|
||||||
|
0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,
|
||||||
|
0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d,
|
||||||
|
0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,
|
||||||
|
0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
|
||||||
|
0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,
|
||||||
|
0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d,
|
||||||
|
0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d,
|
||||||
|
0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,
|
||||||
|
0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7,
|
||||||
|
0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49,
|
||||||
|
0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7,
|
||||||
|
0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7,
|
||||||
|
0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e,
|
||||||
|
0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16,
|
||||||
|
0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e,
|
||||||
|
0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f,
|
||||||
|
0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
|
||||||
|
0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0,
|
||||||
|
0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27,
|
||||||
|
0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91,
|
||||||
|
0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,
|
||||||
|
0xfe, 0xff,
|
||||||
|
};
|
||||||
|
static constexpr singleton singletons1[] = {
|
||||||
|
{0x00, 6}, {0x01, 1}, {0x03, 1}, {0x04, 2}, {0x08, 8}, {0x09, 2},
|
||||||
|
{0x0a, 5}, {0x0b, 2}, {0x0e, 4}, {0x10, 1}, {0x11, 2}, {0x12, 5},
|
||||||
|
{0x13, 17}, {0x14, 1}, {0x15, 2}, {0x17, 2}, {0x19, 13}, {0x1c, 5},
|
||||||
|
{0x1d, 8}, {0x24, 1}, {0x6a, 3}, {0x6b, 2}, {0xbc, 2}, {0xd1, 2},
|
||||||
|
{0xd4, 12}, {0xd5, 9}, {0xd6, 2}, {0xd7, 2}, {0xda, 1}, {0xe0, 5},
|
||||||
|
{0xe1, 2}, {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2}, {0xf9, 2},
|
||||||
|
{0xfa, 2}, {0xfb, 1},
|
||||||
|
};
|
||||||
|
static constexpr unsigned char singletons1_lower[] = {
|
||||||
|
0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07,
|
||||||
|
0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
|
||||||
|
0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87,
|
||||||
|
0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
|
||||||
|
0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b,
|
||||||
|
0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9,
|
||||||
|
0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66,
|
||||||
|
0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27,
|
||||||
|
0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc,
|
||||||
|
0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7,
|
||||||
|
0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6,
|
||||||
|
0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c,
|
||||||
|
0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66,
|
||||||
|
0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0,
|
||||||
|
0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93,
|
||||||
|
};
|
||||||
|
static constexpr unsigned char normal0[] = {
|
||||||
|
0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04,
|
||||||
|
0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0,
|
||||||
|
0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01,
|
||||||
|
0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03,
|
||||||
|
0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03,
|
||||||
|
0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a,
|
||||||
|
0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15,
|
||||||
|
0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f,
|
||||||
|
0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80,
|
||||||
|
0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07,
|
||||||
|
0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06,
|
||||||
|
0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04,
|
||||||
|
0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac,
|
||||||
|
0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c,
|
||||||
|
0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11,
|
||||||
|
0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c,
|
||||||
|
0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b,
|
||||||
|
0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6,
|
||||||
|
0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03,
|
||||||
|
0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80,
|
||||||
|
0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06,
|
||||||
|
0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c,
|
||||||
|
0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17,
|
||||||
|
0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80,
|
||||||
|
0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80,
|
||||||
|
0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d,
|
||||||
|
};
|
||||||
|
static constexpr unsigned char normal1[] = {
|
||||||
|
0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f,
|
||||||
|
0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e,
|
||||||
|
0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04,
|
||||||
|
0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09,
|
||||||
|
0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16,
|
||||||
|
0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f,
|
||||||
|
0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36,
|
||||||
|
0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33,
|
||||||
|
0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08,
|
||||||
|
0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e,
|
||||||
|
0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41,
|
||||||
|
0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03,
|
||||||
|
0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22,
|
||||||
|
0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04,
|
||||||
|
0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45,
|
||||||
|
0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03,
|
||||||
|
0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81,
|
||||||
|
0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75,
|
||||||
|
0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1,
|
||||||
|
0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a,
|
||||||
|
0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11,
|
||||||
|
0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09,
|
||||||
|
0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89,
|
||||||
|
0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6,
|
||||||
|
0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09,
|
||||||
|
0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50,
|
||||||
|
0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05,
|
||||||
|
0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83,
|
||||||
|
0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05,
|
||||||
|
0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80,
|
||||||
|
0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80,
|
||||||
|
0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07,
|
||||||
|
0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e,
|
||||||
|
0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07,
|
||||||
|
0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06,
|
||||||
|
};
|
||||||
|
auto lower = static_cast<uint16_t>(cp);
|
||||||
|
if (cp < 0x10000) {
|
||||||
|
return is_printable(lower, singletons0,
|
||||||
|
sizeof(singletons0) / sizeof(*singletons0),
|
||||||
|
singletons0_lower, normal0, sizeof(normal0));
|
||||||
|
}
|
||||||
|
if (cp < 0x20000) {
|
||||||
|
return is_printable(lower, singletons1,
|
||||||
|
sizeof(singletons1) / sizeof(*singletons1),
|
||||||
|
singletons1_lower, normal1, sizeof(normal1));
|
||||||
|
}
|
||||||
|
if (0x2a6de <= cp && cp < 0x2a700) return false;
|
||||||
|
if (0x2b735 <= cp && cp < 0x2b740) return false;
|
||||||
|
if (0x2b81e <= cp && cp < 0x2b820) return false;
|
||||||
|
if (0x2cea2 <= cp && cp < 0x2ceb0) return false;
|
||||||
|
if (0x2ebe1 <= cp && cp < 0x2f800) return false;
|
||||||
|
if (0x2fa1e <= cp && cp < 0x30000) return false;
|
||||||
|
if (0x3134b <= cp && cp < 0xe0100) return false;
|
||||||
|
if (0xe01f0 <= cp && cp < 0x110000) return false;
|
||||||
|
return cp < 0x110000;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // FMT_FORMAT_INL_H_
|
#endif // FMT_FORMAT_INL_H_
|
||||||
|
@ -1367,11 +1367,173 @@ auto write_ptr(OutputIt out, UIntPtr value,
|
|||||||
: base_iterator(out, write(reserve(out, size)));
|
: base_iterator(out, write(reserve(out, size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true iff the code point cp is printable.
|
||||||
|
FMT_API auto is_printable(uint32_t cp) -> bool;
|
||||||
|
|
||||||
|
inline auto needs_escape(uint32_t cp) -> bool {
|
||||||
|
return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' ||
|
||||||
|
!is_printable(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Char> struct find_escape_result {
|
||||||
|
const Char* begin;
|
||||||
|
const Char* end;
|
||||||
|
uint32_t cp;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
using make_unsigned_char =
|
||||||
|
typename conditional_t<std::is_integral<Char>::value,
|
||||||
|
std::make_unsigned<Char>,
|
||||||
|
type_identity<uint32_t>>::type;
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
auto find_escape(const Char* begin, const Char* end)
|
||||||
|
-> find_escape_result<Char> {
|
||||||
|
for (; begin != end; ++begin) {
|
||||||
|
uint32_t cp = static_cast<make_unsigned_char<Char>>(*begin);
|
||||||
|
if (sizeof(Char) == 1 && cp >= 0x80) continue;
|
||||||
|
if (needs_escape(cp)) return {begin, begin + 1, cp};
|
||||||
|
}
|
||||||
|
return {begin, nullptr, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto find_escape(const char* begin, const char* end)
|
||||||
|
-> find_escape_result<char> {
|
||||||
|
if (!is_utf8()) return find_escape<char>(begin, end);
|
||||||
|
auto result = find_escape_result<char>{end, nullptr, 0};
|
||||||
|
for_each_codepoint(string_view(begin, to_unsigned(end - begin)),
|
||||||
|
[&](uint32_t cp, string_view sv) {
|
||||||
|
if (needs_escape(cp)) {
|
||||||
|
result = {sv.begin(), sv.end(), cp};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FMT_STRING_IMPL(s, base, explicit) \
|
||||||
|
[] { \
|
||||||
|
/* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
|
||||||
|
/* Use a macro-like name to avoid shadowing warnings. */ \
|
||||||
|
struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
|
||||||
|
using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
|
||||||
|
FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
|
||||||
|
operator fmt::basic_string_view<char_type>() const { \
|
||||||
|
return fmt::detail_exported::compile_string_to_view<char_type>(s); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
return FMT_COMPILE_STRING(); \
|
||||||
|
}()
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Constructs a compile-time format string from a string literal *s*.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
// A compile-time error because 'd' is an invalid specifier for strings.
|
||||||
|
std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, )
|
||||||
|
|
||||||
|
template <typename Char, typename OutputIt>
|
||||||
|
auto write_escaped_string(OutputIt out, basic_string_view<Char> str)
|
||||||
|
-> OutputIt {
|
||||||
|
return copy_str<Char>(str.data(), str.data() + str.size(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt, typename Char>
|
||||||
|
auto write_escaped_cp(OutputIt out, const find_escape_result<Char>& escape)
|
||||||
|
-> OutputIt {
|
||||||
|
auto c = static_cast<Char>(escape.cp);
|
||||||
|
switch (escape.cp) {
|
||||||
|
case '\n':
|
||||||
|
*out++ = '\\';
|
||||||
|
c = 'n';
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
*out++ = '\\';
|
||||||
|
c = 'r';
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
*out++ = '\\';
|
||||||
|
c = 't';
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
FMT_FALLTHROUGH;
|
||||||
|
case '\'':
|
||||||
|
FMT_FALLTHROUGH;
|
||||||
|
case '\\':
|
||||||
|
*out++ = '\\';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (is_utf8()) {
|
||||||
|
if (escape.cp < 0x100) {
|
||||||
|
return format_to(out, FMT_STRING("\\x{:02x}"), escape.cp);
|
||||||
|
}
|
||||||
|
if (escape.cp < 0x10000) {
|
||||||
|
return format_to(out, FMT_STRING("\\u{:04x}"), escape.cp);
|
||||||
|
}
|
||||||
|
if (escape.cp < 0x110000) {
|
||||||
|
return format_to(out, FMT_STRING("\\U{:08x}"), escape.cp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (char escape_char : basic_string_view<Char>(
|
||||||
|
escape.begin, to_unsigned(escape.end - escape.begin))) {
|
||||||
|
out = format_to(out, FMT_STRING("\\x{:02x}"),
|
||||||
|
static_cast<make_unsigned_char<Char>>(escape_char));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
*out++ = c;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt>
|
||||||
|
auto write_escaped_string(OutputIt out, basic_string_view<char> str)
|
||||||
|
-> OutputIt {
|
||||||
|
*out++ = '"';
|
||||||
|
auto begin = str.begin(), end = str.end();
|
||||||
|
do {
|
||||||
|
auto escape = find_escape(begin, end);
|
||||||
|
out = copy_str<char>(begin, escape.begin, out);
|
||||||
|
begin = escape.end;
|
||||||
|
if (!begin) break;
|
||||||
|
out = write_escaped_cp(out, escape);
|
||||||
|
} while (begin != end);
|
||||||
|
*out++ = '"';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Char, typename OutputIt>
|
||||||
|
auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
|
||||||
|
*out++ = v;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt>
|
||||||
|
auto write_escaped_char(OutputIt out, char v) -> OutputIt {
|
||||||
|
*out++ = '\'';
|
||||||
|
if ((needs_escape(static_cast<uint32_t>(v)) && v != '"') || v == '\'') {
|
||||||
|
out = write_escaped_cp(
|
||||||
|
out, find_escape_result<char>{&v, &v + 1, static_cast<uint32_t>(v)});
|
||||||
|
} else {
|
||||||
|
*out++ = v;
|
||||||
|
}
|
||||||
|
*out++ = '\'';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Char, typename OutputIt>
|
template <typename Char, typename OutputIt>
|
||||||
FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
|
FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
|
||||||
const basic_format_specs<Char>& specs)
|
const basic_format_specs<Char>& specs)
|
||||||
-> OutputIt {
|
-> OutputIt {
|
||||||
|
bool is_debug = specs.type == presentation_type::debug;
|
||||||
return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
|
return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
|
||||||
|
if (is_debug) return write_escaped_char(it, value);
|
||||||
*it++ = value;
|
*it++ = value;
|
||||||
return it;
|
return it;
|
||||||
});
|
});
|
||||||
@ -1637,6 +1799,45 @@ FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
|
|||||||
return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
|
return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An output iterator that counts the number of objects written to it and
|
||||||
|
// discards them.
|
||||||
|
class counting_iterator {
|
||||||
|
private:
|
||||||
|
size_t count_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator_category = std::output_iterator_tag;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = void;
|
||||||
|
using reference = void;
|
||||||
|
using _Unchecked_type = counting_iterator; // Mark iterator as checked.
|
||||||
|
|
||||||
|
struct value_type {
|
||||||
|
template <typename T> void operator=(const T&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
counting_iterator() : count_(0) {}
|
||||||
|
|
||||||
|
size_t count() const { return count_; }
|
||||||
|
|
||||||
|
counting_iterator& operator++() {
|
||||||
|
++count_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
counting_iterator operator++(int) {
|
||||||
|
auto it = *this;
|
||||||
|
++*this;
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend counting_iterator operator+(counting_iterator it, difference_type n) {
|
||||||
|
it.count_ += static_cast<size_t>(n);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator*() const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Char, typename OutputIt>
|
template <typename Char, typename OutputIt>
|
||||||
FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
|
FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
|
||||||
const basic_format_specs<Char>& specs) -> OutputIt {
|
const basic_format_specs<Char>& specs) -> OutputIt {
|
||||||
@ -1644,10 +1845,17 @@ FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
|
|||||||
auto size = s.size();
|
auto size = s.size();
|
||||||
if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
|
if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
|
||||||
size = code_point_index(s, to_unsigned(specs.precision));
|
size = code_point_index(s, to_unsigned(specs.precision));
|
||||||
auto width =
|
bool is_debug = specs.type == presentation_type::debug;
|
||||||
specs.width != 0 ? compute_width(basic_string_view<Char>(data, size)) : 0;
|
size_t width = 0;
|
||||||
|
if (specs.width != 0) {
|
||||||
|
if (is_debug)
|
||||||
|
width = write_escaped_string(counting_iterator{}, s).count();
|
||||||
|
else
|
||||||
|
width = compute_width(basic_string_view<Char>(data, size));
|
||||||
|
}
|
||||||
return write_padded(out, specs, size, width,
|
return write_padded(out, specs, size, width,
|
||||||
[=](reserve_iterator<OutputIt> it) {
|
[=](reserve_iterator<OutputIt> it) {
|
||||||
|
if (is_debug) return write_escaped_string(it, s);
|
||||||
return copy_str<Char>(data, data + size, it);
|
return copy_str<Char>(data, data + size, it);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -2346,32 +2554,6 @@ FMT_CONSTEXPR void handle_dynamic_spec(int& value,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FMT_STRING_IMPL(s, base, explicit) \
|
|
||||||
[] { \
|
|
||||||
/* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
|
|
||||||
/* Use a macro-like name to avoid shadowing warnings. */ \
|
|
||||||
struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
|
|
||||||
using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
|
|
||||||
FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
|
|
||||||
operator fmt::basic_string_view<char_type>() const { \
|
|
||||||
return fmt::detail_exported::compile_string_to_view<char_type>(s); \
|
|
||||||
} \
|
|
||||||
}; \
|
|
||||||
return FMT_COMPILE_STRING(); \
|
|
||||||
}()
|
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Constructs a compile-time format string from a string literal *s*.
|
|
||||||
|
|
||||||
**Example**::
|
|
||||||
|
|
||||||
// A compile-time error because 'd' is an invalid specifier for strings.
|
|
||||||
std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, )
|
|
||||||
|
|
||||||
#if FMT_USE_USER_DEFINED_LITERALS
|
#if FMT_USE_USER_DEFINED_LITERALS
|
||||||
template <typename Char> struct udl_formatter {
|
template <typename Char> struct udl_formatter {
|
||||||
basic_string_view<Char> str;
|
basic_string_view<Char> str;
|
||||||
|
@ -250,286 +250,9 @@ template <typename OutputIt> OutputIt write_delimiter(OutputIt out) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct singleton {
|
|
||||||
unsigned char upper;
|
|
||||||
unsigned char lower_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline auto is_printable(uint16_t x, const singleton* singletons,
|
|
||||||
size_t singletons_size,
|
|
||||||
const unsigned char* singleton_lowers,
|
|
||||||
const unsigned char* normal, size_t normal_size)
|
|
||||||
-> bool {
|
|
||||||
auto upper = x >> 8;
|
|
||||||
auto lower_start = 0;
|
|
||||||
for (size_t i = 0; i < singletons_size; ++i) {
|
|
||||||
auto s = singletons[i];
|
|
||||||
auto lower_end = lower_start + s.lower_count;
|
|
||||||
if (upper < s.upper) break;
|
|
||||||
if (upper == s.upper) {
|
|
||||||
for (auto j = lower_start; j < lower_end; ++j) {
|
|
||||||
if (singleton_lowers[j] == (x & 0xff)) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lower_start = lower_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto xsigned = static_cast<int>(x);
|
|
||||||
auto current = true;
|
|
||||||
for (size_t i = 0; i < normal_size; ++i) {
|
|
||||||
auto v = static_cast<int>(normal[i]);
|
|
||||||
auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v;
|
|
||||||
xsigned -= len;
|
|
||||||
if (xsigned < 0) break;
|
|
||||||
current = !current;
|
|
||||||
}
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true iff the code point cp is printable.
|
|
||||||
// This code is generated by support/printable.py.
|
|
||||||
inline auto is_printable(uint32_t cp) -> bool {
|
|
||||||
static constexpr singleton singletons0[] = {
|
|
||||||
{0x00, 1}, {0x03, 5}, {0x05, 6}, {0x06, 3}, {0x07, 6}, {0x08, 8},
|
|
||||||
{0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13},
|
|
||||||
{0x0f, 4}, {0x10, 3}, {0x12, 18}, {0x13, 9}, {0x16, 1}, {0x17, 5},
|
|
||||||
{0x18, 2}, {0x19, 3}, {0x1a, 7}, {0x1c, 2}, {0x1d, 1}, {0x1f, 22},
|
|
||||||
{0x20, 3}, {0x2b, 3}, {0x2c, 2}, {0x2d, 11}, {0x2e, 1}, {0x30, 3},
|
|
||||||
{0x31, 2}, {0x32, 1}, {0xa7, 2}, {0xa9, 2}, {0xaa, 4}, {0xab, 8},
|
|
||||||
{0xfa, 2}, {0xfb, 5}, {0xfd, 4}, {0xfe, 3}, {0xff, 9},
|
|
||||||
};
|
|
||||||
static constexpr unsigned char singletons0_lower[] = {
|
|
||||||
0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90,
|
|
||||||
0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
|
|
||||||
0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1,
|
|
||||||
0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,
|
|
||||||
0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d,
|
|
||||||
0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,
|
|
||||||
0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
|
|
||||||
0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,
|
|
||||||
0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d,
|
|
||||||
0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d,
|
|
||||||
0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,
|
|
||||||
0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7,
|
|
||||||
0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49,
|
|
||||||
0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7,
|
|
||||||
0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7,
|
|
||||||
0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e,
|
|
||||||
0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16,
|
|
||||||
0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e,
|
|
||||||
0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f,
|
|
||||||
0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
|
|
||||||
0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0,
|
|
||||||
0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27,
|
|
||||||
0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91,
|
|
||||||
0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,
|
|
||||||
0xfe, 0xff,
|
|
||||||
};
|
|
||||||
static constexpr singleton singletons1[] = {
|
|
||||||
{0x00, 6}, {0x01, 1}, {0x03, 1}, {0x04, 2}, {0x08, 8}, {0x09, 2},
|
|
||||||
{0x0a, 5}, {0x0b, 2}, {0x0e, 4}, {0x10, 1}, {0x11, 2}, {0x12, 5},
|
|
||||||
{0x13, 17}, {0x14, 1}, {0x15, 2}, {0x17, 2}, {0x19, 13}, {0x1c, 5},
|
|
||||||
{0x1d, 8}, {0x24, 1}, {0x6a, 3}, {0x6b, 2}, {0xbc, 2}, {0xd1, 2},
|
|
||||||
{0xd4, 12}, {0xd5, 9}, {0xd6, 2}, {0xd7, 2}, {0xda, 1}, {0xe0, 5},
|
|
||||||
{0xe1, 2}, {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2}, {0xf9, 2},
|
|
||||||
{0xfa, 2}, {0xfb, 1},
|
|
||||||
};
|
|
||||||
static constexpr unsigned char singletons1_lower[] = {
|
|
||||||
0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07,
|
|
||||||
0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
|
|
||||||
0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87,
|
|
||||||
0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
|
|
||||||
0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b,
|
|
||||||
0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9,
|
|
||||||
0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66,
|
|
||||||
0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27,
|
|
||||||
0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc,
|
|
||||||
0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7,
|
|
||||||
0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6,
|
|
||||||
0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c,
|
|
||||||
0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66,
|
|
||||||
0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0,
|
|
||||||
0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93,
|
|
||||||
};
|
|
||||||
static constexpr unsigned char normal0[] = {
|
|
||||||
0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04,
|
|
||||||
0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0,
|
|
||||||
0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01,
|
|
||||||
0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03,
|
|
||||||
0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03,
|
|
||||||
0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a,
|
|
||||||
0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15,
|
|
||||||
0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f,
|
|
||||||
0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80,
|
|
||||||
0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07,
|
|
||||||
0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06,
|
|
||||||
0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04,
|
|
||||||
0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac,
|
|
||||||
0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c,
|
|
||||||
0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11,
|
|
||||||
0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c,
|
|
||||||
0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b,
|
|
||||||
0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6,
|
|
||||||
0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03,
|
|
||||||
0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80,
|
|
||||||
0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06,
|
|
||||||
0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c,
|
|
||||||
0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17,
|
|
||||||
0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80,
|
|
||||||
0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80,
|
|
||||||
0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d,
|
|
||||||
};
|
|
||||||
static constexpr unsigned char normal1[] = {
|
|
||||||
0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f,
|
|
||||||
0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e,
|
|
||||||
0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04,
|
|
||||||
0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09,
|
|
||||||
0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16,
|
|
||||||
0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f,
|
|
||||||
0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36,
|
|
||||||
0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33,
|
|
||||||
0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08,
|
|
||||||
0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e,
|
|
||||||
0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41,
|
|
||||||
0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03,
|
|
||||||
0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22,
|
|
||||||
0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04,
|
|
||||||
0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45,
|
|
||||||
0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03,
|
|
||||||
0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81,
|
|
||||||
0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75,
|
|
||||||
0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1,
|
|
||||||
0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a,
|
|
||||||
0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11,
|
|
||||||
0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09,
|
|
||||||
0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89,
|
|
||||||
0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6,
|
|
||||||
0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09,
|
|
||||||
0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50,
|
|
||||||
0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05,
|
|
||||||
0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83,
|
|
||||||
0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05,
|
|
||||||
0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80,
|
|
||||||
0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80,
|
|
||||||
0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07,
|
|
||||||
0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e,
|
|
||||||
0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07,
|
|
||||||
0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06,
|
|
||||||
};
|
|
||||||
auto lower = static_cast<uint16_t>(cp);
|
|
||||||
if (cp < 0x10000) {
|
|
||||||
return is_printable(lower, singletons0,
|
|
||||||
sizeof(singletons0) / sizeof(*singletons0),
|
|
||||||
singletons0_lower, normal0, sizeof(normal0));
|
|
||||||
}
|
|
||||||
if (cp < 0x20000) {
|
|
||||||
return is_printable(lower, singletons1,
|
|
||||||
sizeof(singletons1) / sizeof(*singletons1),
|
|
||||||
singletons1_lower, normal1, sizeof(normal1));
|
|
||||||
}
|
|
||||||
if (0x2a6de <= cp && cp < 0x2a700) return false;
|
|
||||||
if (0x2b735 <= cp && cp < 0x2b740) return false;
|
|
||||||
if (0x2b81e <= cp && cp < 0x2b820) return false;
|
|
||||||
if (0x2cea2 <= cp && cp < 0x2ceb0) return false;
|
|
||||||
if (0x2ebe1 <= cp && cp < 0x2f800) return false;
|
|
||||||
if (0x2fa1e <= cp && cp < 0x30000) return false;
|
|
||||||
if (0x3134b <= cp && cp < 0xe0100) return false;
|
|
||||||
if (0xe01f0 <= cp && cp < 0x110000) return false;
|
|
||||||
return cp < 0x110000;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline auto needs_escape(uint32_t cp) -> bool {
|
|
||||||
return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' ||
|
|
||||||
!is_printable(cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char> struct find_escape_result {
|
|
||||||
const Char* begin;
|
|
||||||
const Char* end;
|
|
||||||
uint32_t cp;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
auto find_escape(const Char* begin, const Char* end)
|
|
||||||
-> find_escape_result<Char> {
|
|
||||||
for (; begin != end; ++begin) {
|
|
||||||
auto cp = static_cast<typename std::make_unsigned<Char>::type>(*begin);
|
|
||||||
if (sizeof(Char) == 1 && cp >= 0x80) continue;
|
|
||||||
if (needs_escape(cp)) return {begin, begin + 1, cp};
|
|
||||||
}
|
|
||||||
return {begin, nullptr, 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline auto find_escape(const char* begin, const char* end)
|
|
||||||
-> find_escape_result<char> {
|
|
||||||
if (!is_utf8()) return find_escape<char>(begin, end);
|
|
||||||
auto result = find_escape_result<char>{end, nullptr, 0};
|
|
||||||
for_each_codepoint(string_view(begin, to_unsigned(end - begin)),
|
|
||||||
[&](uint32_t cp, string_view sv) {
|
|
||||||
if (needs_escape(cp)) {
|
|
||||||
result = {sv.begin(), sv.end(), cp};
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char, typename OutputIt>
|
template <typename Char, typename OutputIt>
|
||||||
auto write_range_entry(OutputIt out, basic_string_view<Char> str) -> OutputIt {
|
auto write_range_entry(OutputIt out, basic_string_view<Char> str) -> OutputIt {
|
||||||
*out++ = '"';
|
return write_escaped_string(out, str);
|
||||||
auto begin = str.begin(), end = str.end();
|
|
||||||
do {
|
|
||||||
auto escape = find_escape(begin, end);
|
|
||||||
out = copy_str<Char>(begin, escape.begin, out);
|
|
||||||
begin = escape.end;
|
|
||||||
if (!begin) break;
|
|
||||||
auto c = static_cast<Char>(escape.cp);
|
|
||||||
switch (escape.cp) {
|
|
||||||
case '\n':
|
|
||||||
*out++ = '\\';
|
|
||||||
c = 'n';
|
|
||||||
break;
|
|
||||||
case '\r':
|
|
||||||
*out++ = '\\';
|
|
||||||
c = 'r';
|
|
||||||
break;
|
|
||||||
case '\t':
|
|
||||||
*out++ = '\\';
|
|
||||||
c = 't';
|
|
||||||
break;
|
|
||||||
case '"':
|
|
||||||
FMT_FALLTHROUGH;
|
|
||||||
case '\\':
|
|
||||||
*out++ = '\\';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (is_utf8()) {
|
|
||||||
if (escape.cp < 0x100) {
|
|
||||||
out = format_to(out, "\\x{:02x}", escape.cp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (escape.cp < 0x10000) {
|
|
||||||
out = format_to(out, "\\u{:04x}", escape.cp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (escape.cp < 0x110000) {
|
|
||||||
out = format_to(out, "\\U{:08x}", escape.cp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Char escape_char : basic_string_view<Char>(
|
|
||||||
escape.begin, to_unsigned(escape.end - escape.begin))) {
|
|
||||||
out = format_to(
|
|
||||||
out, "\\x{:02x}",
|
|
||||||
static_cast<typename std::make_unsigned<Char>::type>(escape_char));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*out++ = c;
|
|
||||||
} while (begin != end);
|
|
||||||
*out++ = '"';
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char, typename OutputIt, typename T,
|
template <typename Char, typename OutputIt, typename T,
|
||||||
@ -542,10 +265,7 @@ inline auto write_range_entry(OutputIt out, const T& str) -> OutputIt {
|
|||||||
template <typename Char, typename OutputIt, typename Arg,
|
template <typename Char, typename OutputIt, typename Arg,
|
||||||
FMT_ENABLE_IF(std::is_same<Arg, Char>::value)>
|
FMT_ENABLE_IF(std::is_same<Arg, Char>::value)>
|
||||||
OutputIt write_range_entry(OutputIt out, const Arg v) {
|
OutputIt write_range_entry(OutputIt out, const Arg v) {
|
||||||
*out++ = '\'';
|
return write_escaped_char(out, v);
|
||||||
*out++ = v;
|
|
||||||
*out++ = '\'';
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
|
@ -171,7 +171,7 @@ def main():
|
|||||||
normal1 = compress_normal(normal1)
|
normal1 = compress_normal(normal1)
|
||||||
|
|
||||||
print("""\
|
print("""\
|
||||||
inline auto is_printable(uint32_t cp) -> bool {\
|
FMT_FUNC auto is_printable(uint32_t cp) -> bool {\
|
||||||
""")
|
""")
|
||||||
print_singletons(singletons0u, singletons0l, 'singletons0', 'singletons0_lower')
|
print_singletons(singletons0u, singletons0l, 'singletons0', 'singletons0_lower')
|
||||||
print_singletons(singletons1u, singletons1l, 'singletons1', 'singletons1_lower')
|
print_singletons(singletons1u, singletons1l, 'singletons1', 'singletons1_lower')
|
||||||
|
@ -1060,7 +1060,7 @@ TEST(format_test, format_short) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void check_unknown_types(const T& value, const char* types, const char*) {
|
void check_unknown_types(const T& value, const char* types, const char*) {
|
||||||
char format_str[buffer_size];
|
char format_str[buffer_size];
|
||||||
const char* special = ".0123456789L}";
|
const char* special = ".0123456789L?}";
|
||||||
for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) {
|
for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) {
|
||||||
char c = static_cast<char>(i);
|
char c = static_cast<char>(i);
|
||||||
if (std::strchr(types, c) || std::strchr(special, c) || !c) continue;
|
if (std::strchr(types, c) || std::strchr(special, c) || !c) continue;
|
||||||
@ -1363,6 +1363,9 @@ TEST(format_test, format_char) {
|
|||||||
<< format_str;
|
<< format_str;
|
||||||
}
|
}
|
||||||
EXPECT_EQ(fmt::format("{:02X}", n), fmt::format("{:02X}", 'x'));
|
EXPECT_EQ(fmt::format("{:02X}", n), fmt::format("{:02X}", 'x'));
|
||||||
|
|
||||||
|
EXPECT_EQ("\n", fmt::format("{}", '\n'));
|
||||||
|
EXPECT_EQ("'\\n'", fmt::format("{:?}", '\n'));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(format_test, format_volatile_char) {
|
TEST(format_test, format_volatile_char) {
|
||||||
@ -1417,12 +1420,17 @@ TEST(format_test, format_enum_class) {
|
|||||||
|
|
||||||
TEST(format_test, format_string) {
|
TEST(format_test, format_string) {
|
||||||
EXPECT_EQ(fmt::format("{0}", std::string("test")), "test");
|
EXPECT_EQ(fmt::format("{0}", std::string("test")), "test");
|
||||||
|
EXPECT_EQ(fmt::format("{0}", std::string("test")), "test");
|
||||||
|
EXPECT_EQ(fmt::format("{:?}", std::string("test")), "\"test\"");
|
||||||
|
EXPECT_EQ(fmt::format("{:*^10?}", std::string("test")), "**\"test\"**");
|
||||||
|
EXPECT_EQ(fmt::format("{:?}", std::string("\test")), "\"\\test\"");
|
||||||
EXPECT_THROW((void)fmt::format(fmt::runtime("{:x}"), std::string("test")),
|
EXPECT_THROW((void)fmt::format(fmt::runtime("{:x}"), std::string("test")),
|
||||||
fmt::format_error);
|
fmt::format_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(format_test, format_string_view) {
|
TEST(format_test, format_string_view) {
|
||||||
EXPECT_EQ("test", fmt::format("{}", string_view("test")));
|
EXPECT_EQ("test", fmt::format("{}", string_view("test")));
|
||||||
|
EXPECT_EQ("\"t\\nst\"", fmt::format("{:?}", string_view("t\nst")));
|
||||||
EXPECT_EQ("", fmt::format("{}", string_view()));
|
EXPECT_EQ("", fmt::format("{}", string_view()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user