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 U1, class U2, class Tp, class Vp>
     18 // void scoped_allocator_adaptor::construct(pair<U1, U2>*, Tp&&, Up&&)
     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 
     30 void test_no_inner_alloc()
     31 {
     32     using VoidAlloc = CountingAllocator<void>;
     33     AllocController P;
     34     {
     35         using T = UsesAllocatorV1<VoidAlloc, 1>;
     36         using U = UsesAllocatorV2<VoidAlloc, 1>;
     37         using Pair = std::pair<T, U>;
     38         int x = 42;
     39         const int y = 101;
     40         using Alloc = CountingAllocator<Pair>;
     41         using SA = std::scoped_allocator_adaptor<Alloc>;
     42         static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
     43         Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
     44         assert(ptr != nullptr);
     45         Alloc CA(P);
     46         SA A(CA);
     47         A.construct(ptr, x, std::move(y));
     48         assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
     49         assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
     50         assert((P.checkConstruct<std::piecewise_construct_t const&,
     51                                  std::tuple<std::allocator_arg_t, SA&, int&>&&,
     52                                  std::tuple<int const&&, SA&>&&
     53               >(CA, ptr)));
     54         A.destroy(ptr);
     55         std::free(ptr);
     56 
     57     }
     58     P.reset();
     59     {
     60         using T = UsesAllocatorV3<VoidAlloc, 1>;
     61         using U = NotUsesAllocator<VoidAlloc, 1>;
     62         using Pair = std::pair<T, U>;
     63         int x = 42;
     64         const int y = 101;
     65         using Alloc = CountingAllocator<Pair>;
     66         using SA = std::scoped_allocator_adaptor<Alloc>;
     67         static_assert(std::uses_allocator<T, CountingAllocator<T> >::value, "");
     68         Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
     69         assert(ptr != nullptr);
     70         Alloc CA(P);
     71         SA A(CA);
     72         A.construct(ptr, std::move(x), y);
     73         assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
     74         assert(checkConstruct<int const&>(ptr->second, UA_None));
     75         assert((P.checkConstruct<std::piecewise_construct_t const&,
     76                                  std::tuple<std::allocator_arg_t, SA&, int&&>&&,
     77                                  std::tuple<int const&>&&
     78                    >(CA, ptr)));
     79         A.destroy(ptr);
     80         std::free(ptr);
     81     }
     82 }
     83 
     84 void test_with_inner_alloc()
     85 {
     86     using VoidAlloc2 = CountingAllocator<void, 2>;
     87 
     88     AllocController POuter;
     89     AllocController PInner;
     90     {
     91         using T = UsesAllocatorV1<VoidAlloc2, 1>;
     92         using U = UsesAllocatorV2<VoidAlloc2, 1>;
     93         using Pair = std::pair<T, U>;
     94         int x = 42;
     95         int y = 101;
     96         using Outer = CountingAllocator<Pair, 1>;
     97         using Inner = CountingAllocator<Pair, 2>;
     98         using SA = std::scoped_allocator_adaptor<Outer, Inner>;
     99         using SAInner = std::scoped_allocator_adaptor<Inner>;
    100         static_assert(!std::uses_allocator<T, Outer>::value, "");
    101         static_assert(std::uses_allocator<T, Inner>::value, "");
    102         Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
    103         assert(ptr != nullptr);
    104         Outer O(POuter);
    105         Inner I(PInner);
    106         SA A(O, I);
    107         A.construct(ptr, x, std::move(y));
    108         assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
    109         assert(checkConstruct<int &&>(ptr->second, UA_AllocLast));
    110         assert((POuter.checkConstruct<std::piecewise_construct_t const&,
    111                                  std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
    112                                  std::tuple<int &&, SAInner&>&&
    113               >(O, ptr)));
    114         A.destroy(ptr);
    115         std::free(ptr);
    116     }
    117     PInner.reset();
    118     POuter.reset();
    119     {
    120         using T = UsesAllocatorV3<VoidAlloc2, 1>;
    121         using U = NotUsesAllocator<VoidAlloc2, 1>;
    122         using Pair = std::pair<T, U>;
    123         int x = 42;
    124         const int y = 101;
    125         using Outer = CountingAllocator<Pair, 1>;
    126         using Inner = CountingAllocator<Pair, 2>;
    127         using SA = std::scoped_allocator_adaptor<Outer, Inner>;
    128         using SAInner = std::scoped_allocator_adaptor<Inner>;
    129         static_assert(!std::uses_allocator<T, Outer>::value, "");
    130         static_assert(std::uses_allocator<T, Inner>::value, "");
    131         Pair * ptr = (Pair*)std::malloc(sizeof(Pair));
    132         assert(ptr != nullptr);
    133         Outer O(POuter);
    134         Inner I(PInner);
    135         SA A(O, I);
    136         A.construct(ptr, std::move(x), std::move(y));
    137         assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
    138         assert(checkConstruct<int const&&>(ptr->second, UA_None));
    139         assert((POuter.checkConstruct<std::piecewise_construct_t const&,
    140                                  std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
    141                                  std::tuple<int const&&>&&
    142               >(O, ptr)));
    143         A.destroy(ptr);
    144         std::free(ptr);
    145     }
    146 }
    147 int main() {
    148     test_no_inner_alloc();
    149     test_with_inner_alloc();
    150 }
    151