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 A> function(allocator_arg_t, const A&, const function&);
     16 
     17 
     18 #include <functional>
     19 #include <cassert>
     20 
     21 #include "min_allocator.h"
     22 #include "test_allocator.h"
     23 #include "count_new.hpp"
     24 #include "../function_types.h"
     25 
     26 class DummyClass {};
     27 
     28 template <class FuncType, class AllocType>
     29 void test_FunctionObject(AllocType& alloc)
     30 {
     31     assert(globalMemCounter.checkOutstandingNewEq(0));
     32     {
     33     // Construct function from FunctionObject.
     34     std::function<FuncType> f = FunctionObject();
     35     assert(FunctionObject::count == 1);
     36     assert(globalMemCounter.checkOutstandingNewEq(1));
     37     assert(f.template target<FunctionObject>());
     38     assert(f.template target<FuncType>() == 0);
     39     assert(f.template target<FuncType*>() == 0);
     40     // Copy function with allocator
     41     std::function<FuncType> f2(std::allocator_arg, alloc, f);
     42     assert(FunctionObject::count == 2);
     43     assert(globalMemCounter.checkOutstandingNewEq(2));
     44     assert(f2.template target<FunctionObject>());
     45     assert(f2.template target<FuncType>() == 0);
     46     assert(f2.template target<FuncType*>() == 0);
     47     }
     48     assert(FunctionObject::count == 0);
     49     assert(globalMemCounter.checkOutstandingNewEq(0));
     50 }
     51 
     52 template <class FuncType, class AllocType>
     53 void test_FreeFunction(AllocType& alloc)
     54 {
     55     assert(globalMemCounter.checkOutstandingNewEq(0));
     56     {
     57     // Construct function from function pointer.
     58     FuncType* target = &FreeFunction;
     59     std::function<FuncType> f = target;
     60     assert(globalMemCounter.checkOutstandingNewEq(0));
     61     assert(f.template target<FuncType*>());
     62     assert(*f.template target<FuncType*>() == target);
     63     assert(f.template target<FuncType>() == 0);
     64     // Copy function with allocator
     65     std::function<FuncType> f2(std::allocator_arg, alloc, f);
     66     assert(globalMemCounter.checkOutstandingNewEq(0));
     67     assert(f2.template target<FuncType*>());
     68     assert(*f2.template target<FuncType*>() == target);
     69     assert(f2.template target<FuncType>() == 0);
     70     }
     71     assert(globalMemCounter.checkOutstandingNewEq(0));
     72 }
     73 
     74 template <class TargetType, class FuncType, class AllocType>
     75 void test_MemFunClass(AllocType& alloc)
     76 {
     77     assert(globalMemCounter.checkOutstandingNewEq(0));
     78     {
     79     // Construct function from function pointer.
     80     TargetType target = &MemFunClass::foo;
     81     std::function<FuncType> f = target;
     82     assert(globalMemCounter.checkOutstandingNewEq(0));
     83     assert(f.template target<TargetType>());
     84     assert(*f.template target<TargetType>() == target);
     85     assert(f.template target<FuncType*>() == 0);
     86     // Copy function with allocator
     87     std::function<FuncType> f2(std::allocator_arg, alloc, f);
     88     assert(globalMemCounter.checkOutstandingNewEq(0));
     89     assert(f2.template target<TargetType>());
     90     assert(*f2.template target<TargetType>() == target);
     91     assert(f2.template target<FuncType*>() == 0);
     92     }
     93     assert(globalMemCounter.checkOutstandingNewEq(0));
     94 }
     95 
     96 template <class Alloc>
     97 void test_for_alloc(Alloc& alloc)
     98 {
     99     // Large FunctionObject -- Allocation should occur
    100     test_FunctionObject<int()>(alloc);
    101     test_FunctionObject<int(int)>(alloc);
    102     test_FunctionObject<int(int, int)>(alloc);
    103     test_FunctionObject<int(int, int, int)>(alloc);
    104     // Free function -- No allocation should occur
    105     test_FreeFunction<int()>(alloc);
    106     test_FreeFunction<int(int)>(alloc);
    107     test_FreeFunction<int(int, int)>(alloc);
    108     test_FreeFunction<int(int, int, int)>(alloc);
    109     // Member function -- No allocation should occur.
    110     test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
    111     test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
    112     test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
    113 }
    114 
    115 int main()
    116 {
    117   {
    118     bare_allocator<DummyClass> alloc;
    119     test_for_alloc(alloc);
    120   }
    121   {
    122     non_default_test_allocator<DummyClass> alloc(42);
    123     test_for_alloc(alloc);
    124   }
    125 }
    126