mirror of
https://github.com/fmtlib/fmt.git
synced 2025-09-28 23:50:54 +02:00
Minor cleanup
This commit is contained in:
@@ -752,12 +752,11 @@ template <typename T> struct allocator : private std::decay<void> {
|
|||||||
|
|
||||||
void deallocate(T* p, size_t) { std::free(p); }
|
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.
|
return true; // All instances of this allocator are equivalent.
|
||||||
}
|
}
|
||||||
|
constexpr friend auto operator!=(allocator, allocator) noexcept -> bool {
|
||||||
FMT_CONSTEXPR20 friend bool operator!=(allocator a, allocator b) noexcept {
|
return false;
|
||||||
return !(a == b);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -834,42 +833,32 @@ class basic_memory_buffer : public detail::buffer<T> {
|
|||||||
FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
|
FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Alloc = Allocator>
|
template <typename Alloc = Allocator,
|
||||||
FMT_CONSTEXPR20
|
FMT_ENABLE_IF(std::allocator_traits<Alloc>::
|
||||||
typename std::enable_if<std::allocator_traits<Alloc>::
|
propagate_on_container_move_assignment::value)>
|
||||||
propagate_on_container_move_assignment::value,
|
FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool {
|
||||||
bool>::type
|
|
||||||
allocator_move_impl(basic_memory_buffer& other) {
|
|
||||||
alloc_ = std::move(other.alloc_);
|
alloc_ = std::move(other.alloc_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// If the allocator does not propagate,
|
// If the allocator does not propagate then copy the data from other.
|
||||||
// then copy the content from source buffer.
|
template <typename Alloc = Allocator,
|
||||||
template <typename Alloc = Allocator>
|
FMT_ENABLE_IF(!std::allocator_traits<Alloc>::
|
||||||
FMT_CONSTEXPR20
|
propagate_on_container_move_assignment::value)>
|
||||||
typename std::enable_if<!std::allocator_traits<Alloc>::
|
FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool {
|
||||||
propagate_on_container_move_assignment::value,
|
|
||||||
bool>::type
|
|
||||||
allocator_move_impl(basic_memory_buffer& other) {
|
|
||||||
T* data = other.data();
|
T* data = other.data();
|
||||||
if (alloc_ != other.alloc_ && data != other.store_) {
|
if (alloc_ == other.alloc_ || data == other.store_) return true;
|
||||||
size_t size = other.size();
|
size_t size = other.size();
|
||||||
// Perform copy operation, allocators are different
|
// Perform copy operation, allocators are different.
|
||||||
this->resize(size);
|
this->resize(size);
|
||||||
detail::copy<T>(data, data + size, this->data());
|
detail::copy<T>(data, data + size, this->data());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move data from other to this buffer.
|
// Move data from other to this buffer.
|
||||||
FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
|
FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
|
||||||
T* data = other.data();
|
T* data = other.data();
|
||||||
size_t size = other.size(), capacity = other.capacity();
|
size_t size = other.size(), capacity = other.capacity();
|
||||||
// Replicate the behaviour of std library containers
|
if (!move_alloc(other)) return;
|
||||||
if (!allocator_move_impl(other)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (data == other.store_) {
|
if (data == other.store_) {
|
||||||
this->set(store_, capacity);
|
this->set(store_, capacity);
|
||||||
detail::copy<T>(other.store_, other.store_ + size, store_);
|
detail::copy<T>(other.store_, other.store_ + size, store_);
|
||||||
|
@@ -307,7 +307,7 @@ TEST(memory_buffer_test, ctor) {
|
|||||||
EXPECT_EQ(123u, buffer.capacity());
|
EXPECT_EQ(123u, buffer.capacity());
|
||||||
}
|
}
|
||||||
|
|
||||||
using std_allocator = allocator_ref<std::allocator<char>, true>;
|
using std_allocator = allocator_ref<std::allocator<char>>;
|
||||||
|
|
||||||
TEST(memory_buffer_test, move_ctor_inline_buffer) {
|
TEST(memory_buffer_test, move_ctor_inline_buffer) {
|
||||||
auto check_move_buffer =
|
auto check_move_buffer =
|
||||||
@@ -351,15 +351,15 @@ TEST(memory_buffer_test, move_ctor_dynamic_buffer) {
|
|||||||
EXPECT_GT(buffer2.capacity(), 4u);
|
EXPECT_GT(buffer2.capacity(), 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
using std_allocator_n = allocator_ref<std::allocator<char>, false>;
|
using std_allocator_noprop = allocator_ref<std::allocator<char>, false>;
|
||||||
|
|
||||||
TEST(memory_buffer_test, move_ctor_inline_buffer_non_propagating) {
|
TEST(memory_buffer_test, move_ctor_inline_buffer_non_propagating) {
|
||||||
auto check_move_buffer =
|
auto check_move_buffer =
|
||||||
[](const char* str,
|
[](const char* str,
|
||||||
basic_memory_buffer<char, 5, std_allocator_n>& buffer) {
|
basic_memory_buffer<char, 5, std_allocator_noprop>& buffer) {
|
||||||
std::allocator<char>* original_alloc_ptr = buffer.get_allocator().get();
|
std::allocator<char>* original_alloc_ptr = buffer.get_allocator().get();
|
||||||
const char* original_data_ptr = &buffer[0];
|
const char* original_data_ptr = &buffer[0];
|
||||||
basic_memory_buffer<char, 5, std_allocator_n> buffer2(
|
basic_memory_buffer<char, 5, std_allocator_noprop> buffer2(
|
||||||
std::move(buffer));
|
std::move(buffer));
|
||||||
const char* new_data_ptr = &buffer2[0];
|
const char* new_data_ptr = &buffer2[0];
|
||||||
EXPECT_NE(original_data_ptr, new_data_ptr);
|
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());
|
EXPECT_NE(original_alloc_ptr, buffer2.get_allocator().get());
|
||||||
};
|
};
|
||||||
auto alloc = std::allocator<char>();
|
auto alloc = std::allocator<char>();
|
||||||
basic_memory_buffer<char, 5, std_allocator_n> buffer(
|
basic_memory_buffer<char, 5, std_allocator_noprop> buffer(
|
||||||
(std_allocator_n(&alloc)));
|
(std_allocator_noprop(&alloc)));
|
||||||
const char test[] = "test";
|
const char test[] = "test";
|
||||||
buffer.append(string_view(test, 4));
|
buffer.append(string_view(test, 4));
|
||||||
check_move_buffer("test", buffer);
|
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) {
|
TEST(memory_buffer_test, move_ctor_dynamic_buffer_non_propagating) {
|
||||||
auto alloc = std::allocator<char>();
|
auto alloc = std::allocator<char>();
|
||||||
basic_memory_buffer<char, 4, std_allocator_n> buffer(
|
basic_memory_buffer<char, 4, std_allocator_noprop> buffer(
|
||||||
(std_allocator_n(&alloc)));
|
(std_allocator_noprop(&alloc)));
|
||||||
const char test[] = "test";
|
const char test[] = "test";
|
||||||
buffer.append(test, test + 4);
|
buffer.append(test, test + 4);
|
||||||
const char* inline_buffer_ptr = &buffer[0];
|
const char* inline_buffer_ptr = &buffer[0];
|
||||||
buffer.push_back('a');
|
buffer.push_back('a');
|
||||||
EXPECT_NE(&buffer[0], inline_buffer_ptr);
|
EXPECT_NE(&buffer[0], inline_buffer_ptr);
|
||||||
std::allocator<char>* original_alloc_ptr = buffer.get_allocator().get();
|
std::allocator<char>* original_alloc_ptr = buffer.get_allocator().get();
|
||||||
basic_memory_buffer<char, 4, std_allocator_n> buffer2;
|
basic_memory_buffer<char, 4, std_allocator_noprop> buffer2;
|
||||||
buffer2 = std::move(buffer);
|
buffer2 = std::move(buffer);
|
||||||
EXPECT_EQ(std::string(&buffer2[0], buffer2.size()), "testa");
|
EXPECT_EQ(std::string(&buffer2[0], buffer2.size()), "testa");
|
||||||
EXPECT_GT(buffer2.capacity(), 4u);
|
EXPECT_GT(buffer2.capacity(), 4u);
|
||||||
|
@@ -37,8 +37,7 @@ template <typename T> class mock_allocator {
|
|||||||
MOCK_METHOD(void, deallocate, (T*, size_t));
|
MOCK_METHOD(void, deallocate, (T*, size_t));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Allocator, bool PropagateOnMove = false>
|
template <typename Allocator, bool PropagateOnMove = true> class allocator_ref {
|
||||||
class allocator_ref {
|
|
||||||
private:
|
private:
|
||||||
Allocator* alloc_;
|
Allocator* alloc_;
|
||||||
|
|
||||||
@@ -50,8 +49,7 @@ class allocator_ref {
|
|||||||
public:
|
public:
|
||||||
using value_type = typename Allocator::value_type;
|
using value_type = typename Allocator::value_type;
|
||||||
using propagate_on_container_move_assignment =
|
using propagate_on_container_move_assignment =
|
||||||
typename std::conditional<PropagateOnMove, std::true_type,
|
fmt::bool_constant<PropagateOnMove>;
|
||||||
std::false_type>::type;
|
|
||||||
|
|
||||||
explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {}
|
explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {}
|
||||||
|
|
||||||
@@ -70,23 +68,19 @@ class allocator_ref {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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<Allocator>::allocate(*alloc_, n);
|
return std::allocator_traits<Allocator>::allocate(*alloc_, n);
|
||||||
}
|
}
|
||||||
void deallocate(value_type* p, size_t n) { alloc_->deallocate(p, n); }
|
void deallocate(value_type* p, size_t n) { alloc_->deallocate(p, n); }
|
||||||
|
|
||||||
FMT_CONSTEXPR20 friend bool operator==(const allocator_ref& a,
|
friend auto operator==(allocator_ref a, allocator_ref b) noexcept -> bool {
|
||||||
const allocator_ref& b) noexcept {
|
|
||||||
if (a.alloc_ == b.alloc_) return true;
|
if (a.alloc_ == b.alloc_) return true;
|
||||||
if (a.alloc_ == nullptr || b.alloc_ == nullptr) return false;
|
return a.alloc_ && b.alloc_ && *a.alloc_ == *b.alloc_;
|
||||||
|
|
||||||
return *a.alloc_ == *b.alloc_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR20 friend bool operator!=(const allocator_ref& a,
|
friend auto operator!=(allocator_ref a, allocator_ref b) noexcept -> bool {
|
||||||
const allocator_ref& b) noexcept {
|
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user