mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Cleanup base-test
This commit is contained in:
@ -11,8 +11,9 @@
|
|||||||
|
|
||||||
#include "fmt/base.h"
|
#include "fmt/base.h"
|
||||||
|
|
||||||
#include <climits> // INT_MAX
|
#include <limits.h> // INT_MAX
|
||||||
#include <cstring> // std::strlen
|
#include <string.h> // strlen
|
||||||
|
|
||||||
#include <functional> // std::equal_to
|
#include <functional> // std::equal_to
|
||||||
#include <iterator> // std::back_insert_iterator, std::distance
|
#include <iterator> // std::back_insert_iterator, std::distance
|
||||||
#include <limits> // std::numeric_limits
|
#include <limits> // std::numeric_limits
|
||||||
@ -21,7 +22,6 @@
|
|||||||
|
|
||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
using fmt::string_view;
|
|
||||||
using fmt::detail::buffer;
|
using fmt::detail::buffer;
|
||||||
|
|
||||||
using testing::_;
|
using testing::_;
|
||||||
@ -29,31 +29,31 @@ using testing::Invoke;
|
|||||||
using testing::Return;
|
using testing::Return;
|
||||||
|
|
||||||
#ifdef FMT_FORMAT_H_
|
#ifdef FMT_FORMAT_H_
|
||||||
# error core-test includes format.h
|
# error base-test includes format.h
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fmt::appender copy(fmt::string_view s, fmt::appender out) {
|
auto copy(fmt::string_view s, fmt::appender out) -> fmt::appender {
|
||||||
for (char c : s) *out++ = c;
|
for (char c : s) *out++ = c;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(string_view_test, value_type) {
|
TEST(string_view_test, value_type) {
|
||||||
static_assert(std::is_same<string_view::value_type, char>::value, "");
|
static_assert(std::is_same<fmt::string_view::value_type, char>::value, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(string_view_test, ctor) {
|
TEST(string_view_test, ctor) {
|
||||||
EXPECT_STREQ("abc", fmt::string_view("abc").data());
|
EXPECT_STREQ(fmt::string_view("abc").data(), "abc");
|
||||||
EXPECT_EQ(3u, fmt::string_view("abc").size());
|
EXPECT_EQ(fmt::string_view("abc").size(), 3u);
|
||||||
|
|
||||||
EXPECT_STREQ("defg", fmt::string_view(std::string("defg")).data());
|
EXPECT_STREQ(fmt::string_view(std::string("defg")).data(), "defg");
|
||||||
EXPECT_EQ(4u, fmt::string_view(std::string("defg")).size());
|
EXPECT_EQ(fmt::string_view(std::string("defg")).size(), 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(string_view_test, length) {
|
TEST(string_view_test, length) {
|
||||||
// Test that string_view::size() returns string length, not buffer size.
|
// Test that string_view::size() returns string length, not buffer size.
|
||||||
char str[100] = "some string";
|
char str[100] = "some string";
|
||||||
EXPECT_EQ(std::strlen(str), string_view(str).size());
|
EXPECT_EQ(fmt::string_view(str).size(), strlen(str));
|
||||||
EXPECT_LT(std::strlen(str), sizeof(str));
|
EXPECT_LT(strlen(str), sizeof(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check string_view's comparison operator.
|
// Check string_view's comparison operator.
|
||||||
@ -62,13 +62,16 @@ template <template <typename> class Op> void check_op() {
|
|||||||
size_t num_inputs = sizeof(inputs) / sizeof(*inputs);
|
size_t num_inputs = sizeof(inputs) / sizeof(*inputs);
|
||||||
for (size_t i = 0; i < num_inputs; ++i) {
|
for (size_t i = 0; i < num_inputs; ++i) {
|
||||||
for (size_t j = 0; j < num_inputs; ++j) {
|
for (size_t j = 0; j < num_inputs; ++j) {
|
||||||
string_view lhs(inputs[i]), rhs(inputs[j]);
|
fmt::string_view lhs(inputs[i]), rhs(inputs[j]);
|
||||||
EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<string_view>()(lhs, rhs));
|
EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0),
|
||||||
|
Op<fmt::string_view>()(lhs, rhs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(string_view_test, compare) {
|
TEST(string_view_test, compare) {
|
||||||
|
using fmt::string_view;
|
||||||
|
|
||||||
EXPECT_EQ(string_view("foo").compare(string_view("foo")), 0);
|
EXPECT_EQ(string_view("foo").compare(string_view("foo")), 0);
|
||||||
EXPECT_GT(string_view("fop").compare(string_view("foo")), 0);
|
EXPECT_GT(string_view("fop").compare(string_view("foo")), 0);
|
||||||
EXPECT_LT(string_view("foo").compare(string_view("fop")), 0);
|
EXPECT_LT(string_view("foo").compare(string_view("fop")), 0);
|
||||||
@ -108,30 +111,6 @@ TEST(string_view_test, from_constexpr_fixed_string) {
|
|||||||
}
|
}
|
||||||
#endif // FMT_USE_CONSTEVAL
|
#endif // FMT_USE_CONSTEVAL
|
||||||
|
|
||||||
TEST(base_test, is_locking) {
|
|
||||||
EXPECT_FALSE(fmt::detail::is_locking<const char(&)[3]>());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(base_test, is_output_iterator) {
|
|
||||||
EXPECT_TRUE((fmt::detail::is_output_iterator<char*, char>::value));
|
|
||||||
EXPECT_FALSE((fmt::detail::is_output_iterator<const char*, char>::value));
|
|
||||||
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string, char>::value));
|
|
||||||
EXPECT_TRUE(
|
|
||||||
(fmt::detail::is_output_iterator<std::back_insert_iterator<std::string>,
|
|
||||||
char>::value));
|
|
||||||
EXPECT_TRUE(
|
|
||||||
(fmt::detail::is_output_iterator<std::string::iterator, char>::value));
|
|
||||||
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string::const_iterator,
|
|
||||||
char>::value));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(base_test, is_back_insert_iterator) {
|
|
||||||
EXPECT_TRUE(fmt::detail::is_back_insert_iterator<
|
|
||||||
std::back_insert_iterator<std::string>>::value);
|
|
||||||
EXPECT_FALSE(fmt::detail::is_back_insert_iterator<
|
|
||||||
std::front_insert_iterator<std::string>>::value);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470
|
#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470
|
||||||
TEST(buffer_test, noncopyable) {
|
TEST(buffer_test, noncopyable) {
|
||||||
EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value);
|
EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value);
|
||||||
@ -174,24 +153,24 @@ template <typename T> struct mock_buffer final : buffer<T> {
|
|||||||
TEST(buffer_test, ctor) {
|
TEST(buffer_test, ctor) {
|
||||||
{
|
{
|
||||||
mock_buffer<int> buffer;
|
mock_buffer<int> buffer;
|
||||||
EXPECT_EQ(nullptr, buffer.data());
|
EXPECT_EQ(buffer.data(), nullptr);
|
||||||
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
|
EXPECT_EQ(buffer.size(), 0u);
|
||||||
EXPECT_EQ(static_cast<size_t>(0), buffer.capacity());
|
EXPECT_EQ(buffer.capacity(), 0u);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int dummy;
|
int data;
|
||||||
mock_buffer<int> buffer(&dummy);
|
mock_buffer<int> buffer(&data);
|
||||||
EXPECT_EQ(&dummy, &buffer[0]);
|
EXPECT_EQ(&buffer[0], &data);
|
||||||
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
|
EXPECT_EQ(buffer.size(), 0u);
|
||||||
EXPECT_EQ(static_cast<size_t>(0), buffer.capacity());
|
EXPECT_EQ(buffer.capacity(), 0u);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int dummy;
|
int data;
|
||||||
size_t capacity = std::numeric_limits<size_t>::max();
|
size_t capacity = std::numeric_limits<size_t>::max();
|
||||||
mock_buffer<int> buffer(&dummy, capacity);
|
mock_buffer<int> buffer(&data, capacity);
|
||||||
EXPECT_EQ(&dummy, &buffer[0]);
|
EXPECT_EQ(&buffer[0], &data);
|
||||||
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
|
EXPECT_EQ(buffer.size(), 0u);
|
||||||
EXPECT_EQ(capacity, buffer.capacity());
|
EXPECT_EQ(buffer.capacity(), capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,26 +178,26 @@ TEST(buffer_test, access) {
|
|||||||
char data[10];
|
char data[10];
|
||||||
mock_buffer<char> buffer(data, sizeof(data));
|
mock_buffer<char> buffer(data, sizeof(data));
|
||||||
buffer[0] = 11;
|
buffer[0] = 11;
|
||||||
EXPECT_EQ(11, buffer[0]);
|
EXPECT_EQ(buffer[0], 11);
|
||||||
buffer[3] = 42;
|
buffer[3] = 42;
|
||||||
EXPECT_EQ(42, *(&buffer[0] + 3));
|
EXPECT_EQ(*(&buffer[0] + 3), 42);
|
||||||
const fmt::detail::buffer<char>& const_buffer = buffer;
|
const fmt::detail::buffer<char>& const_buffer = buffer;
|
||||||
EXPECT_EQ(42, const_buffer[3]);
|
EXPECT_EQ(const_buffer[3], 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(buffer_test, try_resize) {
|
TEST(buffer_test, try_resize) {
|
||||||
char data[123];
|
char data[123];
|
||||||
mock_buffer<char> buffer(data, sizeof(data));
|
mock_buffer<char> buffer(data, sizeof(data));
|
||||||
buffer[10] = 42;
|
buffer[10] = 42;
|
||||||
EXPECT_EQ(42, buffer[10]);
|
EXPECT_EQ(buffer[10], 42);
|
||||||
buffer.try_resize(20);
|
buffer.try_resize(20);
|
||||||
EXPECT_EQ(20u, buffer.size());
|
EXPECT_EQ(buffer.size(), 20u);
|
||||||
EXPECT_EQ(123u, buffer.capacity());
|
EXPECT_EQ(buffer.capacity(), 123u);
|
||||||
EXPECT_EQ(42, buffer[10]);
|
EXPECT_EQ(buffer[10], 42);
|
||||||
buffer.try_resize(5);
|
buffer.try_resize(5);
|
||||||
EXPECT_EQ(5u, buffer.size());
|
EXPECT_EQ(buffer.size(), 5u);
|
||||||
EXPECT_EQ(123u, buffer.capacity());
|
EXPECT_EQ(buffer.capacity(), 123u);
|
||||||
EXPECT_EQ(42, buffer[10]);
|
EXPECT_EQ(buffer[10], 42);
|
||||||
// Check if try_resize calls grow.
|
// Check if try_resize calls grow.
|
||||||
EXPECT_CALL(buffer, do_grow(124));
|
EXPECT_CALL(buffer, do_grow(124));
|
||||||
buffer.try_resize(124);
|
buffer.try_resize(124);
|
||||||
@ -240,8 +219,8 @@ TEST(buffer_test, clear) {
|
|||||||
EXPECT_CALL(buffer, do_grow(20));
|
EXPECT_CALL(buffer, do_grow(20));
|
||||||
buffer.try_resize(20);
|
buffer.try_resize(20);
|
||||||
buffer.try_resize(0);
|
buffer.try_resize(0);
|
||||||
EXPECT_EQ(static_cast<size_t>(0), buffer.size());
|
EXPECT_EQ(buffer.size(), 0u);
|
||||||
EXPECT_EQ(20u, buffer.capacity());
|
EXPECT_EQ(buffer.capacity(), 20u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(buffer_test, append) {
|
TEST(buffer_test, append) {
|
||||||
@ -249,14 +228,14 @@ TEST(buffer_test, append) {
|
|||||||
mock_buffer<char> buffer(data, 10);
|
mock_buffer<char> buffer(data, 10);
|
||||||
auto test = "test";
|
auto test = "test";
|
||||||
buffer.append(test, test + 5);
|
buffer.append(test, test + 5);
|
||||||
EXPECT_STREQ(test, &buffer[0]);
|
EXPECT_STREQ(&buffer[0], test);
|
||||||
EXPECT_EQ(5u, buffer.size());
|
EXPECT_EQ(buffer.size(), 5u);
|
||||||
buffer.try_resize(10);
|
buffer.try_resize(10);
|
||||||
EXPECT_CALL(buffer, do_grow(12));
|
EXPECT_CALL(buffer, do_grow(12));
|
||||||
buffer.append(test, test + 2);
|
buffer.append(test, test + 2);
|
||||||
EXPECT_EQ('t', buffer[10]);
|
EXPECT_EQ(buffer[10], 't');
|
||||||
EXPECT_EQ('e', buffer[11]);
|
EXPECT_EQ(buffer[11], 'e');
|
||||||
EXPECT_EQ(12u, buffer.size());
|
EXPECT_EQ(buffer.size(), 12u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(buffer_test, append_partial) {
|
TEST(buffer_test, append_partial) {
|
||||||
@ -282,6 +261,30 @@ TEST(buffer_test, append_allocates_enough_storage) {
|
|||||||
buffer.append(test, test + 9);
|
buffer.append(test, test + 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(base_test, is_locking) {
|
||||||
|
EXPECT_FALSE(fmt::detail::is_locking<const char(&)[3]>());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(base_test, is_output_iterator) {
|
||||||
|
EXPECT_TRUE((fmt::detail::is_output_iterator<char*, char>::value));
|
||||||
|
EXPECT_FALSE((fmt::detail::is_output_iterator<const char*, char>::value));
|
||||||
|
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string, char>::value));
|
||||||
|
EXPECT_TRUE(
|
||||||
|
(fmt::detail::is_output_iterator<std::back_insert_iterator<std::string>,
|
||||||
|
char>::value));
|
||||||
|
EXPECT_TRUE(
|
||||||
|
(fmt::detail::is_output_iterator<std::string::iterator, char>::value));
|
||||||
|
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string::const_iterator,
|
||||||
|
char>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(base_test, is_back_insert_iterator) {
|
||||||
|
EXPECT_TRUE(fmt::detail::is_back_insert_iterator<
|
||||||
|
std::back_insert_iterator<std::string>>::value);
|
||||||
|
EXPECT_FALSE(fmt::detail::is_back_insert_iterator<
|
||||||
|
std::front_insert_iterator<std::string>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(base_test, get_buffer) {
|
TEST(base_test, get_buffer) {
|
||||||
mock_buffer<char> buffer;
|
mock_buffer<char> buffer;
|
||||||
void* buffer_ptr = &buffer;
|
void* buffer_ptr = &buffer;
|
||||||
@ -444,7 +447,7 @@ struct check_custom {
|
|||||||
auto parse_ctx = fmt::format_parse_context("");
|
auto parse_ctx = fmt::format_parse_context("");
|
||||||
auto ctx = fmt::format_context(fmt::appender(buffer), fmt::format_args());
|
auto ctx = fmt::format_context(fmt::appender(buffer), fmt::format_args());
|
||||||
h.format(parse_ctx, ctx);
|
h.format(parse_ctx, ctx);
|
||||||
EXPECT_EQ("test", std::string(buffer.data, buffer.size()));
|
EXPECT_EQ(std::string(buffer.data, buffer.size()), "test");
|
||||||
return test_result();
|
return test_result();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -470,14 +473,14 @@ enum class arg_id_result { none, index, name };
|
|||||||
struct test_arg_id_handler {
|
struct test_arg_id_handler {
|
||||||
arg_id_result res = arg_id_result::none;
|
arg_id_result res = arg_id_result::none;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
string_view name;
|
fmt::string_view name;
|
||||||
|
|
||||||
constexpr void on_index(int i) {
|
constexpr void on_index(int i) {
|
||||||
res = arg_id_result::index;
|
res = arg_id_result::index;
|
||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void on_name(string_view n) {
|
constexpr void on_name(fmt::string_view n) {
|
||||||
res = arg_id_result::name;
|
res = arg_id_result::name;
|
||||||
name = n;
|
name = n;
|
||||||
}
|
}
|
||||||
@ -700,46 +703,46 @@ TEST(base_test, format_to) {
|
|||||||
TEST(base_test, format_to_array) {
|
TEST(base_test, format_to_array) {
|
||||||
char buffer[4];
|
char buffer[4];
|
||||||
auto result = fmt::format_to(buffer, "{}", 12345);
|
auto result = fmt::format_to(buffer, "{}", 12345);
|
||||||
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
|
EXPECT_EQ(std::distance(&buffer[0], result.out), 4);
|
||||||
EXPECT_TRUE(result.truncated);
|
EXPECT_TRUE(result.truncated);
|
||||||
EXPECT_EQ(buffer + 4, result.out);
|
EXPECT_EQ(result.out, buffer + 4);
|
||||||
EXPECT_EQ("1234", fmt::string_view(buffer, 4));
|
EXPECT_EQ(fmt::string_view(buffer, 4), "1234");
|
||||||
|
|
||||||
char* out = nullptr;
|
char* out = nullptr;
|
||||||
EXPECT_THROW(out = result, std::runtime_error);
|
EXPECT_THROW(out = result, std::runtime_error);
|
||||||
(void)out;
|
(void)out;
|
||||||
|
|
||||||
result = fmt::format_to(buffer, "{:s}", "foobar");
|
result = fmt::format_to(buffer, "{:s}", "foobar");
|
||||||
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
|
EXPECT_EQ(std::distance(&buffer[0], result.out), 4);
|
||||||
EXPECT_TRUE(result.truncated);
|
EXPECT_TRUE(result.truncated);
|
||||||
EXPECT_EQ(buffer + 4, result.out);
|
EXPECT_EQ(result.out, buffer + 4);
|
||||||
EXPECT_EQ("foob", fmt::string_view(buffer, 4));
|
EXPECT_EQ(fmt::string_view(buffer, 4), "foob");
|
||||||
|
|
||||||
buffer[0] = 'x';
|
buffer[0] = 'x';
|
||||||
buffer[1] = 'x';
|
buffer[1] = 'x';
|
||||||
buffer[2] = 'x';
|
buffer[2] = 'x';
|
||||||
buffer[3] = 'x';
|
buffer[3] = 'x';
|
||||||
result = fmt::format_to(buffer, "{}", 'A');
|
result = fmt::format_to(buffer, "{}", 'A');
|
||||||
EXPECT_EQ(1, std::distance(&buffer[0], result.out));
|
EXPECT_EQ(std::distance(&buffer[0], result.out), 1);
|
||||||
EXPECT_FALSE(result.truncated);
|
EXPECT_FALSE(result.truncated);
|
||||||
EXPECT_EQ(buffer + 1, result.out);
|
EXPECT_EQ(result.out, buffer + 1);
|
||||||
EXPECT_EQ("Axxx", fmt::string_view(buffer, 4));
|
EXPECT_EQ(fmt::string_view(buffer, 4), "Axxx");
|
||||||
|
|
||||||
result = fmt::format_to(buffer, "{}{} ", 'B', 'C');
|
result = fmt::format_to(buffer, "{}{} ", 'B', 'C');
|
||||||
EXPECT_EQ(3, std::distance(&buffer[0], result.out));
|
EXPECT_EQ(std::distance(&buffer[0], result.out), 3);
|
||||||
EXPECT_FALSE(result.truncated);
|
EXPECT_FALSE(result.truncated);
|
||||||
EXPECT_EQ(buffer + 3, result.out);
|
EXPECT_EQ(result.out, buffer + 3);
|
||||||
EXPECT_EQ("BC x", fmt::string_view(buffer, 4));
|
EXPECT_EQ(fmt::string_view(buffer, 4), "BC x");
|
||||||
|
|
||||||
result = fmt::format_to(buffer, "{}", "ABCDE");
|
result = fmt::format_to(buffer, "{}", "ABCDE");
|
||||||
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
|
EXPECT_EQ(std::distance(&buffer[0], result.out), 4);
|
||||||
EXPECT_TRUE(result.truncated);
|
EXPECT_TRUE(result.truncated);
|
||||||
EXPECT_EQ("ABCD", fmt::string_view(buffer, 4));
|
EXPECT_EQ(fmt::string_view(buffer, 4), "ABCD");
|
||||||
|
|
||||||
result = fmt::format_to(buffer, "{}", std::string(1000, '*').c_str());
|
result = fmt::format_to(buffer, "{}", std::string(1000, '*').c_str());
|
||||||
EXPECT_EQ(4, std::distance(&buffer[0], result.out));
|
EXPECT_EQ(std::distance(&buffer[0], result.out), 4);
|
||||||
EXPECT_TRUE(result.truncated);
|
EXPECT_TRUE(result.truncated);
|
||||||
EXPECT_EQ("****", fmt::string_view(buffer, 4));
|
EXPECT_EQ(fmt::string_view(buffer, 4), "****");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that check is not found by ADL.
|
// Test that check is not found by ADL.
|
||||||
@ -828,7 +831,7 @@ TEST(base_test, throw_in_buffer_dtor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct its_a_trap {
|
struct convertible_to_any_type_with_member_x {
|
||||||
template <typename T> operator T() const {
|
template <typename T> operator T() const {
|
||||||
auto v = T();
|
auto v = T();
|
||||||
v.x = 42;
|
v.x = 42;
|
||||||
@ -837,12 +840,12 @@ struct its_a_trap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
template <> struct formatter<its_a_trap> {
|
template <> struct formatter<convertible_to_any_type_with_member_x> {
|
||||||
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
|
FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
|
||||||
return ctx.begin();
|
return ctx.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto format(its_a_trap, format_context& ctx) const
|
auto format(convertible_to_any_type_with_member_x, format_context& ctx) const
|
||||||
-> decltype(ctx.out()) const {
|
-> decltype(ctx.out()) const {
|
||||||
auto out = ctx.out();
|
auto out = ctx.out();
|
||||||
*out++ = 'x';
|
*out++ = 'x';
|
||||||
@ -851,9 +854,10 @@ template <> struct formatter<its_a_trap> {
|
|||||||
};
|
};
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
TEST(base_test, trappy_conversion) {
|
TEST(base_test, promiscuous_conversions) {
|
||||||
auto s = std::string();
|
auto s = std::string();
|
||||||
fmt::format_to(std::back_inserter(s), "{}", its_a_trap());
|
fmt::format_to(std::back_inserter(s), "{}",
|
||||||
|
convertible_to_any_type_with_member_x());
|
||||||
EXPECT_EQ(s, "x");
|
EXPECT_EQ(s, "x");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -878,14 +882,14 @@ TEST(base_test, format_to_custom_container) {
|
|||||||
fmt::format_to(std::back_inserter(c), "");
|
fmt::format_to(std::back_inserter(c), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nondeterministic_format_string {
|
|
||||||
mutable int i = 0;
|
|
||||||
FMT_CONSTEXPR operator string_view() const {
|
|
||||||
return string_view("{}", i++ != 0 ? 2 : 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(base_test, no_repeated_format_string_conversions) {
|
TEST(base_test, no_repeated_format_string_conversions) {
|
||||||
|
struct nondeterministic_format_string {
|
||||||
|
mutable int i = 0;
|
||||||
|
FMT_CONSTEXPR operator fmt::string_view() const {
|
||||||
|
return {"{}", i++ != 0 ? 2u : 0u};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#if !FMT_GCC_VERSION
|
#if !FMT_GCC_VERSION
|
||||||
char buf[10];
|
char buf[10];
|
||||||
fmt::format_to(buf, nondeterministic_format_string());
|
fmt::format_to(buf, nondeterministic_format_string());
|
||||||
@ -893,10 +897,8 @@ TEST(base_test, no_repeated_format_string_conversions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(base_test, format_context_accessors) {
|
TEST(base_test, format_context_accessors) {
|
||||||
class copier {
|
auto copy = [](fmt::appender app, const fmt::format_context& ctx) {
|
||||||
static fmt::format_context copy(fmt::appender app,
|
return fmt::format_context(app, ctx.args(), ctx.locale());
|
||||||
const fmt::format_context& ctx) {
|
|
||||||
return fmt::format_context(std::move(app), ctx.args(), ctx.locale());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
fmt::detail::ignore_unused(copy);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user