From d23f4f2669b82d7cef34678f8782ff7584d5a149 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 10 Jan 2024 19:34:31 -0800 Subject: [PATCH] Remove memory dependency --- include/fmt/base.h | 17 ++++++++++++++++- include/fmt/format.h | 28 +++------------------------- include/fmt/std.h | 8 ++++++++ test/format-test.cc | 13 ------------- test/std-test.cc | 18 ++++++++++++++++++ 5 files changed, 45 insertions(+), 39 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index da017d3e20e53..56378b2c61f9d 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -863,7 +863,22 @@ template class buffer { } /** Appends data to the end of the buffer. */ - template void append(const U* begin, const U* end); + template void append(const U* begin, const U* end) { + while (begin != end) { + auto count = to_unsigned(end - begin); + try_reserve(size_ + count); + auto free_cap = capacity_ - size_; + if (free_cap < count) count = free_cap; + if (std::is_same::value) { + memcpy(ptr_ + size_, begin, count * sizeof(T)); + } else { + T* out = ptr_ + size_; + for (size_t i = 0; i < count; ++i) out[i] = begin[i]; + } + size_ += count; + begin += count; + } + } template FMT_CONSTEXPR auto operator[](Idx index) -> T& { return ptr_[index]; diff --git a/include/fmt/format.h b/include/fmt/format.h index 37508fb14064d..6b73598c1dbc7 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -43,9 +43,8 @@ #include // std::memcpy #include // std::initializer_list #include // std::numeric_limits -#include // std::uninitialized_copy_n #include // std::runtime_error -#include // std::basic_string +#include // std::string #include // std::system_error #ifdef __cpp_lib_bit_cast @@ -861,20 +860,6 @@ using is_double_double = bool_constant::digits == 106>; # define FMT_USE_FULL_CACHE_DRAGONBOX 0 #endif -template -template -void buffer::append(const U* begin, const U* end) { - while (begin != end) { - 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, ptr_ + size_); - size_ += count; - begin += count; - } -} - template struct is_locale : std::false_type {}; template @@ -940,7 +925,7 @@ class basic_memory_buffer : public detail::buffer { // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481). detail::assume(buf.size() <= new_capacity); // The following code doesn't throw, so the raw pointer above doesn't leak. - std::uninitialized_copy_n(old_data, buf.size(), new_data); + memcpy(new_data, old_data, buf.size() * sizeof(T)); self.set(new_data, new_capacity); // deallocate must not throw according to the standard, but even if it does, // the buffer already uses the new storage and will deallocate it in @@ -3088,7 +3073,7 @@ class bigint { bigits_.resize(to_unsigned(num_bigits + exp_difference)); for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) bigits_[j] = bigits_[i]; - std::uninitialized_fill_n(bigits_.data(), exp_difference, 0u); + memset(bigits_.data(), 0, to_unsigned(exp_difference) * sizeof(bigit)); exp_ -= exp_difference; } @@ -4141,13 +4126,6 @@ template auto ptr(T p) -> const void* { static_assert(std::is_pointer::value, ""); return detail::bit_cast(p); } -template -auto ptr(const std::unique_ptr& p) -> const void* { - return p.get(); -} -template auto ptr(const std::shared_ptr& p) -> const void* { - return p.get(); -} /** \rst diff --git a/include/fmt/std.h b/include/fmt/std.h index d8f30a192d671..205e6dd104a2e 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -509,6 +509,14 @@ struct formatter +auto ptr(const std::unique_ptr& p) -> const void* { + return p.get(); +} +template auto ptr(const std::shared_ptr& p) -> const void* { + return p.get(); +} + FMT_EXPORT template struct formatter, Char, diff --git a/test/format-test.cc b/test/format-test.cc index 223fb1b3ce10a..3e53147d3f681 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -20,7 +20,6 @@ #include // std::strlen #include // std::back_inserter #include // std::list -#include // std::unique_ptr #include // std::is_default_constructible #include "gtest-extra.h" @@ -1540,18 +1539,6 @@ TEST(format_test, format_pointer) { fmt::format("{0}", reinterpret_cast(~uintptr_t()))); EXPECT_EQ("0x1234", fmt::format("{}", fmt::ptr(reinterpret_cast(0x1234)))); - std::unique_ptr up(new int(1)); - EXPECT_EQ(fmt::format("{}", fmt::ptr(up.get())), - fmt::format("{}", fmt::ptr(up))); - struct custom_deleter { - void operator()(int* p) const { delete p; } - }; - std::unique_ptr upcd(new int(1)); - EXPECT_EQ(fmt::format("{}", fmt::ptr(upcd.get())), - fmt::format("{}", fmt::ptr(upcd))); - std::shared_ptr sp(new int(1)); - EXPECT_EQ(fmt::format("{}", fmt::ptr(sp.get())), - fmt::format("{}", fmt::ptr(sp))); EXPECT_EQ(fmt::format("{}", fmt::detail::bit_cast( &function_pointer_test)), fmt::format("{}", fmt::ptr(function_pointer_test))); diff --git a/test/std-test.cc b/test/std-test.cc index de3feaa051b90..f5566848e023b 100644 --- a/test/std-test.cc +++ b/test/std-test.cc @@ -304,3 +304,21 @@ TEST(std_test, format_atomic_flag) { EXPECT_EQ(fmt::format("{}", cf), "false"); } #endif // __cpp_lib_atomic_flag_test + +TEST(std_test, format_unique_ptr) { + std::unique_ptr up(new int(1)); + EXPECT_EQ(fmt::format("{}", fmt::ptr(up.get())), + fmt::format("{}", fmt::ptr(up))); + struct custom_deleter { + void operator()(int* p) const { delete p; } + }; + std::unique_ptr upcd(new int(1)); + EXPECT_EQ(fmt::format("{}", fmt::ptr(upcd.get())), + fmt::format("{}", fmt::ptr(upcd))); +} + +TEST(std_test, format_shared_ptr) { + std::shared_ptr sp(new int(1)); + EXPECT_EQ(fmt::format("{}", fmt::ptr(sp.get())), + fmt::format("{}", fmt::ptr(sp))); +}