Home | History | Annotate | Download | only in memory.polymorphic.allocator.mem
      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 // REQUIRES: c++experimental
     11 // UNSUPPORTED: c++98, c++03
     12 
     13 // <experimental/memory_resource>
     14 
     15 // template <class T> class polymorphic_allocator
     16 
     17 // template <class P1, class P2, class U1, class U2>
     18 // void polymorphic_allocator<T>::construct(pair<P1, P2>*, pair<U1, U2> &&)
     19 
     20 #include <experimental/memory_resource>
     21 #include <type_traits>
     22 #include <utility>
     23 #include <tuple>
     24 #include <cassert>
     25 #include <cstdlib>
     26 
     27 #include "test_macros.h"
     28 #include "test_memory_resource.hpp"
     29 #include "uses_alloc_types.hpp"
     30 #include "controlled_allocators.hpp"
     31 #include "test_allocator.h"
     32 
     33 namespace ex = std::experimental::pmr;
     34 
     35 
     36 
     37 template <class UA1, class UA2, class TT, class UU>
     38 bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect,
     39             std::pair<TT, UU>&& p)
     40 {
     41     using P = std::pair<UA1, UA2>;
     42     TestResource R;
     43     ex::memory_resource * M = &R;
     44     ex::polymorphic_allocator<P> A(M);
     45     P * ptr  = A.allocate(2);
     46     P * ptr2 = ptr + 1;
     47 
     48     // UNDER TEST //
     49     A.construct(ptr, std::move(p));
     50 
     51     A.construct(ptr2, std::piecewise_construct,
     52                 std::forward_as_tuple(std::forward<TT>(p.first)),
     53                 std::forward_as_tuple(std::forward<UU>(p.second)));
     54     // ------- //
     55 
     56     bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) &&
     57                 checkConstructionEquiv(ptr->first, ptr2->first);
     58 
     59     bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) &&
     60                 checkConstructionEquiv(ptr->second, ptr2->second);
     61 
     62     A.destroy(ptr);
     63     A.destroy(ptr2);
     64     A.deallocate(ptr, 2);
     65     return tres && ures;
     66 }
     67 
     68 template <class Alloc, class TT, class UU>
     69 void test_pmr_uses_allocator(std::pair<TT, UU>&& p)
     70 {
     71     {
     72         using T = NotUsesAllocator<Alloc, 1>;
     73         using U = NotUsesAllocator<Alloc, 1>;
     74         assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
     75     }
     76     {
     77         using T = UsesAllocatorV1<Alloc, 1>;
     78         using U = UsesAllocatorV2<Alloc, 1>;
     79         assert((doTest<T, U>(UA_AllocArg, UA_AllocLast, std::move(p))));
     80     }
     81     {
     82         using T = UsesAllocatorV2<Alloc, 1>;
     83         using U = UsesAllocatorV3<Alloc, 1>;
     84         assert((doTest<T, U>(UA_AllocLast, UA_AllocArg, std::move(p))));
     85     }
     86     {
     87         using T = UsesAllocatorV3<Alloc, 1>;
     88         using U = NotUsesAllocator<Alloc, 1>;
     89         assert((doTest<T, U>(UA_AllocArg, UA_None, std::move(p))));
     90     }
     91 }
     92 
     93 template <class Alloc, class TT, class UU>
     94 void test_pmr_not_uses_allocator(std::pair<TT, UU>&& p)
     95 {
     96     {
     97         using T = NotUsesAllocator<Alloc, 1>;
     98         using U = NotUsesAllocator<Alloc, 1>;
     99         assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
    100     }
    101     {
    102         using T = UsesAllocatorV1<Alloc, 1>;
    103         using U = UsesAllocatorV2<Alloc, 1>;
    104         assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
    105     }
    106     {
    107         using T = UsesAllocatorV2<Alloc, 1>;
    108         using U = UsesAllocatorV3<Alloc, 1>;
    109         assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
    110     }
    111     {
    112         using T = UsesAllocatorV3<Alloc, 1>;
    113         using U = NotUsesAllocator<Alloc, 1>;
    114         assert((doTest<T, U>(UA_None, UA_None, std::move(p))));
    115     }
    116 }
    117 
    118 int main()
    119 {
    120     using ERT = std::experimental::erased_type;
    121     using PMR = ex::memory_resource*;
    122     using PMA = ex::polymorphic_allocator<char>;
    123     {
    124         int x = 42;
    125         int y = 42;
    126         std::pair<int&, int&&> p(x, std::move(y));
    127         test_pmr_uses_allocator<ERT>(std::move(p));
    128         test_pmr_not_uses_allocator<PMR>(std::move(p));
    129         test_pmr_uses_allocator<PMA>(std::move(p));
    130     }
    131     {
    132         int x = 42;
    133         int y = 42;
    134         std::pair<int&&, int&> p(std::move(x), y);
    135         test_pmr_uses_allocator<ERT>(std::move(p));
    136         test_pmr_not_uses_allocator<PMR>(std::move(p));
    137         test_pmr_uses_allocator<PMA>(std::move(p));
    138     }
    139 }
    140