1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // REQUIRES: c++experimental 11 // UNSUPPORTED: c++98, c++03 12 13 // <experimental/memory_resource> 14 15 // template <class T> class polymorphic_allocator 16 17 // template <class P1, class P2, class U1, class U2> 18 // void polymorphic_allocator<T>::construct(pair<P1, P2>*, U1&&, U2&&) 19 20 #include <experimental/memory_resource> 21 #include <type_traits> 22 #include <utility> 23 #include <tuple> 24 #include <cassert> 25 #include <cstdlib> 26 27 #include "test_macros.h" 28 #include "test_memory_resource.hpp" 29 #include "uses_alloc_types.hpp" 30 #include "controlled_allocators.hpp" 31 #include "test_allocator.h" 32 33 namespace ex = std::experimental::pmr; 34 35 36 template <class UA1, class UA2, class TT, class UU> 37 bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, 38 TT&& t, UU&& u) 39 { 40 using P = std::pair<UA1, UA2>; 41 TestResource R; 42 ex::memory_resource * M = &R; 43 ex::polymorphic_allocator<P> A(M); 44 P * ptr = (P*)std::malloc(sizeof(P)); 45 P * ptr2 = (P*)std::malloc(sizeof(P)); 46 47 // UNDER TEST // 48 A.construct(ptr, std::forward<TT>(t), std::forward<UU>(u)); 49 A.construct(ptr2, std::piecewise_construct, 50 std::forward_as_tuple(std::forward<TT>(t)), 51 std::forward_as_tuple(std::forward<UU>(u))); 52 // ------- // 53 54 bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) && 55 checkConstructionEquiv(ptr->first, ptr2->first); 56 57 bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) && 58 checkConstructionEquiv(ptr->second, ptr2->second); 59 60 A.destroy(ptr); 61 A.destroy(ptr2); 62 std::free(ptr); 63 std::free(ptr2); 64 return tres && ures; 65 } 66 67 template <class Alloc, class TT, class UU> 68 void test_pmr_uses_allocator(TT&& t, UU&& u) 69 { 70 { 71 using T = NotUsesAllocator<Alloc, 1>; 72 using U = NotUsesAllocator<Alloc, 1>; 73 assert((doTest<T, U>(UA_None, UA_None, 74 std::forward<TT>(t), std::forward<UU>(u)))); 75 } 76 { 77 using T = UsesAllocatorV1<Alloc, 1>; 78 using U = UsesAllocatorV2<Alloc, 1>; 79 assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, 80 std::forward<TT>(t), std::forward<UU>(u)))); 81 } 82 { 83 using T = UsesAllocatorV2<Alloc, 1>; 84 using U = UsesAllocatorV3<Alloc, 1>; 85 assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, 86 std::forward<TT>(t), std::forward<UU>(u)))); 87 } 88 { 89 using T = UsesAllocatorV3<Alloc, 1>; 90 using U = NotUsesAllocator<Alloc, 1>; 91 assert((doTest<T, U>(UA_AllocArg, UA_None, 92 std::forward<TT>(t), std::forward<UU>(u)))); 93 } 94 } 95 96 int main() 97 { 98 using ERT = std::experimental::erased_type; 99 using PMR = ex::memory_resource*; 100 using PMA = ex::polymorphic_allocator<char>; 101 { 102 int x = 42; 103 int y = 42; 104 test_pmr_uses_allocator<ERT>(x, std::move(y)); 105 test_pmr_uses_allocator<PMR>(x, std::move(y)); 106 test_pmr_uses_allocator<PMA>(x, std::move(y)); 107 } 108 { 109 int x = 42; 110 const int y = 42; 111 test_pmr_uses_allocator<ERT>(std::move(x), y); 112 test_pmr_uses_allocator<PMR>(std::move(x), y); 113 test_pmr_uses_allocator<PMA>(std::move(x), y); 114 } 115 } 116