mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-09 21:00:06 +00:00
Make append work with fixed-size buffer
This commit is contained in:
parent
e8ec09ae83
commit
d870468159
@ -1811,9 +1811,9 @@ OutputIt vformat_to(
|
||||
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||
auto& c = detail::get_container(out);
|
||||
using container = remove_reference_t<decltype(c)>;
|
||||
typename std::conditional<
|
||||
std::is_same<container, detail::buffer<Char>>::value,
|
||||
detail::buffer<Char>&, detail::container_buffer<container>>::type buf(c);
|
||||
conditional_t<std::is_same<container, detail::buffer<Char>>::value,
|
||||
detail::buffer<Char>&, detail::container_buffer<container>>
|
||||
buf(c);
|
||||
detail::vformat_to(buf, to_string_view(format_str), args);
|
||||
return out;
|
||||
}
|
||||
|
@ -571,11 +571,15 @@ template <typename T> constexpr bool use_grisu() {
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void buffer<T>::append(const U* begin, const U* end) {
|
||||
size_t new_size = size_ + to_unsigned(end - begin);
|
||||
try_reserve(new_size);
|
||||
std::uninitialized_copy(begin, end,
|
||||
make_checked(ptr_ + size_, capacity_ - size_));
|
||||
size_ = new_size;
|
||||
do {
|
||||
auto count = to_unsigned(end - begin);
|
||||
try_reserve(size_ + count);
|
||||
auto free_cap = capacity_ - size_;
|
||||
if (free_cap < count) count = free_cap;
|
||||
std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
|
||||
size_ += count;
|
||||
begin += count;
|
||||
} while (begin != end);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
|
@ -35,6 +35,7 @@ using fmt::detail::make_arg;
|
||||
using fmt::detail::value;
|
||||
|
||||
using testing::_;
|
||||
using testing::Invoke;
|
||||
using testing::Return;
|
||||
using testing::StrictMock;
|
||||
|
||||
@ -84,9 +85,9 @@ template <typename T> struct mock_buffer : buffer<T> {
|
||||
|
||||
mock_buffer(T* data = nullptr, size_t capacity = 0) {
|
||||
this->set(data, capacity);
|
||||
ON_CALL(*this, do_grow(_))
|
||||
.WillByDefault(
|
||||
testing::Invoke([](size_t capacity) { return capacity; }));
|
||||
ON_CALL(*this, do_grow(_)).WillByDefault(Invoke([](size_t capacity) {
|
||||
return capacity;
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -178,6 +179,20 @@ TEST(BufferTest, Append) {
|
||||
EXPECT_EQ(12u, buffer.size());
|
||||
}
|
||||
|
||||
TEST(BufferTest, AppendPartial) {
|
||||
char data[10];
|
||||
mock_buffer<char> buffer(data, sizeof(data));
|
||||
testing::InSequence seq;
|
||||
EXPECT_CALL(buffer, do_grow(15)).WillOnce(Return(10));
|
||||
EXPECT_CALL(buffer, do_grow(15)).WillOnce(Invoke([&buffer](size_t) {
|
||||
EXPECT_EQ(fmt::string_view(buffer.data(), buffer.size()), "0123456789");
|
||||
buffer.clear();
|
||||
return 10;
|
||||
}));
|
||||
auto test = "0123456789abcde";
|
||||
buffer.append(test, test + 15);
|
||||
}
|
||||
|
||||
TEST(BufferTest, AppendAllocatesEnoughStorage) {
|
||||
char data[19];
|
||||
mock_buffer<char> buffer(data, 10);
|
||||
@ -292,10 +307,10 @@ VISIT_TYPE(unsigned long, unsigned long long);
|
||||
|
||||
template <typename T> class NumericArgTest : public testing::Test {};
|
||||
|
||||
using types = ::testing::Types<bool, signed char, unsigned char, signed,
|
||||
unsigned short, int, unsigned, long, unsigned long,
|
||||
long long, unsigned long long, float, double,
|
||||
long double>;
|
||||
using types =
|
||||
::testing::Types<bool, signed char, unsigned char, signed, unsigned short,
|
||||
int, unsigned, long, unsigned long, long long,
|
||||
unsigned long long, float, double, long double>;
|
||||
TYPED_TEST_CASE(NumericArgTest, types);
|
||||
|
||||
template <typename T>
|
||||
@ -372,7 +387,7 @@ TEST(ArgTest, CustomArg) {
|
||||
using visitor =
|
||||
mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>;
|
||||
testing::StrictMock<visitor> v;
|
||||
EXPECT_CALL(v, visit(_)).WillOnce(testing::Invoke(check_custom()));
|
||||
EXPECT_CALL(v, visit(_)).WillOnce(Invoke(check_custom()));
|
||||
fmt::visit_format_arg(v, make_arg<fmt::format_context>(test));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user