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>
     18 // void scoped_allocator_adaptor::construct(pair<U1, U2>*, pair<T1, T2>&&)
     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         using PairIn = std::pair<int&, int const&&>;
     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         PairIn in(x, std::move(y));
     49         A.construct(ptr, std::move(in));
     50         assert(checkConstruct<int&>(ptr->first, UA_AllocArg, CA));
     51         assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast, CA));
     52         assert((P.checkConstruct<std::piecewise_construct_t const&,
     53                                  std::tuple<std::allocator_arg_t, SA&, int&>&&,
     54                                  std::tuple<int const&&, SA&>&&
     55               >(CA, ptr)));
     56         A.destroy(ptr);
     57         std::free(ptr);
     58 
     59     }
     60     P.reset();
     61     {
     62         using T = UsesAllocatorV3<VoidAlloc, 1>;
     63         using U = NotUsesAllocator<VoidAlloc, 1>;
     64         using Pair = std::pair<T, U>;
     65         using PairIn = std::pair<int, int const&>;
     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         PairIn in(x, y);
     76         A.construct(ptr, std::move(in));
     77         assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, CA));
     78         assert(checkConstruct<int const&>(ptr->second, UA_None));
     79         assert((P.checkConstruct<std::piecewise_construct_t const&,
     80                                  std::tuple<std::allocator_arg_t, SA&, int&&>&&,
     81                                  std::tuple<int const&>&&
     82                    >(CA, ptr)));
     83         A.destroy(ptr);
     84         std::free(ptr);
     85     }
     86 }
     87 
     88 void test_with_inner_alloc()
     89 {
     90     using VoidAlloc2 = CountingAllocator<void, 2>;
     91 
     92     AllocController POuter;
     93     AllocController PInner;
     94     {
     95         using T = UsesAllocatorV1<VoidAlloc2, 1>;
     96         using U = UsesAllocatorV2<VoidAlloc2, 1>;
     97         using Pair = std::pair<T, U>;
     98         using PairIn = std::pair<int&, int const&&>;
     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         PairIn in(x, std::move(y));
    113         A.construct(ptr, std::move(in));
    114         assert(checkConstruct<int&>(ptr->first, UA_AllocArg, I));
    115         assert(checkConstruct<int const&&>(ptr->second, UA_AllocLast));
    116         assert((POuter.checkConstruct<std::piecewise_construct_t const&,
    117                                  std::tuple<std::allocator_arg_t, SAInner&, int&>&&,
    118                                  std::tuple<int const&&, SAInner&>&&
    119               >(O, ptr)));
    120         A.destroy(ptr);
    121         std::free(ptr);
    122     }
    123     PInner.reset();
    124     POuter.reset();
    125     {
    126         using T = UsesAllocatorV3<VoidAlloc2, 1>;
    127         using U = NotUsesAllocator<VoidAlloc2, 1>;
    128         using Pair = std::pair<T, U>;
    129         using PairIn = std::pair<int, int const &>;
    130         int x = 42;
    131         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         PairIn in(x, y);
    144         A.construct(ptr, std::move(in));
    145         assert(checkConstruct<int&&>(ptr->first, UA_AllocArg, I));
    146         assert(checkConstruct<int const&>(ptr->second, UA_None));
    147         assert((POuter.checkConstruct<std::piecewise_construct_t const&,
    148                                  std::tuple<std::allocator_arg_t, SAInner&, int&&>&&,
    149                                  std::tuple<int const&>&&
    150               >(O, ptr)));
    151         A.destroy(ptr);
    152         std::free(ptr);
    153     }
    154 }
    155 int main() {
    156     test_no_inner_alloc();
    157     test_with_inner_alloc();
    158 }
    159