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; }
};
template <typename MemRes>
class holder_memory_resource : public holder_base {
MemRes *p_mem_res_;
template <typename MemRes, typename = void>
class holder_memory_resource;
/**
* @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:
holder_memory_resource(MemRes *p_mr) noexcept
holder_memory_resource(MR *p_mr) noexcept
: p_mem_res_(p_mr) {}
void *alloc(std::size_t s) override {
@ -68,9 +75,13 @@ class LIBIMP_EXPORT allocator {
}
};
template <>
class holder_memory_resource<void> : public holder_null {
void *p_dummy_;
/**
* @brief An empty holding class used to calculate a reasonable memory size for the holder.
* @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>;

View File

@ -6,11 +6,11 @@
LIBPMR_NAMESPACE_BEG_
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 {
return *::LIBIMP_::byte_cast<holder_base const>(holder_.data());
return *reinterpret_cast<holder_base const *>(holder_.data());
}
allocator::allocator() noexcept {

View File

@ -1,6 +1,5 @@
#include <cstdlib> // std::aligned_alloc
#include <exception>
#include <cstdlib> // std::aligned_alloc
#include "libimp/detect_plat.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)) {
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)) {
/// @see https://en.cppreference.com/w/cpp/memory/c/malloc
return std::malloc(bytes);
}
#if defined(LIBIMP_CPP_17)
/// @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)
#if defined(LIBIMP_OS_WIN)
/// @see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc
return ::_aligned_malloc(bytes, alignment);
#else // try posix
@ -82,6 +72,7 @@ void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) no
}
return p;
#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)) {
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)
std_free(p);
/// @see https://en.cppreference.com/w/cpp/memory/c/free
std::free(p);
#else
if (alignment <= alignof(std::max_align_t)) {
std_free(p);
std::free(p);
return;
}
#if defined(LIBIMP_OS_WIN)