Home | History | Annotate | Download | only in func.wrap.func.con
      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 // <functional>
     11 // REQUIRES: c++98 || c++03 || c++11 ||c++14
     12 
     13 // class function<R(ArgTypes...)>
     14 
     15 // template<class F, class A> function(allocator_arg_t, const A&, F);
     16 
     17 #include <functional>
     18 #include <cassert>
     19 
     20 #include "test_macros.h"
     21 #include "min_allocator.h"
     22 #include "test_allocator.h"
     23 #include "count_new.hpp"
     24 #include "../function_types.h"
     25 
     26 
     27 #if TEST_STD_VER >= 11
     28 struct RValueCallable {
     29     template <class ...Args>
     30     void operator()(Args&&...) && {}
     31 };
     32 struct LValueCallable {
     33     template <class ...Args>
     34     void operator()(Args&&...) & {}
     35 };
     36 #endif
     37 
     38 class DummyClass {};
     39 
     40 template <class FuncType, class AllocType>
     41 void test_FunctionObject(AllocType& alloc)
     42 {
     43     assert(globalMemCounter.checkOutstandingNewEq(0));
     44     {
     45     FunctionObject target;
     46     assert(FunctionObject::count == 1);
     47     assert(globalMemCounter.checkOutstandingNewEq(0));
     48     std::function<FuncType> f2(std::allocator_arg, alloc, target);
     49     assert(FunctionObject::count == 2);
     50     assert(globalMemCounter.checkOutstandingNewEq(1));
     51     assert(f2.template target<FunctionObject>());
     52     assert(f2.template target<FuncType>() == 0);
     53     assert(f2.template target<FuncType*>() == 0);
     54     }
     55     assert(FunctionObject::count == 0);
     56     assert(globalMemCounter.checkOutstandingNewEq(0));
     57 }
     58 
     59 
     60 template <class FuncType, class AllocType>
     61 void test_FreeFunction(AllocType& alloc)
     62 {
     63     assert(globalMemCounter.checkOutstandingNewEq(0));
     64     {
     65     FuncType* target = &FreeFunction;
     66     assert(globalMemCounter.checkOutstandingNewEq(0));
     67     std::function<FuncType> f2(std::allocator_arg, alloc, target);
     68     assert(globalMemCounter.checkOutstandingNewEq(0));
     69     assert(f2.template target<FuncType*>());
     70     assert(*f2.template target<FuncType*>() == target);
     71     assert(f2.template target<FuncType>() == 0);
     72     assert(f2.template target<DummyClass>() == 0);
     73     }
     74     assert(globalMemCounter.checkOutstandingNewEq(0));
     75 }
     76 
     77 template <class TargetType, class FuncType, class AllocType>
     78 void test_MemFunClass(AllocType& alloc)
     79 {
     80     assert(globalMemCounter.checkOutstandingNewEq(0));
     81     {
     82     TargetType target = &MemFunClass::foo;
     83     assert(globalMemCounter.checkOutstandingNewEq(0));
     84     std::function<FuncType> f2(std::allocator_arg, alloc, target);
     85     assert(globalMemCounter.checkOutstandingNewEq(0));
     86     assert(f2.template target<TargetType>());
     87     assert(*f2.template target<TargetType>() == target);
     88     assert(f2.template target<FuncType*>() == 0);
     89     }
     90     assert(globalMemCounter.checkOutstandingNewEq(0));
     91 }
     92 
     93 template <class Alloc>
     94 void test_for_alloc(Alloc& alloc) {
     95     test_FunctionObject<int()>(alloc);
     96     test_FunctionObject<int(int)>(alloc);
     97     test_FunctionObject<int(int, int)>(alloc);
     98     test_FunctionObject<int(int, int, int)>(alloc);
     99 
    100     test_FreeFunction<int()>(alloc);
    101     test_FreeFunction<int(int)>(alloc);
    102     test_FreeFunction<int(int, int)>(alloc);
    103     test_FreeFunction<int(int, int, int)>(alloc);
    104 
    105     test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
    106     test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
    107     test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
    108 }
    109 
    110 int main()
    111 {
    112     {
    113         bare_allocator<DummyClass> bare_alloc;
    114         test_for_alloc(bare_alloc);
    115     }
    116     {
    117         non_default_test_allocator<DummyClass> non_default_alloc(42);
    118         test_for_alloc(non_default_alloc);
    119     }
    120 #if TEST_STD_VER >= 11
    121     {
    122         using Fn = std::function<void(int, int, int)>;
    123         static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable&>::value, "");
    124         static_assert(std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, LValueCallable>::value, "");
    125         static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable&>::value, "");
    126         static_assert(!std::is_constructible<Fn, std::allocator_arg_t, std::allocator<int>, RValueCallable>::value, "");
    127     }
    128 #endif
    129 
    130 }
    131