Home | History | Annotate | Download | only in allocator.adaptor.members
      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 // UNSUPPORTED: c++98, c++03
     11 
     12 // <scoped_allocator>
     13 
     14 // template <class OtherAlloc, class ...InnerAlloc>
     15 //   class scoped_allocator_adaptor
     16 
     17 // template <class T, class ...Args>
     18 // void scoped_allocator_adaptor::construct(T*, Args&&...)
     19 
     20 #include <scoped_allocator>
     21 #include <type_traits>
     22 #include <utility>
     23 #include <tuple>
     24 #include <cassert>
     25 #include <cstdlib>
     26 #include "uses_alloc_types.hpp"
     27 #include "controlled_allocators.hpp"
     28 
     29 //  If uses_allocator_v<T, inner_allocator_type> is false and
     30 //   is_constructible_v<T, Args...> is true, calls
     31 //   OUTERMOST_ALLOC_TRAITS(*this)::construct(
     32 //      OUTERMOST (*this), p, std::forward<Args>(args)...).
     33 void test_bullet_one() {
     34     using VoidAlloc2 = CountingAllocator<void, 2>;
     35 
     36     AllocController POuter;
     37     AllocController PInner;
     38     {
     39         using T = NotUsesAllocator<VoidAlloc2, 3>;
     40         using Outer = CountingAllocator<T, 1>;
     41         using Inner = CountingAllocator<T, 2>;
     42         using SA = std::scoped_allocator_adaptor<Outer, Inner>;
     43         static_assert(!std::uses_allocator<T, Outer>::value, "");
     44         static_assert(!std::uses_allocator<T, Inner>::value, "");
     45         T* ptr = (T*)::operator new(sizeof(T));
     46         Outer O(POuter);
     47         Inner I(PInner);
     48         SA A(O, I);
     49         int x = 42;
     50         int const& cx = x;
     51         A.construct(ptr, x, cx, std::move(x));
     52         assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_None)));
     53         assert((POuter.checkConstruct<int&, int const&, int&&>(O, ptr)));
     54         A.destroy(ptr);
     55         ::operator delete((void*)ptr);
     56     }
     57     PInner.reset();
     58     POuter.reset();
     59 }
     60 
     61 
     62 // Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
     63 // is_constructible_v<T, allocator_arg_t, inner_allocator_type&, Args...> is
     64 // true, calls OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
     65 //     allocator_arg, inner_allocator(), std::forward<Args>(args)...).
     66 void test_bullet_two() {
     67     using VoidAlloc2 = CountingAllocator<void, 2>;
     68 
     69     AllocController POuter;
     70     AllocController PInner;
     71     {
     72         using T = UsesAllocatorV1<VoidAlloc2, 3>;
     73         using Outer = CountingAllocator<T, 1>;
     74         using Inner = CountingAllocator<T, 2>;
     75         using SA = std::scoped_allocator_adaptor<Outer, Inner>;
     76         static_assert(!std::uses_allocator<T, Outer>::value, "");
     77         static_assert(std::uses_allocator<T, Inner>::value, "");
     78         T* ptr = (T*)::operator new(sizeof(T));
     79         Outer O(POuter);
     80         Inner I(PInner);
     81         SA A(O, I);
     82         int x = 42;
     83         int const& cx = x;
     84         A.construct(ptr, x, cx, std::move(x));
     85         assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocArg, I)));
     86         assert((POuter.checkConstruct<std::allocator_arg_t const&,
     87                    SA::inner_allocator_type&, int&, int const&, int&&>(O, ptr)));
     88         A.destroy(ptr);
     89         ::operator delete((void*)ptr);
     90     }
     91     PInner.reset();
     92     POuter.reset();
     93 }
     94 
     95 // Otherwise, if uses_allocator_v<T, inner_allocator_type> is true and
     96 // is_constructible_v<T, Args..., inner_allocator_type&> is true, calls
     97 // OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST (*this), p,
     98 //   std::forward<Args>(args)..., inner_allocator()).
     99 void test_bullet_three() {
    100     using VoidAlloc2 = CountingAllocator<void, 2>;
    101 
    102     AllocController POuter;
    103     AllocController PInner;
    104     {
    105         using T = UsesAllocatorV2<VoidAlloc2, 3>;
    106         using Outer = CountingAllocator<T, 1>;
    107         using Inner = CountingAllocator<T, 2>;
    108         using SA = std::scoped_allocator_adaptor<Outer, Inner>;
    109         static_assert(!std::uses_allocator<T, Outer>::value, "");
    110         static_assert(std::uses_allocator<T, Inner>::value, "");
    111         T* ptr = (T*)::operator new(sizeof(T));
    112         Outer O(POuter);
    113         Inner I(PInner);
    114         SA A(O, I);
    115         int x = 42;
    116         int const& cx = x;
    117         A.construct(ptr, x, cx, std::move(x));
    118         assert((checkConstruct<int&, int const&, int&&>(*ptr, UA_AllocLast, I)));
    119         assert((POuter.checkConstruct<
    120                    int&, int const&, int&&,
    121                    SA::inner_allocator_type&>(O, ptr)));
    122         A.destroy(ptr);
    123         ::operator delete((void*)ptr);
    124     }
    125     PInner.reset();
    126     POuter.reset();
    127 }
    128 
    129 int main() {
    130     test_bullet_one();
    131     test_bullet_two();
    132     test_bullet_three();
    133 }
    134