blob: 6a8217d2aa5c59eb1607116d8480f23a949516c6 [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <experimental/memory_resource>
// template <class Alloc> class resource_adaptor_imp;
// void * do_allocate(size_t size, size_t align)
// void do_deallocate(void*, size_t, size_t)
// When back-deploying to macosx10.7, the RTTI for exception classes
// incorrectly provided by libc++.dylib is mixed with the one in
// libc++abi.dylib and exceptions are not caught properly.
// XFAIL: with_system_cxx_lib=macosx10.7
#include <experimental/memory_resource>
#include <type_traits>
#include <memory>
#include <exception>
#include <cassert>
#include "test_macros.h"
#include "test_memory_resource.h"
namespace ex = std::experimental::pmr;
template <class Alloc>
void check_allocate_deallocate()
{
typedef ex::resource_adaptor<Alloc> R1;
const std::size_t max_align = alignof(std::max_align_t);
for (std::size_t s = 1; s < 5012; ++s)
{
for(std::size_t align_req = 1; align_req <= (max_align * 2); align_req *= 2)
{
const std::size_t align_exp = align_req > max_align
? max_align : align_req;
AllocController P;
R1 r{Alloc(P)};
ex::memory_resource & m1 = r;
void * const ret = m1.allocate(s, align_req);
assert(P.alive == 1);
assert(P.alloc_count == 1);
assert(P.checkAllocAtLeast(ret, s, align_exp));
assert(((std::size_t)ret % align_exp) == 0);
m1.deallocate(ret, s, align_req);
assert(P.alive == 0);
assert(P.dealloc_count == 1);
assert(P.checkDeallocMatchesAlloc());
}
}
}
void check_alloc_max_size() {
using Alloc = NullAllocator<char>;
using R1 = ex::resource_adaptor<Alloc>;
const std::size_t max_align = alignof(std::max_align_t);
auto check = [=](std::size_t s, std::size_t align_req) {
const std::size_t align_exp = align_req > max_align
? max_align : align_req;
AllocController P;
R1 r{Alloc(P)};
ex::memory_resource & m1 = r;
void * const ret = m1.allocate(s, align_req);
assert(P.alive == 1);
assert(P.alloc_count == 1);
assert(P.checkAllocAtLeast(ret, s, align_exp));
m1.deallocate(ret, s, align_req);
assert(P.alive == 0);
assert(P.dealloc_count == 1);
assert(P.checkDeallocMatchesAlloc());
};
const std::size_t sizeTypeMax = ~0;
const std::size_t testSizeStart = sizeTypeMax - (max_align * 3);
const std::size_t testSizeEnd = sizeTypeMax - max_align;
for (std::size_t size = testSizeStart; size <= testSizeEnd; ++size) {
for (std::size_t align=1; align <= (max_align * 2); align *= 2) {
check(size, align);
}
}
#ifndef TEST_HAS_NO_EXCEPTIONS
for (std::size_t size = sizeTypeMax; size > testSizeEnd; --size) {
AllocController P;
R1 r{Alloc(P)};
ex::memory_resource & m1 = r;
try {
m1.allocate(size);
assert(false);
} catch (std::exception const&) {
}
}
#endif
}
int main(int, char**)
{
check_allocate_deallocate<CountingAllocator<char>>();
check_allocate_deallocate<MinAlignedAllocator<char>>();
check_alloc_max_size();
return 0;
}