// Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and // is_constructible_v<T, Args..., inner_allocator_type&> is true, calls // OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p, // std::forward<Args>(args)..., inner_allocator()). void test_bullet_three() { using VoidAlloc2 = CountingAllocator<void, 2>; AllocController POuter; AllocController PInner; { using T = UsesAllocatorV2<VoidAlloc2, 3>; using Outer = CountingAllocator<T, 1>; using Inner = CountingAllocator<T, 2>; using SA = std::scoped_allocator_adaptor<Outer, Inner>; static_assert(!std::uses_allocator<T, Outer>::value, ""); static_assert(std::uses_allocator<T, Inner>::value, ""); T* ptr = (T*)::operator new(sizeof(T)); Outer O(POuter); Inner I(PInner); SA A(O, I); int x = 42; int const& cx = x; A.construct(ptr, x, cx, std::move(x)); assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocLast, I))); assert((POuter.checkConstruct< int&, int const&, int&&, SA::inner_allocator_type&>(O, ptr))); A.destroy(ptr); ::operator delete((void*)ptr); } PInner.reset(); POuter.reset(); }
void test_with_inner_alloc() { using VoidAlloc2 = CountingAllocator<void, 2>; AllocController POuter; AllocController PInner; { using T = UsesAllocatorV1<VoidAlloc2, 0>; using U = UsesAllocatorV2<VoidAlloc2, 0>; using Pair = std::pair<T, U>; using Outer = CountingAllocator<Pair, 1>; using Inner = CountingAllocator<Pair, 2>; using SA = std::scoped_allocator_adaptor<Outer, Inner>; using SAInner = std::scoped_allocator_adaptor<Inner>; static_assert(!std::uses_allocator<T, Outer>::value, ""); static_assert(std::uses_allocator<T, Inner>::value, ""); Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); assert(ptr); Outer O(POuter); Inner I(PInner); SA A(O, I); A.construct(ptr); assert(checkConstruct<>(ptr->first, UA_AllocArg, I)); assert(checkConstruct<>(ptr->second, UA_AllocLast)); assert((POuter.checkConstruct<std::piecewise_construct_t const&, std::tuple<std::allocator_arg_t, SAInner&>&&, std::tuple<SAInner&>&& >(O, ptr))); A.destroy(ptr); std::free(ptr); } PInner.reset(); POuter.reset(); { using T = UsesAllocatorV3<VoidAlloc2, 0>; using U = NotUsesAllocator<VoidAlloc2, 0>; using Pair = std::pair<T, U>; using Outer = CountingAllocator<Pair, 1>; using Inner = CountingAllocator<Pair, 2>; using SA = std::scoped_allocator_adaptor<Outer, Inner>; using SAInner = std::scoped_allocator_adaptor<Inner>; static_assert(!std::uses_allocator<T, Outer>::value, ""); static_assert(std::uses_allocator<T, Inner>::value, ""); Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); assert(ptr); Outer O(POuter); Inner I(PInner); SA A(O, I); A.construct(ptr); assert(checkConstruct<>(ptr->first, UA_AllocArg, I)); assert(checkConstruct<>(ptr->second, UA_None)); assert((POuter.checkConstruct<std::piecewise_construct_t const&, std::tuple<std::allocator_arg_t, SAInner&>&&, std::tuple<>&& >(O, ptr))); A.destroy(ptr); std::free(ptr); } }
void test_no_inner_alloc() { using VoidAlloc = CountingAllocator<void>; AllocController P; { using T = UsesAllocatorV1<VoidAlloc, 1>; using U = UsesAllocatorV2<VoidAlloc, 1>; using Pair = std::pair<T, U>; using PairIn = std::pair<int&, int const&&>; int x = 42; const int y = 101; using Alloc = CountingAllocator<Pair>; using SA = std::scoped_allocator_adaptor<Alloc>; static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); assert(ptr != nullptr); Alloc CA(P); SA A(CA); PairIn in(x, std::move(y)); A.construct(ptr, std::move(in)); assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA)); assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA)); assert((P.checkConstruct<std::piecewise_construct_t const&, std::tuple<std::allocator_arg_t, SA&, int&>&&, std::tuple<int const&&, SA&>&& >(CA, ptr))); A.destroy(ptr); std::free(ptr); } P.reset(); { using T = UsesAllocatorV3<VoidAlloc, 1>; using U = NotUsesAllocator<VoidAlloc, 1>; using Pair = std::pair<T, U>; using PairIn = std::pair<int, int const&>; int x = 42; const int y = 101; using Alloc = CountingAllocator<Pair>; using SA = std::scoped_allocator_adaptor<Alloc>; static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, ""); Pair * ptr = (Pair*)std::malloc(sizeof(Pair)); assert(ptr != nullptr); Alloc CA(P); SA A(CA); PairIn in(x, y); A.construct(ptr, std::move(in)); assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA)); assert(checkConstruct<int const&>(ptr->second, UA_None)); assert((P.checkConstruct<std::piecewise_construct_t const&, std::tuple<std::allocator_arg_t, SA&, int&&>&&, std::tuple<int const&>&& >(CA, ptr))); A.destroy(ptr); std::free(ptr); } }