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