upd: [pmr] helper trait for allocator

This commit is contained in:
mutouyun 2022-11-14 21:32:00 +08:00
parent efe1fe61dd
commit a392b88787
6 changed files with 49 additions and 9 deletions

View File

@ -31,7 +31,7 @@
LIBIMP_NAMESPACE_BEG_
namespace detail {
/// @brief helper trait for span
/// @brief Helper trait for span.
template <typename From, typename To>
using array_convertible = std::is_convertible<From(*)[], To(*)[]>;

View File

@ -6,10 +6,37 @@
*/
#pragma once
#include <type_traits>
#include "libimp/export.h"
#include "libpmr/def.h"
#include "libpmr/memory_resource.h"
LIBPMR_NAMESPACE_BEG_
namespace detail {
/// @brief Helper trait for allocator.
template <typename T, typename = void>
struct has_allocate : std::false_type {};
template <typename T>
struct has_allocate<T,
typename std::enable_if<std::is_convertible<
decltype(std::declval<T &>().allocate(std::declval<std::size_t>())), void *
>::value>::type> : std::true_type {};
template <typename T, typename = void>
struct has_deallocate : std::false_type {};
template <typename T>
struct has_deallocate<T,
decltype(std::declval<T &>().deallocate(std::declval<void *>(),
std::declval<std::size_t>()))
> : std::true_type {};
} // namespace detail
/**
* @brief An allocator which exhibits different allocation behavior
@ -23,6 +50,8 @@ LIBPMR_NAMESPACE_BEG_
* @see https://en.cppreference.com/w/cpp/memory/memory_resource
* https://en.cppreference.com/w/cpp/memory/polymorphic_allocator
*/
class LIBIMP_EXPORT allocator {
};
LIBPMR_NAMESPACE_END_

View File

@ -6,7 +6,7 @@
*/
#pragma once
#include <cstddef> // std::size_t
#include <cstddef> // std::size_t, std::max_align_t
#include "libimp/export.h"
#include "libpmr/def.h"
@ -24,11 +24,11 @@ public:
/// @brief Allocates storage with a size of at least bytes bytes, aligned to the specified alignment.
/// @remark Returns nullptr if storage of the requested size and alignment cannot be obtained.
/// @see https://en.cppreference.com/w/cpp/memory/memory_resource/do_allocate
void *do_allocate(std::size_t bytes, std::size_t alignment) noexcept;
void *allocate(std::size_t bytes, std::size_t alignment = alignof(std::max_align_t)) noexcept;
/// @brief Deallocates the storage pointed to by p.
/// @see https://en.cppreference.com/w/cpp/memory/memory_resource/deallocate
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) noexcept;
void deallocate(void *p, std::size_t bytes, std::size_t alignment = alignof(std::max_align_t)) noexcept;
};
LIBPMR_NAMESPACE_END_

View File

@ -1,6 +1,5 @@
#include <cstdlib> // std::aligned_alloc
#include <cstddef> // std::max_align_t
#include <exception>
#include "libimp/detect_plat.h"
@ -37,7 +36,7 @@ bool verify_args(::LIBIMP_::log::gripper &log, std::size_t bytes, std::size_t al
*
* @return void * - nullptr if storage of the requested size and alignment cannot be obtained.
*/
void *new_delete_resource::do_allocate(std::size_t bytes, std::size_t alignment) noexcept {
void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) noexcept {
LIBIMP_LOG_();
if (!verify_args(log, bytes, alignment)) {
return nullptr;
@ -83,7 +82,7 @@ void *new_delete_resource::do_allocate(std::size_t bytes, std::size_t alignment)
*
* @param p must have been returned by a prior call to new_delete_resource::do_allocate(bytes, alignment).
*/
void new_delete_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) noexcept {
void new_delete_resource::deallocate(void *p, std::size_t bytes, std::size_t alignment) noexcept {
LIBIMP_LOG_();
if (p == nullptr) {
return;

View File

@ -1,7 +1,19 @@
#include <vector>
#include <memory_resource>
#include "gtest/gtest.h"
#include "libpmr/allocator.h"
TEST(allocator, detail) {
EXPECT_FALSE(pmr::detail::has_allocate<void>::value);
EXPECT_FALSE(pmr::detail::has_allocate<int>::value);
EXPECT_FALSE(pmr::detail::has_allocate<std::vector<int>>::value);
EXPECT_TRUE (pmr::detail::has_allocate<std::allocator<int>>::value);
EXPECT_TRUE (pmr::detail::has_allocate<std::pmr::memory_resource>::value);
EXPECT_TRUE (pmr::detail::has_allocate<std::pmr::polymorphic_allocator<int>>::value);
}
TEST(allocator, construct) {
}

View File

@ -9,13 +9,13 @@ namespace {
template <typename T>
void *test_mr(T &&mr, std::size_t bytes, std::size_t alignment) {
auto p = std::forward<T>(mr).do_allocate(bytes, alignment);
auto p = std::forward<T>(mr).allocate(bytes, alignment);
if (alignment == 0) {
EXPECT_EQ(p, nullptr);
} else if (p != nullptr) {
EXPECT_EQ((std::size_t)p % alignment, 0);
}
std::forward<T>(mr).do_deallocate(p, bytes, alignment);
std::forward<T>(mr).deallocate(p, bytes, alignment);
return p;
}