diff --git a/include/fmt/format.h b/include/fmt/format.h index bed75195..6c2831e0 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -752,12 +752,11 @@ template struct allocator : private std::decay { void deallocate(T* p, size_t) { std::free(p); } - FMT_CONSTEXPR20 friend bool operator==(allocator, allocator) noexcept { + constexpr friend auto operator==(allocator, allocator) noexcept -> bool { return true; // All instances of this allocator are equivalent. } - - FMT_CONSTEXPR20 friend bool operator!=(allocator a, allocator b) noexcept { - return !(a == b); + constexpr friend auto operator!=(allocator, allocator) noexcept -> bool { + return false; } }; @@ -834,42 +833,32 @@ class basic_memory_buffer : public detail::buffer { FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); } private: - template - FMT_CONSTEXPR20 - typename std::enable_if:: - propagate_on_container_move_assignment::value, - bool>::type - allocator_move_impl(basic_memory_buffer& other) { + template :: + propagate_on_container_move_assignment::value)> + FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool { alloc_ = std::move(other.alloc_); return true; } - // If the allocator does not propagate, - // then copy the content from source buffer. - template - FMT_CONSTEXPR20 - typename std::enable_if:: - propagate_on_container_move_assignment::value, - bool>::type - allocator_move_impl(basic_memory_buffer& other) { + // If the allocator does not propagate then copy the data from other. + template :: + propagate_on_container_move_assignment::value)> + FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool { T* data = other.data(); - if (alloc_ != other.alloc_ && data != other.store_) { - size_t size = other.size(); - // Perform copy operation, allocators are different - this->resize(size); - detail::copy(data, data + size, this->data()); - return false; - } - return true; + if (alloc_ == other.alloc_ || data == other.store_) return true; + size_t size = other.size(); + // Perform copy operation, allocators are different. + this->resize(size); + detail::copy(data, data + size, this->data()); + return false; } // Move data from other to this buffer. FMT_CONSTEXPR20 void move(basic_memory_buffer& other) { T* data = other.data(); size_t size = other.size(), capacity = other.capacity(); - // Replicate the behaviour of std library containers - if (!allocator_move_impl(other)) { - return; - } + if (!move_alloc(other)) return; if (data == other.store_) { this->set(store_, capacity); detail::copy(other.store_, other.store_ + size, store_); diff --git a/test/format-test.cc b/test/format-test.cc index a835bd16..cb6a87c3 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -307,7 +307,7 @@ TEST(memory_buffer_test, ctor) { EXPECT_EQ(123u, buffer.capacity()); } -using std_allocator = allocator_ref, true>; +using std_allocator = allocator_ref>; TEST(memory_buffer_test, move_ctor_inline_buffer) { auto check_move_buffer = @@ -351,15 +351,15 @@ TEST(memory_buffer_test, move_ctor_dynamic_buffer) { EXPECT_GT(buffer2.capacity(), 4u); } -using std_allocator_n = allocator_ref, false>; +using std_allocator_noprop = allocator_ref, false>; TEST(memory_buffer_test, move_ctor_inline_buffer_non_propagating) { auto check_move_buffer = [](const char* str, - basic_memory_buffer& buffer) { + basic_memory_buffer& buffer) { std::allocator* original_alloc_ptr = buffer.get_allocator().get(); const char* original_data_ptr = &buffer[0]; - basic_memory_buffer buffer2( + basic_memory_buffer buffer2( std::move(buffer)); const char* new_data_ptr = &buffer2[0]; EXPECT_NE(original_data_ptr, new_data_ptr); @@ -373,8 +373,8 @@ TEST(memory_buffer_test, move_ctor_inline_buffer_non_propagating) { EXPECT_NE(original_alloc_ptr, buffer2.get_allocator().get()); }; auto alloc = std::allocator(); - basic_memory_buffer buffer( - (std_allocator_n(&alloc))); + basic_memory_buffer buffer( + (std_allocator_noprop(&alloc))); const char test[] = "test"; buffer.append(string_view(test, 4)); check_move_buffer("test", buffer); @@ -384,15 +384,15 @@ TEST(memory_buffer_test, move_ctor_inline_buffer_non_propagating) { TEST(memory_buffer_test, move_ctor_dynamic_buffer_non_propagating) { auto alloc = std::allocator(); - basic_memory_buffer buffer( - (std_allocator_n(&alloc))); + basic_memory_buffer buffer( + (std_allocator_noprop(&alloc))); const char test[] = "test"; buffer.append(test, test + 4); const char* inline_buffer_ptr = &buffer[0]; buffer.push_back('a'); EXPECT_NE(&buffer[0], inline_buffer_ptr); std::allocator* original_alloc_ptr = buffer.get_allocator().get(); - basic_memory_buffer buffer2; + basic_memory_buffer buffer2; buffer2 = std::move(buffer); EXPECT_EQ(std::string(&buffer2[0], buffer2.size()), "testa"); EXPECT_GT(buffer2.capacity(), 4u); diff --git a/test/mock-allocator.h b/test/mock-allocator.h index 868cf6cb..0bf015a4 100644 --- a/test/mock-allocator.h +++ b/test/mock-allocator.h @@ -37,8 +37,7 @@ template class mock_allocator { MOCK_METHOD(void, deallocate, (T*, size_t)); }; -template -class allocator_ref { +template class allocator_ref { private: Allocator* alloc_; @@ -50,8 +49,7 @@ class allocator_ref { public: using value_type = typename Allocator::value_type; using propagate_on_container_move_assignment = - typename std::conditional::type; + fmt::bool_constant; explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {} @@ -70,23 +68,19 @@ class allocator_ref { } public: - Allocator* get() const { return alloc_; } + auto get() const -> Allocator* { return alloc_; } - value_type* allocate(size_t n) { + auto allocate(size_t n) -> value_type* { return std::allocator_traits::allocate(*alloc_, n); } void deallocate(value_type* p, size_t n) { alloc_->deallocate(p, n); } - FMT_CONSTEXPR20 friend bool operator==(const allocator_ref& a, - const allocator_ref& b) noexcept { + friend auto operator==(allocator_ref a, allocator_ref b) noexcept -> bool { if (a.alloc_ == b.alloc_) return true; - if (a.alloc_ == nullptr || b.alloc_ == nullptr) return false; - - return *a.alloc_ == *b.alloc_; + return a.alloc_ && b.alloc_ && *a.alloc_ == *b.alloc_; } - FMT_CONSTEXPR20 friend bool operator!=(const allocator_ref& a, - const allocator_ref& b) noexcept { + friend auto operator!=(allocator_ref a, allocator_ref b) noexcept -> bool { return !(a == b); } };