mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 08:46:45 +08:00
Compare commits
2 Commits
8bd5c83349
...
5d56ef759f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d56ef759f | ||
|
|
eede00165e |
@ -21,20 +21,32 @@ namespace ipc {
|
|||||||
* \see https://en.cppreference.com/w/cpp/memory/construct_at
|
* \see https://en.cppreference.com/w/cpp/memory/construct_at
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename T, typename... A>
|
// Overload for zero arguments - use value initialization
|
||||||
auto construct(void *p, A &&...args)
|
template <typename T>
|
||||||
-> std::enable_if_t<::std::is_constructible<T, A...>::value, T *> {
|
T* construct(void *p) {
|
||||||
#if defined(LIBIPC_CPP_20)
|
#if defined(LIBIPC_CPP_20)
|
||||||
return std::construct_at(static_cast<T *>(p), std::forward<A>(args)...);
|
return std::construct_at(static_cast<T *>(p));
|
||||||
#else
|
#else
|
||||||
return ::new (p) T(std::forward<A>(args)...);
|
return ::new (p) T();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... A>
|
// Overload for one or more arguments - prefer direct initialization
|
||||||
auto construct(void *p, A &&...args)
|
template <typename T, typename A1, typename... A>
|
||||||
-> std::enable_if_t<!::std::is_constructible<T, A...>::value, T *> {
|
auto construct(void *p, A1 &&arg1, A &&...args)
|
||||||
return ::new (p) T{std::forward<A>(args)...};
|
-> std::enable_if_t<::std::is_constructible<T, A1, A...>::value, T *> {
|
||||||
|
#if defined(LIBIPC_CPP_20)
|
||||||
|
return std::construct_at(static_cast<T *>(p), std::forward<A1>(arg1), std::forward<A>(args)...);
|
||||||
|
#else
|
||||||
|
return ::new (p) T(std::forward<A1>(arg1), std::forward<A>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload for non-constructible types - use aggregate initialization
|
||||||
|
template <typename T, typename A1, typename... A>
|
||||||
|
auto construct(void *p, A1 &&arg1, A &&...args)
|
||||||
|
-> std::enable_if_t<!::std::is_constructible<T, A1, A...>::value, T *> {
|
||||||
|
return ::new (p) T{std::forward<A1>(arg1), std::forward<A>(args)...};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -63,26 +63,18 @@ public:
|
|||||||
pointer allocate(size_type count) noexcept {
|
pointer allocate(size_type count) noexcept {
|
||||||
if (count == 0) return nullptr;
|
if (count == 0) return nullptr;
|
||||||
if (count > this->max_size()) return nullptr;
|
if (count > this->max_size()) return nullptr;
|
||||||
if (count == 1) {
|
// Allocate raw memory without constructing objects
|
||||||
return mem::$new<value_type>();
|
// Construction should be done by construct() member function
|
||||||
} else {
|
void *p = mem::alloc(sizeof(value_type) * count);
|
||||||
void *p = mem::alloc(sizeof(value_type) * count);
|
return static_cast<pointer>(p);
|
||||||
if (p == nullptr) return nullptr;
|
|
||||||
for (std::size_t i = 0; i < count; ++i) {
|
|
||||||
std::ignore = ipc::construct<value_type>(static_cast<byte *>(p) + sizeof(value_type) * i);
|
|
||||||
}
|
|
||||||
return static_cast<pointer>(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(pointer p, size_type count) noexcept {
|
void deallocate(pointer p, size_type count) noexcept {
|
||||||
if (count == 0) return;
|
if (count == 0) return;
|
||||||
if (count > this->max_size()) return;
|
if (count > this->max_size()) return;
|
||||||
if (count == 1) {
|
// Deallocate raw memory without destroying objects
|
||||||
mem::$delete(p);
|
// Destruction should be done by destroy() member function before deallocate
|
||||||
} else {
|
mem::free(p, sizeof(value_type) * count);
|
||||||
mem::free(ipc::destroy_n(p, count), sizeof(value_type) * count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... P>
|
template <typename... P>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user