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>*, 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 template <class UA1, class UA2, class TT, class UU>
     37 bool doTest(UsesAllocatorType TExpect, UsesAllocatorType UExpect,
     38             TT&& t, UU&& u)
     39 {
     40     using P = std::pair<UA1, UA2>;
     41     TestResource R;
     42     ex::memory_resource * M = &R;
     43     ex::polymorphic_allocator<P> A(M);
     44     P * ptr = (P*)std::malloc(sizeof(P));
     45     P * ptr2 = (P*)std::malloc(sizeof(P));
     46 
     47     // UNDER TEST //
     48     A.construct(ptr, std::forward<TT>(t), std::forward<UU>(u));
     49     A.construct(ptr2, std::piecewise_construct,
     50                       std::forward_as_tuple(std::forward<TT>(t)),
     51                       std::forward_as_tuple(std::forward<UU>(u)));
     52     // ------- //
     53 
     54     bool tres = checkConstruct<TT&&>(ptr->first, TExpect, M) &&
     55                 checkConstructionEquiv(ptr->first, ptr2->first);
     56 
     57     bool ures = checkConstruct<UU&&>(ptr->second, UExpect, M) &&
     58                 checkConstructionEquiv(ptr->second, ptr2->second);
     59 
     60     A.destroy(ptr);
     61     A.destroy(ptr2);
     62     std::free(ptr);
     63     std::free(ptr2);
     64     return tres && ures;
     65 }
     66 
     67 template <class Alloc, class TT, class UU>
     68 void test_pmr_uses_allocator(TT&& t, UU&& u)
     69 {
     70     {
     71         using T = NotUsesAllocator<Alloc, 1>;
     72         using U = NotUsesAllocator<Alloc, 1>;
     73         assert((doTest<T, U>(UA_None, UA_None,
     74                              std::forward<TT>(t), std::forward<UU>(u))));
     75     }
     76     {
     77         using T = UsesAllocatorV1<Alloc, 1>;
     78         using U = UsesAllocatorV2<Alloc, 1>;
     79         assert((doTest<T, U>(UA_AllocArg, UA_AllocLast,
     80                              std::forward<TT>(t), std::forward<UU>(u))));
     81     }
     82     {
     83         using T = UsesAllocatorV2<Alloc, 1>;
     84         using U = UsesAllocatorV3<Alloc, 1>;
     85         assert((doTest<T, U>(UA_AllocLast, UA_AllocArg,
     86                              std::forward<TT>(t), std::forward<UU>(u))));
     87     }
     88     {
     89         using T = UsesAllocatorV3<Alloc, 1>;
     90         using U = NotUsesAllocator<Alloc, 1>;
     91         assert((doTest<T, U>(UA_AllocArg, UA_None,
     92                              std::forward<TT>(t), std::forward<UU>(u))));
     93     }
     94 }
     95 
     96 int main()
     97 {
     98     using ERT = std::experimental::erased_type;
     99     using PMR = ex::memory_resource*;
    100     using PMA = ex::polymorphic_allocator<char>;
    101     {
    102         int x = 42;
    103         int y = 42;
    104         test_pmr_uses_allocator<ERT>(x, std::move(y));
    105         test_pmr_uses_allocator<PMR>(x, std::move(y));
    106         test_pmr_uses_allocator<PMA>(x, std::move(y));
    107     }
    108     {
    109         int x = 42;
    110         const int y = 42;
    111         test_pmr_uses_allocator<ERT>(std::move(x), y);
    112         test_pmr_uses_allocator<PMR>(std::move(x), y);
    113         test_pmr_uses_allocator<PMA>(std::move(x), y);
    114     }
    115 }
    116