1ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier//===----------------------------------------------------------------------===// 2ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// 3ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// The LLVM Compiler Infrastructure 4ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// 5ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open 6ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// Source Licenses. See LICENSE.TXT for details. 7ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// 8ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier//===----------------------------------------------------------------------===// 9ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 10ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// UNSUPPORTED: c++98, c++03 11ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 12ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// <scoped_allocator> 13ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 14ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// template <class OtherAlloc, class ...InnerAlloc> 15ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// class scoped_allocator_adaptor 16ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 17ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// template <class U1, class U2, class ...Args1, class ...Args2> 18ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// void scoped_allocator_adaptor::construct(pair<U1, U2>*, 19ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier// piecewise_construct_t, tuple<Args1...>, tuple<Args2...>) 20ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 21ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include <scoped_allocator> 22ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include <type_traits> 23ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include <utility> 24ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include <tuple> 25ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include <cassert> 26ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include <cstdlib> 27ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include "uses_alloc_types.hpp" 28ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier#include "controlled_allocators.hpp" 29ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 30ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 31ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiseliervoid test_no_inner_alloc() 32ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier{ 33ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using VoidAlloc = CountingAllocator<void>; 34ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier AllocController P; 35ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier { 36ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using T = UsesAllocatorV1<VoidAlloc, 1>; 37ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using U = UsesAllocatorV2<VoidAlloc, 1>; 38ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Pair = std::pair<T, U>; 39ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier int x = 42; 40ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier const int y = 101; 41ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Alloc = CountingAllocator<Pair>; 42ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using SA = std::scoped_allocator_adaptor<Alloc>; 43ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 44ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 453169d4a451aef7929cc5bc399d1a089e127868a4Stephan T. Lavavej assert(ptr != nullptr); 46ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Alloc CA(P); 47ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier SA A(CA); 48ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.construct(ptr, std::piecewise_construct, 49ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(x), 50ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(std::move(y))); 51ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA)); 52ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA)); 53ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert((P.checkConstruct<std::piecewise_construct_t const&, 54ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<std::allocator_arg_t, SA&, int&>&&, 55ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<int const&&, SA&>&& 56ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier >(CA, ptr))); 57ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.destroy(ptr); 58ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::free(ptr); 59ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 60ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier } 61ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier P.reset(); 62ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier { 63ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using T = UsesAllocatorV3<VoidAlloc, 1>; 64ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using U = NotUsesAllocator<VoidAlloc, 1>; 65ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Pair = std::pair<T, U>; 66ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier int x = 42; 67ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier const int y = 101; 68ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Alloc = CountingAllocator<Pair>; 69ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using SA = std::scoped_allocator_adaptor<Alloc>; 70ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); 71ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 723169d4a451aef7929cc5bc399d1a089e127868a4Stephan T. Lavavej assert(ptr != nullptr); 73ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Alloc CA(P); 74ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier SA A(CA); 75ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.construct(ptr, std::piecewise_construct, 76ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(std::move(x)), 77ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(y)); 78ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA)); 79ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int const&>(ptr->second, UA_None)); 80ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert((P.checkConstruct<std::piecewise_construct_t const&, 81ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<std::allocator_arg_t, SA&, int&&>&&, 82ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<int const&>&& 83ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier >(CA, ptr))); 84ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.destroy(ptr); 85ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::free(ptr); 86ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier } 87ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier} 88ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 89ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiseliervoid test_with_inner_alloc() 90ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier{ 91ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using VoidAlloc2 = CountingAllocator<void, 2>; 92ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier 93ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier AllocController POuter; 94ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier AllocController PInner; 95ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier { 96ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using T = UsesAllocatorV1<VoidAlloc2, 1>; 97ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using U = UsesAllocatorV2<VoidAlloc2, 1>; 98ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Pair = std::pair<T, U>; 99ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier int x = 42; 100ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier int y = 101; 101ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Outer = CountingAllocator<Pair, 1>; 102ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Inner = CountingAllocator<Pair, 2>; 103ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using SA = std::scoped_allocator_adaptor<Outer, Inner>; 104ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using SAInner = std::scoped_allocator_adaptor<Inner>; 105ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier static_assert(!std::uses_allocator<T, Outer>::value, ""); 106ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier static_assert(std::uses_allocator<T, Inner>::value, ""); 107ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 1083169d4a451aef7929cc5bc399d1a089e127868a4Stephan T. Lavavej assert(ptr != nullptr); 109ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Outer O(POuter); 110ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Inner I(PInner); 111ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier SA A(O, I); 112ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.construct(ptr, std::piecewise_construct, 113ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(x), 114ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(std::move(y))); 115ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I)); 116ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int &&>(ptr->second, UA_AllocLast)); 117ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert((POuter.checkConstruct<std::piecewise_construct_t const&, 118ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<std::allocator_arg_t, SAInner&, int&>&&, 119ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<int &&, SAInner&>&& 120ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier >(O, ptr))); 121ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.destroy(ptr); 122ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::free(ptr); 123ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier } 124ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier PInner.reset(); 125ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier POuter.reset(); 126ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier { 127ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using T = UsesAllocatorV3<VoidAlloc2, 1>; 128ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using U = NotUsesAllocator<VoidAlloc2, 1>; 129ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Pair = std::pair<T, U>; 130ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier int x = 42; 131ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier const int y = 101; 132ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Outer = CountingAllocator<Pair, 1>; 133ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using Inner = CountingAllocator<Pair, 2>; 134ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using SA = std::scoped_allocator_adaptor<Outer, Inner>; 135ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier using SAInner = std::scoped_allocator_adaptor<Inner>; 136ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier static_assert(!std::uses_allocator<T, Outer>::value, ""); 137ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier static_assert(std::uses_allocator<T, Inner>::value, ""); 138ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); 1393169d4a451aef7929cc5bc399d1a089e127868a4Stephan T. Lavavej assert(ptr != nullptr); 140ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Outer O(POuter); 141ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier Inner I(PInner); 142ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier SA A(O, I); 143ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.construct(ptr, std::piecewise_construct, 144ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(std::move(x)), 145ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::forward_as_tuple(std::move(y))); 146ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I)); 147ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert(checkConstruct<int const&&>(ptr->second, UA_None)); 148ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier assert((POuter.checkConstruct<std::piecewise_construct_t const&, 149ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<std::allocator_arg_t, SAInner&, int&&>&&, 150ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::tuple<int const&&>&& 151ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier >(O, ptr))); 152ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier A.destroy(ptr); 153ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier std::free(ptr); 154ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier } 155ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier} 156ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselierint main() { 157ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier test_no_inner_alloc(); 158ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier test_with_inner_alloc(); 159ff62475dcdf8fd5bebdce7fa61c81038db4f2fa7Eric Fiselier} 160