fix: [pmr] explicit specialization in non-namespace scope ‘class pmr::allocator’

This commit is contained in:
mutouyun 2022-11-18 21:55:08 +08:00
parent 1fd5b3825e
commit 890492a3b9
3 changed files with 30 additions and 39 deletions

View File

@ -47,12 +47,19 @@ class LIBIMP_EXPORT allocator {
bool valid() const noexcept override { return false; } bool valid() const noexcept override { return false; }
}; };
template <typename MemRes> template <typename MemRes, typename = void>
class holder_memory_resource : public holder_base { class holder_memory_resource;
MemRes *p_mem_res_;
/**
* @brief A memory resource pointer holder class for type erasure.
* @tparam MR memory resource type
*/
template <typename MR>
class holder_memory_resource<MR, is_memory_resource<MR>> : public holder_base {
MR *p_mem_res_;
public: public:
holder_memory_resource(MemRes *p_mr) noexcept holder_memory_resource(MR *p_mr) noexcept
: p_mem_res_(p_mr) {} : p_mem_res_(p_mr) {}
void *alloc(std::size_t s) override { void *alloc(std::size_t s) override {
@ -68,9 +75,13 @@ class LIBIMP_EXPORT allocator {
} }
}; };
template <> /**
class holder_memory_resource<void> : public holder_null { * @brief An empty holding class used to calculate a reasonable memory size for the holder.
void *p_dummy_; * @tparam MR cannot be converted to the type of memory resource
*/
template <typename MR, typename U>
class holder_memory_resource : public holder_null {
MR *p_dummy_;
}; };
using void_holder_type = holder_memory_resource<void>; using void_holder_type = holder_memory_resource<void>;

View File

@ -6,11 +6,11 @@
LIBPMR_NAMESPACE_BEG_ LIBPMR_NAMESPACE_BEG_
allocator::holder_base &allocator::get_holder() noexcept { allocator::holder_base &allocator::get_holder() noexcept {
return *::LIBIMP_::byte_cast<holder_base>(holder_.data()); return *reinterpret_cast<holder_base *>(holder_.data());
} }
allocator::holder_base const &allocator::get_holder() const noexcept { allocator::holder_base const &allocator::get_holder() const noexcept {
return *::LIBIMP_::byte_cast<holder_base const>(holder_.data()); return *reinterpret_cast<holder_base const *>(holder_.data());
} }
allocator::allocator() noexcept { allocator::allocator() noexcept {

View File

@ -1,6 +1,5 @@
#include <cstdlib> // std::aligned_alloc #include <cstdlib> // std::aligned_alloc
#include <exception>
#include "libimp/detect_plat.h" #include "libimp/detect_plat.h"
#include "libimp/system.h" #include "libimp/system.h"
@ -51,24 +50,15 @@ void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) no
if (!verify_args(log, bytes, alignment)) { if (!verify_args(log, bytes, alignment)) {
return nullptr; return nullptr;
} }
#if defined(LIBIMP_CPP_17)
/// @see https://en.cppreference.com/w/cpp/memory/c/aligned_alloc
return std::aligned_alloc(alignment, bytes);
#else
if (alignment <= alignof(std::max_align_t)) { if (alignment <= alignof(std::max_align_t)) {
/// @see https://en.cppreference.com/w/cpp/memory/c/malloc /// @see https://en.cppreference.com/w/cpp/memory/c/malloc
return std::malloc(bytes); return std::malloc(bytes);
} }
#if defined(LIBIMP_CPP_17) #if defined(LIBIMP_OS_WIN)
/// @see https://en.cppreference.com/w/cpp/memory/c/aligned_alloc
LIBIMP_TRY {
return std::aligned_alloc(alignment, bytes);
} LIBIMP_CATCH(std::exception const &e) {
log.error("std::aligned_alloc(alignment = {}, bytes = {}) fails. error = {}",
alignment, bytes, e.what());
return nullptr;
} LIBIMP_CATCH(...) {
log.error("std::aligned_alloc(alignment = {}, bytes = {}) fails. error = unknown exception",
alignment, bytes);
return nullptr;
}
#elif defined(LIBIMP_OS_WIN)
/// @see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc /// @see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc
return ::_aligned_malloc(bytes, alignment); return ::_aligned_malloc(bytes, alignment);
#else // try posix #else // try posix
@ -82,6 +72,7 @@ void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) no
} }
return p; return p;
#endif #endif
#endif // defined(LIBIMP_CPP_17)
} }
/** /**
@ -100,23 +91,12 @@ void new_delete_resource::deallocate(void *p, std::size_t bytes, std::size_t ali
if (!verify_args(log, bytes, alignment)) { if (!verify_args(log, bytes, alignment)) {
return; return;
} }
auto std_free = [&log, bytes, alignment](void* p) noexcept {
/// @see https://en.cppreference.com/w/cpp/memory/c/free
LIBIMP_TRY {
std::free(p);
} LIBIMP_CATCH(std::exception const &e) {
log.error("std::free(p = {}) fails, alignment = {}, bytes = {}. error = {}",
p, alignment, bytes, e.what());
} LIBIMP_CATCH(...) {
log.error("std::free(p = {}) fails, alignment = {}, bytes = {}. error = unknown exception",
p, alignment, bytes);
}
};
#if defined(LIBIMP_CPP_17) #if defined(LIBIMP_CPP_17)
std_free(p); /// @see https://en.cppreference.com/w/cpp/memory/c/free
std::free(p);
#else #else
if (alignment <= alignof(std::max_align_t)) { if (alignment <= alignof(std::max_align_t)) {
std_free(p); std::free(p);
return; return;
} }
#if defined(LIBIMP_OS_WIN) #if defined(LIBIMP_OS_WIN)