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 U1, class U2, class ...Args1, class ...Args2> 18// void polymorphic_allocator<T>::construct(pair<U1, U2>*, piecewise_construct_t 19// tuple<Args1...>, tuple<Args2...>) 20 21#include <experimental/memory_resource> 22#include <type_traits> 23#include <utility> 24#include <tuple> 25#include <cassert> 26#include <cstdlib> 27 28#include "test_macros.h" 29#include "test_memory_resource.hpp" 30#include "uses_alloc_types.hpp" 31#include "controlled_allocators.hpp" 32#include "test_allocator.h" 33 34namespace ex = std::experimental::pmr; 35 36template <class T, class U, class ...TTuple, class ...UTuple> 37bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect, 38 std::tuple<TTuple...> ttuple, std::tuple<UTuple...> utuple) 39{ 40 using P = std::pair<T, U>; 41 TestResource R; 42 ex::memory_resource * M = &R; 43 ex::polymorphic_allocator<P> A(M); 44 P * ptr = A.allocate(1); 45 46 // UNDER TEST // 47 A.construct(ptr, std::piecewise_construct, std::move(ttuple), std::move(utuple)); 48 // ------- // 49 bool tres = checkConstruct<TTuple&&...>(ptr->first, TExpect, M); 50 bool ures = checkConstruct<UTuple&&...>(ptr->second, UExpect, M); 51 52 A.destroy(ptr); 53 A.deallocate(ptr, 1); 54 return tres && ures; 55} 56 57template <class Alloc, class ...TTypes, class ...UTypes> 58void test_pmr_uses_allocator(std::tuple<TTypes...> ttuple, std::tuple<UTypes...> utuple) 59{ 60 { 61 using T = NotUsesAllocator<Alloc, sizeof...(TTypes)>; 62 using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; 63 assert((doTest<T, U>(UA_None, UA_None, 64 std::move(ttuple), std::move(utuple)))); 65 } 66 { 67 using T = UsesAllocatorV1<Alloc, sizeof...(TTypes)>; 68 using U = UsesAllocatorV2<Alloc, sizeof...(UTypes)>; 69 assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, 70 std::move(ttuple), std::move(utuple)))); 71 } 72 { 73 using T = UsesAllocatorV2<Alloc, sizeof...(TTypes)>; 74 using U = UsesAllocatorV3<Alloc, sizeof...(UTypes)>; 75 assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, 76 std::move(ttuple), std::move(utuple)))); 77 } 78 { 79 using T = UsesAllocatorV3<Alloc, sizeof...(TTypes)>; 80 using U = NotUsesAllocator<Alloc, sizeof...(UTypes)>; 81 assert((doTest<T, U>(UA_AllocArg, UA_None, 82 std::move(ttuple), std::move(utuple)))); 83 } 84} 85 86int main() 87{ 88 using ERT = std::experimental::erased_type; 89 using PMR = ex::memory_resource*; 90 using PMA = ex::polymorphic_allocator<char>; 91 { 92 std::tuple<> t1; 93 test_pmr_uses_allocator<ERT>(t1, t1); 94 test_pmr_uses_allocator<PMR>(t1, t1); 95 test_pmr_uses_allocator<PMA>(t1, t1); 96 } 97 { 98 std::tuple<int> t1(42); 99 std::tuple<> t2; 100 test_pmr_uses_allocator<ERT>(t1, t2); 101 test_pmr_uses_allocator<ERT>(t2, t1); 102 test_pmr_uses_allocator<PMR>(t1, t2); 103 test_pmr_uses_allocator<PMR>(t2, t1); 104 test_pmr_uses_allocator<PMA>(t1, t2); 105 test_pmr_uses_allocator<PMA>(t2, t1); 106 } 107 { 108 std::tuple<int> t1(42); 109 int x = 55; 110 double dx = 42.42; 111 std::tuple<int&, double&&> t2(x, std::move(dx)); 112 test_pmr_uses_allocator<ERT>( t1, std::move(t2)); 113 test_pmr_uses_allocator<ERT>(std::move(t2), t1); 114 test_pmr_uses_allocator<PMR>( t1, std::move(t2)); 115 test_pmr_uses_allocator<PMR>(std::move(t2), t1); 116 test_pmr_uses_allocator<PMA>( t1, std::move(t2)); 117 test_pmr_uses_allocator<PMA>(std::move(t2), t1); 118 } 119 { 120 void* xptr = nullptr; 121 long y = 4242; 122 std::tuple<int, long const&, void*&> t1(42, y, xptr); 123 int x = 55; 124 double dx = 42.42; 125 const char* s = "hello World"; 126 std::tuple<int&, double&&, const char*> t2(x, std::move(dx), s); 127 test_pmr_uses_allocator<ERT>( t1, std::move(t2)); 128 test_pmr_uses_allocator<ERT>(std::move(t2), t1); 129 test_pmr_uses_allocator<PMR>( t1, std::move(t2)); 130 test_pmr_uses_allocator<PMR>(std::move(t2), t1); 131 test_pmr_uses_allocator<PMA>( t1, std::move(t2)); 132 test_pmr_uses_allocator<PMA>(std::move(t2), t1); 133 } 134} 135