diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-05-07 01:04:55 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-05-07 01:04:55 +0000 |
commit | 15551efd432d797ce49c320ade8ab516d783491c (patch) | |
tree | 5ca73490b77bf70ff23f61e369e7d3c9a8955b30 /libcxx/test/std/experimental/memory | |
parent | 7fa7dc36fed383098cd20f2bb94480e9562f17cf (diff) | |
download | bcm5719-llvm-15551efd432d797ce49c320ade8ab516d783491c.tar.gz bcm5719-llvm-15551efd432d797ce49c320ade8ab516d783491c.zip |
Add <experimental/memory_resource>
Reviewers: mclow.lists, EricWF
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D20007
llvm-svn: 268829
Diffstat (limited to 'libcxx/test/std/experimental/memory')
40 files changed, 2732 insertions, 0 deletions
diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp new file mode 100644 index 00000000000..77ffb51a330 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/assign.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator operator=(polymorphic_allocator const &) = delete + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> T; + static_assert(std::is_copy_assignable<T>::value, ""); + static_assert(std::is_move_assignable<T>::value, ""); +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp new file mode 100644 index 00000000000..ba3710d4de1 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/copy.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator const &); + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + { + static_assert( + std::is_copy_constructible<A1>::value, "" + ); + static_assert( + std::is_move_constructible<A1>::value, "" + ); + } + // copy + { + A1 const a((ex::memory_resource*)42); + A1 const a2(a); + assert(a.resource() == a2.resource()); + } + // move + { + A1 a((ex::memory_resource*)42); + A1 a2(std::move(a)); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp new file mode 100644 index 00000000000..1007556a485 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/default.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator() noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + static_assert( + std::is_nothrow_default_constructible<ex::polymorphic_allocator<void>>::value + , "Must me nothrow default constructible" + ); + } + { + // test that the allocator gets its resource from get_default_resource + TestResource R1(42); + ex::set_default_resource(&R1); + + typedef ex::polymorphic_allocator<void> A; + A const a; + assert(a.resource() == &R1); + + ex::set_default_resource(nullptr); + A const a2; + assert(a.resource() == &R1); + assert(a2.resource() == ex::new_delete_resource()); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp new file mode 100644 index 00000000000..19d9646ad61 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/memory_resource_convert.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator<T>::polymorphic_allocator(memory_resource *) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + typedef ex::polymorphic_allocator<void> A; + static_assert( + std::is_convertible<decltype(nullptr), A>::value + , "Must be convertible" + ); + static_assert( + std::is_convertible<ex::memory_resource *, A>::value + , "Must be convertible" + ); + } + { + typedef ex::polymorphic_allocator<void> A; + TestResource R; + A const a(&R); + assert(a.resource() == &R); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp new file mode 100644 index 00000000000..aadfbcc322f --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.ctor/other_alloc.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U> +// polymorphic_allocator<T>::polymorphic_allocator(polymorphic_allocator<U> const &); + + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<char> A2; + { // Test that the conversion is implicit and noexcept. + static_assert( + std::is_convertible<A1 const &, A2>::value, "" + ); + static_assert( + std::is_convertible<A2 const &, A1>::value, "" + ); + static_assert( + std::is_nothrow_constructible<A1, A2 const &>::value, "" + ); + static_assert( + std::is_nothrow_constructible<A2, A1 const &>::value, "" + ); + } + // copy other type + { + A1 const a((ex::memory_resource*)42); + A2 const a2(a); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } + { + A1 a((ex::memory_resource*)42); + A2 const a2(std::move(a)); + assert(a.resource() == a2.resource()); + assert(a2.resource() == (ex::memory_resource*)42); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp new file mode 100644 index 00000000000..d5a3d01961d --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/equal.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator; + +// template <class T, class U> +// bool operator==( +// polymorphic_allocator<T> const & +// , polymorphic_allocator<U> const &) noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<int> A2; + // check return types + { + A1 const a1; + A2 const a2; + static_assert(std::is_same<decltype(a1 == a2), bool>::value, ""); + static_assert(noexcept(a1 == a2), ""); + } + // equal same type (different resource) + { + TestResource d1(1); + TestResource d2(1); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } + // equal same type (same resource) + { + TestResource d1; + A1 const a1(&d1); + A1 const a2(&d1); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + } + // equal different type (different resource) + { + TestResource d1(42); + TestResource d2(42); + A1 const a1(&d1); + A2 const a2(&d2); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // equal different type (same resource) + { + TestResource d1(42); + A1 const a1(&d1); + A2 const a2(&d1); + + assert(a1 == a2); + assert(d1.checkIsEqualCalledEq(0)); + + assert(a2 == a1); + assert(d1.checkIsEqualCalledEq(0)); + + } + // not equal same type + { + TestResource d1(1); + TestResource d2(2); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(!(a1 == a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 == a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // not equal different types + { + TestResource d1; + TestResource1 d2; + A1 const a1(&d1); + A2 const a2(&d2); + + assert(!(a1 == a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 == a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp new file mode 100644 index 00000000000..e83757607a6 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.eq/not_equal.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator; + +// template <class T> +// bool operator!=( +// polymorphic_allocator<T> const & +// , polymorphic_allocator<T> const &) noexcept + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A1; + typedef ex::polymorphic_allocator<int> A2; + // check return types + { + A1 const a1; + A2 const a2; + static_assert(std::is_same<decltype(a1 != a2), bool>::value, ""); + static_assert(noexcept(a1 != a2), ""); + } + // not equal same type (different resource) + { + TestResource d1(1); + TestResource d2(2); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(a1 != a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 != a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } + // equal same type (same resource) + { + TestResource d1; + A1 const a1(&d1); + A1 const a2(&d1); + + assert(!(a1 != a2)); + assert(d1.checkIsEqualCalledEq(0)); + + assert(!(a2 != a1)); + assert(d1.checkIsEqualCalledEq(0)); + } + // equal same type + { + TestResource d1(1); + TestResource d2(1); + A1 const a1(&d1); + A1 const a2(&d2); + + assert(!(a1 != a2)); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(!(a2 != a1)); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + + } + // not equal different types + { + TestResource d1; + TestResource1 d2; + A1 const a1(&d1); + A2 const a2(&d2); + + assert(a1 != a2); + assert(d1.checkIsEqualCalledEq(1)); + assert(d2.checkIsEqualCalledEq(0)); + + d1.reset(); + + assert(a2 != a1); + assert(d1.checkIsEqualCalledEq(0)); + assert(d2.checkIsEqualCalledEq(1)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp new file mode 100644 index 00000000000..1a6ce872a63 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/allocate.pass.cpp @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::allocate(size_t n) + +#include <experimental/memory_resource> +#include <limits> +#include <memory> +#include <exception> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <size_t S, size_t Align> +void testForSizeAndAlign() { + using T = typename std::aligned_storage<S, Align>::type; + TestResource R; + ex::polymorphic_allocator<T> a(&R); + + for (int N = 1; N <= 5; ++N) { + auto ret = a.allocate(N); + assert(R.checkAlloc(ret, N * sizeof(T), alignof(T))); + + a.deallocate(ret, N); + R.reset(); + } +} + +#ifndef TEST_HAS_NO_EXCEPTIONS +template <size_t S> +void testAllocForSizeThrows() { + using T = typename std::aligned_storage<S>::type; + using Alloc = ex::polymorphic_allocator<T>; + using Traits = std::allocator_traits<Alloc>; + NullResource R; + Alloc a(&R); + + // Test that allocating exactly the max size does not throw. + size_t maxSize = Traits::max_size(a); + try { + a.allocate(maxSize); + } catch (...) { + assert(false); + } + + size_t sizeTypeMax = std::numeric_limits<std::size_t>::max(); + if (maxSize != sizeTypeMax) + { + // Test that allocating size_t(~0) throws bad alloc. + try { + a.allocate(sizeTypeMax); + assert(false); + } catch (std::exception const&) { + } + + // Test that allocating even one more than the max size does throw. + size_t overSize = maxSize + 1; + try { + a.allocate(overSize); + assert(false); + } catch (std::exception const&) { + } + } +} +#endif // TEST_HAS_NO_EXCEPTIONS + +int main() +{ + { + ex::polymorphic_allocator<int> a; + static_assert(std::is_same<decltype(a.allocate(0)), int*>::value, ""); + static_assert(!noexcept(a.allocate(0)), ""); + } + { + constexpr std::size_t MA = alignof(std::max_align_t); + testForSizeAndAlign<1, 1>(); + testForSizeAndAlign<1, 2>(); + testForSizeAndAlign<1, MA>(); + testForSizeAndAlign<2, 2>(); + testForSizeAndAlign<73, alignof(void*)>(); + testForSizeAndAlign<73, MA>(); + testForSizeAndAlign<13, MA>(); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + testAllocForSizeThrows<1>(); + testAllocForSizeThrows<2>(); + testAllocForSizeThrows<4>(); + testAllocForSizeThrows<8>(); + testAllocForSizeThrows<16>(); + testAllocForSizeThrows<73>(); + testAllocForSizeThrows<13>(); + } +#endif +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp new file mode 100644 index 00000000000..9ce04045058 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<U1, U2>*) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + +int constructed = 0; + +struct default_constructible +{ + default_constructible() : x(42) { ++constructed; } + int x{0}; +}; + +int main() +{ + // pair<default_constructible, default_constructible> as T() + { + typedef default_constructible T; + typedef std::pair<T, T> P; + typedef ex::polymorphic_allocator<void> A; + P * ptr = (P*)std::malloc(sizeof(P)); + A a; + a.construct(ptr); + assert(constructed == 2); + assert(ptr->first.x == 42); + assert(ptr->second.x == 42); + std::free(ptr); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp new file mode 100644 index 00000000000..6fbe1a3cc3a --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> const&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::pair<TT, UU> const& p) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = (P*)std::malloc(sizeof(P)); + P * ptr2 = (P*)std::malloc(sizeof(P)); + + // UNDER TEST // + A.construct(ptr, p); + + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(p.first), + std::forward_as_tuple(p.second)); + // ------- // + + bool tres = checkConstruct<decltype((p.first))>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<decltype((p.second))>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + std::free(ptr); + A.destroy(ptr2); + std::free(ptr2); + return tres && ures; + +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(std::pair<TT, UU> const& p) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, p))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, p))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, p))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, p))); + } +} +template <class Tp> +struct Print; + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + const std::pair<int, int&> p(x, y); + test_pmr_uses_allocator<ERT>(p); + test_pmr_uses_allocator<PMR>(p); + test_pmr_uses_allocator<PMA>(p); + } + { + int x = 42; + int y = 42; + const std::pair<int&, int&&> p(x, std::move(y)); + test_pmr_uses_allocator<ERT>(p); + test_pmr_uses_allocator<PMR>(p); + test_pmr_uses_allocator<PMA>(p); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp new file mode 100644 index 00000000000..67d16bd83e5 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_rvalue.pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> &&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::pair<TT, UU>&& p) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = A.allocate(2); + P * ptr2 = ptr + 1; + + // UNDER TEST // + A.construct(ptr, std::move(p)); + + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(std::forward<TT>(p.first)), + std::forward_as_tuple(std::forward<UU>(p.second))); + // ------- // + + bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + A.destroy(ptr2); + A.deallocate(ptr, 2); + return tres && ures; +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(std::pair<TT, UU>&& p) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, std::move(p)))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::move(p)))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::move(p)))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, std::move(p)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + std::pair<int&, int&&> p(x, std::move(y)); + test_pmr_uses_allocator<ERT>(std::move(p)); + test_pmr_uses_allocator<PMR>(std::move(p)); + test_pmr_uses_allocator<PMA>(std::move(p)); + } + { + int x = 42; + int y = 42; + std::pair<int&&, int&> p(std::move(x), y); + test_pmr_uses_allocator<ERT>(std::move(p)); + test_pmr_uses_allocator<PMR>(std::move(p)); + test_pmr_uses_allocator<PMA>(std::move(p)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp new file mode 100644 index 00000000000..d4c8e036928 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_pair_values.pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class P1, class P2, class U1, class U2> +// void polymorphic_allocator<T>::construct(pair<P1, P2>*, U1&&, U2&&) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" + +namespace ex = std::experimental::pmr; + + +template <class UA1, class UA2, class TT, class UU> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + TT&& t, UU&& u) +{ + using P = std::pair<UA1, UA2>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = (P*)std::malloc(sizeof(P)); + P * ptr2 = (P*)std::malloc(sizeof(P)); + + // UNDER TEST // + A.construct(ptr, std::forward<TT>(t), std::forward<UU>(u)); + A.construct(ptr2, std::piecewise_construct, + std::forward_as_tuple(std::forward<TT>(t)), + std::forward_as_tuple(std::forward<UU>(u))); + // ------- // + + bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && + checkConstructionEquiv(ptr->first, ptr2->first); + + bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && + checkConstructionEquiv(ptr->second, ptr2->second); + + A.destroy(ptr); + A.destroy(ptr2); + std::free(ptr); + std::free(ptr2); + return tres && ures; +} + +template <class Alloc, class TT, class UU> +void test_pmr_uses_allocator(TT&& t, UU&& u) +{ + { + using T = NotUsesAllocator<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_None, UA_None, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV1<Alloc, 1>; + using U = UsesAllocatorV2<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV2<Alloc, 1>; + using U = UsesAllocatorV3<Alloc, 1>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, + std::forward<TT>(t), std::forward<UU>(u)))); + } + { + using T = UsesAllocatorV3<Alloc, 1>; + using U = NotUsesAllocator<Alloc, 1>; + assert((doTest<T, U>(UA_AllocArg, UA_None, + std::forward<TT>(t), std::forward<UU>(u)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + int x = 42; + int y = 42; + test_pmr_uses_allocator<ERT>(x, std::move(y)); + test_pmr_uses_allocator<PMR>(x, std::move(y)); + test_pmr_uses_allocator<PMA>(x, std::move(y)); + } + { + int x = 42; + const int y = 42; + test_pmr_uses_allocator<ERT>(std::move(x), y); + test_pmr_uses_allocator<PMR>(std::move(x), y); + test_pmr_uses_allocator<PMA>(std::move(x), y); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp new file mode 100644 index 00000000000..206bfb017ed --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_piecewise_pair.pass.cpp @@ -0,0 +1,129 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U1, class U2, class ...Args1, class ...Args2> +// void polymorphic_allocator<T>::construct(pair<U1, U2>*, piecewise_construct_t +// tuple<Args1...>, tuple<Args2...>) + +#include <experimental/memory_resource> +#include <type_traits> +#include <utility> +#include <tuple> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" +#include "test_allocator.h" + +namespace ex = std::experimental::pmr; + +template <class T, class U, class ...TTuple, class ...UTuple> +bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, + std::tuple<TTuple...> ttuple, std::tuple<UTuple...> utuple) +{ + using P = std::pair<T, U>; + TestResource R; + ex::memory_resource * M = &R; + ex::polymorphic_allocator<P> A(M); + P * ptr = A.allocate(1); + + // UNDER TEST // + A.construct(ptr, std::piecewise_construct, std::move(ttuple), std::move(utuple)); + // ------- // + bool tres = checkConstruct<TTuple&&...>(ptr->first, TExpect, M); + bool ures = checkConstruct<UTuple&&...>(ptr->second, UExpect, M); + + A.destroy(ptr); + A.deallocate(ptr, 1); + return tres && ures; +} + +template <class Alloc, class ...TTypes, class ...UTypes> +void test_pmr_uses_allocator(std::tuple<TTypes...> ttuple, std::tuple<UTypes...> utuple) +{ + { + using T = NotUsesAllocator<Alloc, sizeof...(TTypes)>; + using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_None, UA_None, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV1<Alloc, sizeof...(TTypes)>; + using U = UsesAllocatorV2<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV2<Alloc, sizeof...(TTypes)>; + using U = UsesAllocatorV3<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, + std::move(ttuple), std::move(utuple)))); + } + { + using T = UsesAllocatorV3<Alloc, sizeof...(TTypes)>; + using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; + assert((doTest<T, U>(UA_AllocArg, UA_None, + std::move(ttuple), std::move(utuple)))); + } +} + +int main() +{ + using ERT = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<char>; + { + std::tuple<> t1; + test_pmr_uses_allocator<ERT>(t1, t1); + test_pmr_uses_allocator<PMR>(t1, t1); + test_pmr_uses_allocator<PMA>(t1, t1); + } + { + std::tuple<int> t1(42); + std::tuple<> t2; + test_pmr_uses_allocator<ERT>(t1, t2); + test_pmr_uses_allocator<ERT>(t2, t1); + test_pmr_uses_allocator<PMR>(t1, t2); + test_pmr_uses_allocator<PMR>(t2, t1); + test_pmr_uses_allocator<PMA>(t1, t2); + test_pmr_uses_allocator<PMA>(t2, t1); + } + { + std::tuple<int> t1(42); + int x = 55; + double dx = 42.42; + std::tuple<int&, double&&> t2(x, std::move(dx)); + test_pmr_uses_allocator<ERT>( t1, std::move(t2)); + test_pmr_uses_allocator<ERT>(std::move(t2), t1); + test_pmr_uses_allocator<PMR>( t1, std::move(t2)); + test_pmr_uses_allocator<PMR>(std::move(t2), t1); + test_pmr_uses_allocator<PMA>( t1, std::move(t2)); + test_pmr_uses_allocator<PMA>(std::move(t2), t1); + } + { + void* xptr = nullptr; + long y = 4242; + std::tuple<int, long const&, void*&> t1(42, y, xptr); + int x = 55; + double dx = 42.42; + const char* s = "hello World"; + std::tuple<int&, double&&, const char*> t2(x, std::move(dx), s); + test_pmr_uses_allocator<ERT>( t1, std::move(t2)); + test_pmr_uses_allocator<ERT>(std::move(t2), t1); + test_pmr_uses_allocator<PMR>( t1, std::move(t2)); + test_pmr_uses_allocator<PMR>(std::move(t2), t1); + test_pmr_uses_allocator<PMA>( t1, std::move(t2)); + test_pmr_uses_allocator<PMA>(std::move(t2), t1); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp new file mode 100644 index 00000000000..9f515e9608e --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/construct_types.pass.cpp @@ -0,0 +1,189 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U, class ...Args> +// void polymorphic_allocator<T>::construct(U *, Args &&...) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> +#include <cstdlib> +#include "uses_alloc_types.hpp" +#include "test_allocator.h" + +namespace ex = std::experimental::pmr; + +template <class T> +struct PMATest { + TestResource R; + ex::polymorphic_allocator<T> A; + T* ptr; + bool constructed; + + PMATest() : A(&R), ptr(A.allocate(1)), constructed(false) {} + + template <class ...Args> + void construct(Args&&... args) { + A.construct(ptr, std::forward<Args>(args)...); + constructed = true; + } + + ~PMATest() { + if (constructed) A.destroy(ptr); + A.deallocate(ptr, 1); + } +}; + +template <class T, class ...Args> +bool doTest(UsesAllocatorType UAExpect, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UAExpect, &TH.R); + // ------- // +} + + +template <class T, class ...Args> +bool doTestUsesAllocV0(Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UA_None); + // -------- // +} + + +template <class T, class EAlloc, class ...Args> +bool doTestUsesAllocV1(EAlloc const& ealloc, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::allocator_arg, ealloc, std::forward<Args>(args)...); + return checkConstruct<Args&&...>(*TH.ptr, UA_AllocArg, ealloc); + // -------- // +} + +template <class T, class EAlloc, class ...Args> +bool doTestUsesAllocV2(EAlloc const& ealloc, Args&&... args) +{ + PMATest<T> TH; + // UNDER TEST // + TH.construct(std::forward<Args>(args)..., ealloc); + return checkConstruct<Args&&...>(*TH.ptr, UA_AllocLast, ealloc); + // -------- // +} + +template <class Alloc, class ...Args> +void test_pmr_uses_alloc(Args&&... args) +{ + TestResource R(12435); + ex::memory_resource* M = &R; + { + // NotUsesAllocator provides valid signatures for each uses-allocator + // construction but does not supply the required allocator_type typedef. + // Test that we can call these constructors manually without + // polymorphic_allocator interfering. + using T = NotUsesAllocator<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(M, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(M, std::forward<Args>(args)...))); + } + { + // Test T(std::allocator_arg_t, Alloc const&, Args...) construction + using T = UsesAllocatorV1<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...))); + } + { + // Test T(Args..., Alloc const&) construction + using T = UsesAllocatorV2<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocLast, std::forward<Args>(args)...))); + } + { + // Test that T(std::allocator_arg_t, Alloc const&, Args...) construction + // is prefered when T(Args..., Alloc const&) is also available. + using T = UsesAllocatorV3<Alloc, sizeof...(Args)>; + assert((doTest<T>(UA_AllocArg, std::forward<Args>(args)...))); + } +} + +// Test that polymorphic_allocator does not prevent us from manually +// doing non-pmr uses-allocator construction. +template <class Alloc, class AllocObj, class ...Args> +void test_non_pmr_uses_alloc(AllocObj const& A, Args&&... args) +{ + { + using T = NotUsesAllocator<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV1<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV2<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } + { + using T = UsesAllocatorV3<Alloc, sizeof...(Args)>; + assert(doTestUsesAllocV0<T>(std::forward<Args>(args)...)); + assert((doTestUsesAllocV1<T>(A, std::forward<Args>(args)...))); + assert((doTestUsesAllocV2<T>(A, std::forward<Args>(args)...))); + } +} + +int main() +{ + using ET = std::experimental::erased_type; + using PMR = ex::memory_resource*; + using PMA = ex::polymorphic_allocator<void>; + using STDA = std::allocator<char>; + using TESTA = test_allocator<char>; + + int value = 42; + const int cvalue = 43; + { + test_pmr_uses_alloc<ET>(); + test_pmr_uses_alloc<PMR>(); + test_pmr_uses_alloc<PMA>(); + test_pmr_uses_alloc<ET>(value); + test_pmr_uses_alloc<PMR>(value); + test_pmr_uses_alloc<PMA>(value); + test_pmr_uses_alloc<ET>(cvalue); + test_pmr_uses_alloc<PMR>(cvalue); + test_pmr_uses_alloc<PMA>(cvalue); + test_pmr_uses_alloc<ET>(cvalue, std::move(value)); + test_pmr_uses_alloc<PMR>(cvalue, std::move(value)); + test_pmr_uses_alloc<PMA>(cvalue, std::move(value)); + } + { + STDA std_alloc; + TESTA test_alloc(42); + test_non_pmr_uses_alloc<STDA>(std_alloc); + test_non_pmr_uses_alloc<TESTA>(test_alloc); + test_non_pmr_uses_alloc<STDA>(std_alloc, value); + test_non_pmr_uses_alloc<TESTA>(test_alloc, value); + test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue); + test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue); + test_non_pmr_uses_alloc<STDA>(std_alloc, cvalue, std::move(value)); + test_non_pmr_uses_alloc<TESTA>(test_alloc, cvalue, std::move(value)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp new file mode 100644 index 00000000000..b631f6eaaad --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/deallocate.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// T* polymorphic_allocator<T>::deallocate(T*, size_t size) + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +template <size_t S, size_t Align> +void testForSizeAndAlign() { + using T = typename std::aligned_storage<S, Align>::type; + + TestResource R; + ex::polymorphic_allocator<T> a(&R); + + for (int N = 1; N <= 5; ++N) { + auto ret = a.allocate(N); + assert(R.checkAlloc(ret, N * sizeof(T), alignof(T))); + + a.deallocate(ret, N); + assert(R.checkDealloc(ret, N * sizeof(T), alignof(T))); + + R.reset(); + } +} + +int main() +{ + { + ex::polymorphic_allocator<int> a; + static_assert( + std::is_same<decltype(a.deallocate(nullptr, 0)), void>::value, ""); + } + { + constexpr std::size_t MA = alignof(std::max_align_t); + testForSizeAndAlign<1, 1>(); + testForSizeAndAlign<1, 2>(); + testForSizeAndAlign<1, MA>(); + testForSizeAndAlign<2, 2>(); + testForSizeAndAlign<73, alignof(void*)>(); + testForSizeAndAlign<73, MA>(); + testForSizeAndAlign<13, MA>(); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp new file mode 100644 index 00000000000..f117bf08dcb --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/destroy.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// template <class U> +// void polymorphic_allocator<T>::destroy(U * ptr); + +#include <experimental/memory_resource> +#include <type_traits> +#include <new> +#include <cassert> +#include <cstdlib> + +namespace ex = std::experimental::pmr; + +int count = 0; + +struct destroyable +{ + destroyable() { ++count; } + ~destroyable() { --count; } +}; + +int main() +{ + typedef ex::polymorphic_allocator<double> A; + { + A a; + static_assert( + std::is_same<decltype(a.destroy((destroyable*)nullptr)), void>::value, + ""); + } + { + destroyable * ptr = ::new (std::malloc(sizeof(destroyable))) destroyable(); + assert(count == 1); + A{}.destroy(ptr); + assert(count == 0); + std::free(ptr); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp new file mode 100644 index 00000000000..5f5411b63e8 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/resource.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// memory_resource * +// polymorphic_allocator<T>::resource() const + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A; + { + A const a; + static_assert( + std::is_same<decltype(a.resource()), ex::memory_resource*>::value + , "" + ); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + A const a(mptr); + assert(a.resource() == mptr); + } + { + A const a(nullptr); + assert(a.resource() == nullptr); + assert(a.resource() == nullptr); + } + { + A const a; + assert(a.resource() == ex::get_default_resource()); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + ex::set_default_resource(mptr); + A const a; + assert(a.resource() == mptr); + assert(a.resource() == ex::get_default_resource()); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp new file mode 100644 index 00000000000..92933cef2f8 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.mem/select_on_container_copy_construction.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class T> class polymorphic_allocator + +// polymorphic_allocator +// polymorphic_allocator<T>::select_on_container_copy_construction() const + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::polymorphic_allocator<void> A; + { + A const a; + static_assert( + std::is_same<decltype(a.select_on_container_copy_construction()), A>::value, + ""); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + A const a(mptr); + assert(a.resource() == mptr); + A const other = a.select_on_container_copy_construction(); + assert(other.resource() == ex::get_default_resource()); + assert(a.resource() == mptr); + } + { + ex::memory_resource * mptr = (ex::memory_resource*)42; + ex::set_default_resource(mptr); + A const a(nullptr); + assert(a.resource() == nullptr); + A const other = a.select_on_container_copy_construction(); + assert(other.resource() == ex::get_default_resource()); + assert(other.resource() == mptr); + assert(a.resource() == nullptr); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp new file mode 100644 index 00000000000..86bf8cc11bb --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/memory.polymorphic.allocator.overview/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp new file mode 100644 index 00000000000..86bf8cc11bb --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.polymorphic.allocator.class/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp new file mode 100644 index 00000000000..4de30bccb81 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_copy.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc const &) + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef CountingAllocator<char> AllocT; + typedef ex::resource_adaptor<AllocT> R; + { + AllocController P; + AllocT const a(P); + R const r(a); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } + { + AllocController P; + AllocT a(P); + R const r(a); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } + { + AllocController P; + AllocT const a(P); + R const r(std::move(a)); + assert(P.copy_constructed == 1); + assert(P.move_constructed == 0); + assert(r.get_allocator() == a); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp new file mode 100644 index 00000000000..f3ecc98eeaa --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/alloc_move.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp(Alloc &&) + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef CountingAllocator<char> AllocT; + typedef ex::resource_adaptor<AllocT> R; + { + AllocController P; + AllocT a(P); + R const r(std::move(a)); + assert(P.copy_constructed == 0); + assert(P.move_constructed == 1); + assert(r.get_allocator() == a); + } + { + AllocController P; + R const r(AllocT{P}); + assert(P.copy_constructed == 0); + assert(P.move_constructed == 1); + assert(r.get_allocator() == AllocT{P}); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp new file mode 100644 index 00000000000..4abc69f0b3d --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.ctor/default.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// resource_adaptor_imp<Alloc>::resource_adaptor_imp() = default; + +#include <experimental/memory_resource> +#include <memory> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + { + typedef CountingAllocator<char> AllocT; // Not default constructible + typedef ex::resource_adaptor<AllocT> R; + static_assert(!std::is_default_constructible<R>::value, ""); + } + { + typedef std::allocator<char> AllocT; // Is default constructible + typedef ex::resource_adaptor<AllocT> R; + static_assert(std::is_default_constructible<R>::value, ""); + R r; ((void)r); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp new file mode 100644 index 00000000000..875c3e01686 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_allocate_and_deallocate.pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// 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) + + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <exception> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +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 = 0; 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() +{ + check_allocate_deallocate<CountingAllocator<char>>(); + check_allocate_deallocate<MinAlignedAllocator<char>>(); + check_alloc_max_size(); +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp new file mode 100644 index 00000000000..ff4b3179a42 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/do_is_equal.pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +// bool do_is_equal(memory_resource const &) const noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <cassert> +#include "test_memory_resource.hpp" + +using std::size_t; +namespace ex = std::experimental::pmr; + +int main() +{ + + typedef CountingAllocator<char> Alloc1; + typedef CountingAllocator<int> RAlloc1; + typedef ex::resource_adaptor<Alloc1> R1; + typedef ex::resource_adaptor<RAlloc1> RR1; + static_assert(std::is_same<R1, RR1>::value, ""); + + typedef std::allocator<char> Alloc2; + typedef ex::resource_adaptor<Alloc2> R2; + static_assert(!std::is_same<R1, R2>::value, ""); + + // equal same type + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + Alloc1 a2(C); + R1 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(m1.is_equal(m2)); + assert(m2.is_equal(m1)); + } + // not equal same type + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + AllocController C2; + Alloc1 a2(C2); + R1 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(!m1.is_equal(m2)); + assert(!m2.is_equal(m1)); + } + // different allocator types + { + AllocController C; + Alloc1 a1(C); + R1 const r1(a1); + ex::memory_resource const & m1 = r1; + + Alloc2 a2; + R2 const r2(a2); + ex::memory_resource const & m2 = r2; + + assert(!m1.is_equal(m2)); + assert(!m2.is_equal(m1)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp new file mode 100644 index 00000000000..898543fbce4 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.overview/overview.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// template <class Alloc> class resource_adaptor_imp; + +#include <experimental/memory_resource> +#include <type_traits> +#include <memory> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + typedef ex::resource_adaptor<std::allocator<void>> R; + typedef ex::resource_adaptor<std::allocator<long>> R2; + static_assert(std::is_same<R, R2>::value, ""); + { + static_assert(std::is_base_of<ex::memory_resource, R>::value, ""); + static_assert(std::is_same<R::allocator_type, std::allocator<char>>::value, ""); + } + { + static_assert(std::is_default_constructible<R>::value, ""); + static_assert(std::is_copy_constructible<R>::value, ""); + static_assert(std::is_move_constructible<R>::value, ""); + static_assert(std::is_copy_assignable<R>::value, ""); + static_assert(std::is_move_assignable<R>::value, ""); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp new file mode 100644 index 00000000000..c89c49d0669 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.global/default_resource.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +//----------------------------------------------------------------------------- +// TESTING memory_resource * get_default_resource() noexcept; +// memory_resource * set_default_resource(memory_resource*) noexcept; +// +// Concerns: +// A) 'get_default_resource()' returns a non-null memory_resource pointer. +// B) 'get_default_resource()' returns the value set by the last call to +// 'set_default_resource(...)' and 'new_delete_resource()' if no call +// to 'set_default_resource(...)' has occurred. +// C) 'set_default_resource(...)' returns the previous value of the default +// resource. +// D) 'set_default_resource(T* p)' for a non-null 'p' sets the default resource +// to be 'p'. +// E) 'set_default_resource(null)' sets the default resource to +// 'new_delete_resource()'. +// F) 'get_default_resource' and 'set_default_resource' are noexcept. + + +#include <experimental/memory_resource> +#include <cassert> + +#include "test_memory_resource.hpp" + +using namespace std::experimental::pmr; + +int main() { + TestResource R; + { // Test (A) and (B) + memory_resource* p = get_default_resource(); + assert(p != nullptr); + assert(p == new_delete_resource()); + assert(p == get_default_resource()); + } + { // Test (C) and (D) + memory_resource *expect = &R; + memory_resource *old = set_default_resource(expect); + assert(old != nullptr); + assert(old == new_delete_resource()); + + memory_resource *p = get_default_resource(); + assert(p != nullptr); + assert(p == expect); + assert(p == get_default_resource()); + } + { // Test (E) + memory_resource* old = set_default_resource(nullptr); + assert(old == &R); + memory_resource* p = get_default_resource(); + assert(p != nullptr); + assert(p == new_delete_resource()); + assert(p == get_default_resource()); + } + { // Test (F) + static_assert(noexcept(get_default_resource()), + "get_default_resource() must be noexcept"); + + static_assert(noexcept(set_default_resource(nullptr)), + "set_default_resource() must be noexcept"); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp new file mode 100644 index 00000000000..bd8c121a4e8 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.global/new_delete_resource.pass.cpp @@ -0,0 +1,101 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * new_delete_resource() + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "count_new.hpp" + +namespace ex = std::experimental::pmr; + +struct assert_on_compare : public ex::memory_resource +{ +protected: + virtual void * do_allocate(size_t, size_t) + { assert(false); } + + virtual void do_deallocate(void *, size_t, size_t) + { assert(false); } + + virtual bool do_is_equal(ex::memory_resource const &) const noexcept + { assert(false); } +}; + +void test_return() +{ + { + static_assert(std::is_same< + decltype(ex::new_delete_resource()), ex::memory_resource* + >::value, ""); + } + // assert not null + { + assert(ex::new_delete_resource()); + } + // assert same return value + { + assert(ex::new_delete_resource() == ex::new_delete_resource()); + } +} + +void test_equality() +{ + // Same object + { + ex::memory_resource & r1 = *ex::new_delete_resource(); + ex::memory_resource & r2 = *ex::new_delete_resource(); + // check both calls returned the same object + assert(&r1 == &r2); + // check for proper equality semantics + assert(r1 == r2); + assert(r2 == r1); + assert(!(r1 != r2)); + assert(!(r2 != r1)); + } + // Different types + { + ex::memory_resource & r1 = *ex::new_delete_resource(); + assert_on_compare c; + ex::memory_resource & r2 = c; + assert(r1 != r2); + assert(!(r1 == r2)); + } +} + +void test_allocate_deallocate() +{ + ex::memory_resource & r1 = *ex::new_delete_resource(); + + globalMemCounter.reset(); + + void *ret = r1.allocate(50); + assert(ret); + assert(globalMemCounter.checkOutstandingNewEq(1)); + assert(globalMemCounter.checkLastNewSizeEq(50)); + + r1.deallocate(ret, 1); + assert(globalMemCounter.checkOutstandingNewEq(0)); + assert(globalMemCounter.checkDeleteCalledEq(1)); + +} + +int main() +{ + static_assert(noexcept(ex::new_delete_resource()), "Must be noexcept"); + test_return(); + test_equality(); + test_allocate_deallocate(); +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp new file mode 100644 index 00000000000..2be74363c1d --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.global/null_memory_resource.pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource * null_memory_resource() + +#include <experimental/memory_resource> +#include <new> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" + +namespace ex = std::experimental::pmr; + +struct assert_on_compare : public ex::memory_resource +{ +protected: + virtual void * do_allocate(size_t, size_t) + { assert(false); } + + virtual void do_deallocate(void *, size_t, size_t) + { assert(false); } + + virtual bool do_is_equal(ex::memory_resource const &) const noexcept + { assert(false); } +}; + +void test_return() +{ + { + static_assert(std::is_same< + decltype(ex::null_memory_resource()), ex::memory_resource* + >::value, ""); + } + // Test that the returned value is not null + { + assert(ex::null_memory_resource()); + } + // Test the same value is returned by repeated calls. + { + assert(ex::null_memory_resource() == ex::null_memory_resource()); + } +} + +void test_equality() +{ + // Same object + { + ex::memory_resource & r1 = *ex::null_memory_resource(); + ex::memory_resource & r2 = *ex::null_memory_resource(); + // check both calls returned the same object + assert(&r1 == &r2); + // check for proper equality semantics + assert(r1 == r2); + assert(r2 == r1); + assert(!(r1 != r2)); + assert(!(r2 != r1)); + // check the is_equal method + assert(r1.is_equal(r2)); + assert(r2.is_equal(r1)); + } + // Different types + { + ex::memory_resource & r1 = *ex::null_memory_resource(); + assert_on_compare c; + ex::memory_resource & r2 = c; + assert(r1 != r2); + assert(!(r1 == r2)); + assert(!r1.is_equal(r2)); + } +} + +void test_allocate() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + DisableAllocationGuard g; // null_memory_resource shouldn't allocate. + try { + ex::null_memory_resource()->allocate(1); + assert(false); + } catch (std::bad_alloc const &) { + // do nothing + } catch (...) { + assert(false); + } +#endif +} + +void test_deallocate() +{ + globalMemCounter.reset(); + + int x = 42; + ex::null_memory_resource()->deallocate(nullptr, 0); + ex::null_memory_resource()->deallocate(&x, 0); + + assert(globalMemCounter.checkDeleteCalledEq(0)); + assert(globalMemCounter.checkDeleteArrayCalledEq(0)); +} + +int main() +{ + test_return(); + test_equality(); + test_allocate(); + test_deallocate(); +} diff --git a/libcxx/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp new file mode 100644 index 00000000000..9a59227abdd --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource.synop/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/libcxx/test/std/experimental/memory/memory.resource/construct.fail.cpp b/libcxx/test/std/experimental/memory/memory.resource/construct.fail.cpp new file mode 100644 index 00000000000..d990714acfd --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/construct.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// Check that memory_resource is not constructible + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +namespace ex = std::experimental::pmr; + +int main() +{ + ex::memory_resource m; // expected-error {{variable type 'ex::memory_resource' is an abstract class}} +} diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp new file mode 100644 index 00000000000..0ccdeed3c54 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.eq/equal.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// bool operator==(memory_resource const &, memory_resource const &) noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + // check return types + { + ex::memory_resource const * mr1(nullptr); + ex::memory_resource const * mr2(nullptr); + static_assert(std::is_same<decltype(*mr1 == *mr2), bool>::value, ""); + static_assert(noexcept(*mr1 == *mr2), ""); + } + // equal + { + TestResource r1(1); + TestResource r2(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(mr1 == mr2); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(mr2 == mr1); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal same object + { + TestResource r1(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r1; + + assert(mr1 == mr2); + assert(r1.checkIsEqualCalledEq(0)); + + assert(mr2 == mr1); + assert(r1.checkIsEqualCalledEq(0)); + } + // not equal + { + TestResource r1(1); + TestResource r2(2); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(!(mr1 == mr2)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(!(mr2 == mr1)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp new file mode 100644 index 00000000000..ede1bfdf9ba --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.eq/not_equal.pass.cpp @@ -0,0 +1,75 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// bool operator!=(memory_resource const &, memory_resource const &) noexcept; + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +namespace ex = std::experimental::pmr; + +int main() +{ + // check return types + { + ex::memory_resource const * mr1(nullptr); + ex::memory_resource const * mr2(nullptr); + static_assert(std::is_same<decltype(*mr1 != *mr2), bool>::value, ""); + static_assert(noexcept(*mr1 != *mr2), ""); + } + // not equal + { + TestResource r1(1); + TestResource r2(2); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(mr1 != mr2); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(mr2 != mr1); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal + { + TestResource r1(1); + TestResource r2(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r2; + + assert(!(mr1 != mr2)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(0)); + + assert(!(mr2 != mr1)); + assert(r1.checkIsEqualCalledEq(1)); + assert(r2.checkIsEqualCalledEq(1)); + } + // equal same object + { + TestResource r1(1); + ex::memory_resource const & mr1 = r1; + ex::memory_resource const & mr2 = r1; + + assert(!(mr1 != mr2)); + assert(r1.checkIsEqualCalledEq(0)); + + assert(!(mr2 != mr1)); + assert(r1.checkIsEqualCalledEq(0)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp new file mode 100644 index 00000000000..86bf8cc11bb --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.overview/nothing_to_do.pass.cpp @@ -0,0 +1,10 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main () {} diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp new file mode 100644 index 00000000000..eddfede2963 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.priv/protected_members.fail.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +// memory_resource::do_allocate(size_t, size_t); /* protected */ +// memory_resource::do_deallocate(void*, size_t, size_t); /* protected */ +// memory_resource::do_is_equal(memory_resource const&); /* protected */ + +#include <experimental/memory_resource> + +namespace ex = std::experimental::pmr; + +int main() { + ex::memory_resource *m = ex::new_delete_resource(); + m->do_allocate(0, 0); // expected-error{{'do_allocate' is a protected member}} + m->do_deallocate(nullptr, 0, 0); // expected-error{{'do_deallocate' is a protected member}} + m->do_is_equal(*m); // expected-error{{'do_is_equal' is a protected member}} +}
\ No newline at end of file diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp new file mode 100644 index 00000000000..26cf903fe0d --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/allocate.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <experimental/memory_resource> + +// UNSUPPORTED: c++98, c++03 + +//------------------------------------------------------------------------------ +// TESTING void * memory_resource::allocate(size_t, size_t = max_align) +// +// Concerns: +// A) 'memory_resource' contains a member 'allocate' with the required +// signature, including the default alignment parameter. +// B) The return type of 'allocate' is 'void*'. +// C) 'allocate' is not marked as 'noexcept'. +// D) Invoking 'allocate' invokes 'do_allocate' with the same arguments. +// E) If 'do_allocate' throws then 'allocate' propagates that exception. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cstddef> +#include <cassert> + +#include "test_macros.h" +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + TestResource R(42); + auto& P = R.getController(); + memory_resource& M = R; + { + static_assert( + std::is_same<decltype(M.allocate(0, 0)), void*>::value + , "Must be void*" + ); + static_assert( + std::is_same<decltype(M.allocate(0)), void*>::value + , "Must be void*" + ); + } + { + static_assert( + ! noexcept(M.allocate(0, 0)) + , "Must not be noexcept." + ); + static_assert( + ! noexcept(M.allocate(0)) + , "Must not be noexcept." + ); + } + { + int s = 42; + int a = 64; + void* p = M.allocate(s, a); + assert(P.alloc_count == 1); + assert(P.checkAlloc(p, s, a)); + + s = 128; + a = MaxAlignV; + p = M.allocate(s); + assert(P.alloc_count == 2); + assert(P.checkAlloc(p, s, a)); + } +#ifndef TEST_HAS_NO_EXCEPTIONS + { + TestResource R2; + auto& P = R2.getController(); + P.throw_on_alloc = true; + memory_resource& M2 = R2; + try { + M2.allocate(42); + assert(false); + } catch (TestException const&) { + // do nothing. + } catch (...) { + assert(false); + } + } +#endif +} diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp new file mode 100644 index 00000000000..d1a4ab2b819 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/deallocate.pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <experimental/memory_resource> + +// UNSUPPORTED: c++98, c++03 + +//------------------------------------------------------------------------------ +// TESTING void * memory_resource::deallocate(void *, size_t, size_t = max_align) +// +// Concerns: +// A) 'memory_resource' contains a member 'deallocate' with the required +// signature, including the default alignment parameter. +// B) The return type of 'deallocate' is 'void'. +// C) 'deallocate' is not marked as 'noexcept'. +// D) Invoking 'deallocate' invokes 'do_deallocate' with the same arguments. + + +#include <experimental/memory_resource> +#include <type_traits> +#include <cstddef> +#include <cassert> + +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + NullResource R(42); + auto& P = R.getController(); + memory_resource& M = R; + { + static_assert( + std::is_same<decltype(M.deallocate(nullptr, 0, 0)), void>::value + , "Must be void" + ); + static_assert( + std::is_same<decltype(M.deallocate(nullptr, 0)), void>::value + , "Must be void" + ); + } + { + static_assert( + ! noexcept(M.deallocate(nullptr, 0, 0)) + , "Must not be noexcept." + ); + static_assert( + ! noexcept(M.deallocate(nullptr, 0)) + , "Must not be noexcept." + ); + } + { + int s = 100; + int a = 64; + void* p = reinterpret_cast<void*>(640); + M.deallocate(p, s, a); + assert(P.dealloc_count == 1); + assert(P.checkDealloc(p, s, a)); + + s = 128; + a = alignof(std::max_align_t); + p = reinterpret_cast<void*>(12800); + M.deallocate(p, s); + assert(P.dealloc_count == 2); + assert(P.checkDealloc(p, s, a)); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp new file mode 100644 index 00000000000..9e1d28618f9 --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/dtor.pass.cpp @@ -0,0 +1,59 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +//------------------------------------------------------------------------------ +// TESTING virtual ~memory_resource() +// +// Concerns: +// A) 'memory_resource' is destructible. +// B) The destructor is implicitly marked noexcept. +// C) The destructor is marked virtual. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> + +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + static_assert( + std::has_virtual_destructor<memory_resource>::value + , "Must have virtual destructor" + ); + static_assert( + std::is_nothrow_destructible<memory_resource>::value, + "Must be nothrow destructible" + ); + static_assert( + std::is_abstract<memory_resource>::value + , "Must be abstract" + ); + // Check that the destructor of `TestResource` is called when + // it is deleted as a pointer to `memory_resource` + { + using TR = TestResource; + memory_resource* M = new TR(42); + assert(TR::resource_alive == 1); + assert(TR::resource_constructed == 1); + assert(TR::resource_destructed == 0); + + delete M; + + assert(TR::resource_alive == 0); + assert(TR::resource_constructed == 1); + assert(TR::resource_destructed == 1); + } +} diff --git a/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp new file mode 100644 index 00000000000..32792cf867a --- /dev/null +++ b/libcxx/test/std/experimental/memory/memory.resource/memory.resource.public/is_equal.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// <experimental/memory_resource> + +//------------------------------------------------------------------------------ +// TESTING virtual bool is_equal(memory_resource const &) const noexcept +// +// Concerns: +// A) 'memory_resource' provides a function 'is_equal' with the required +// signature. +// B) 'is_equal' is noexcept. +// C) 'do_is_equal' is called using the same arguments passed to 'is_equal' +// and the resulting value is returned. +// D) 'do_is_equal' is called on the LHS object and not the RHS object. + +#include <experimental/memory_resource> +#include <type_traits> +#include <cassert> +#include "test_memory_resource.hpp" + +using std::experimental::pmr::memory_resource; + +int main() +{ + { + memory_resource const* r1 = nullptr; + memory_resource const* r2 = nullptr; + static_assert( + noexcept(r1->is_equal(*r2)) + , "is_equal must be noexcept" + ); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource2 R2(1); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == false); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == false); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource1 R2(2); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == false); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == false); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } + { + TestResource1 R1(1); + auto& P1 = R1.getController(); + memory_resource const& M1 = R1; + + TestResource1 R2(1); + auto& P2 = R2.getController(); + memory_resource const& M2 = R2; + + assert(M1.is_equal(M2) == true); + assert(P1.checkIsEqualCalledEq(1)); + assert(P2.checkIsEqualCalledEq(0)); + + assert(M2.is_equal(M1) == true); + assert(P2.checkIsEqualCalledEq(1)); + assert(P1.checkIsEqualCalledEq(1)); + } +} diff --git a/libcxx/test/std/experimental/memory/nothing_to_do.pass.cpp b/libcxx/test/std/experimental/memory/nothing_to_do.pass.cpp new file mode 100644 index 00000000000..9a59227abdd --- /dev/null +++ b/libcxx/test/std/experimental/memory/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} |