brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 7ccb678 Raw
113 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++0310// REQUIRES: c++11 || c++1411 12// <functional>13 14// class function<R(ArgTypes...)>15 16// template<class A> function(allocator_arg_t, const A&, function&&);17//18// This signature was removed in C++1719 20#include <functional>21#include <memory>22#include <cassert>23 24#include "test_macros.h"25#include "min_allocator.h"26#include "count_new.h"27 28class A29{30    int data_[10];31public:32    static int count;33 34    A()35    {36        ++count;37        for (int i = 0; i < 10; ++i)38            data_[i] = i;39    }40 41    A(const A&) {++count;}42 43    ~A() {--count;}44 45    int operator()(int i) const46    {47        for (int j = 0; j < 10; ++j)48            i += data_[j];49        return i;50    }51};52 53int A::count = 0;54 55int g(int) { return 0; }56 57int main(int, char**)58{59  globalMemCounter.reset();60  assert(globalMemCounter.checkOutstandingNewEq(0));61  {62    std::function<int(int)> f = A();63    assert(A::count == 1);64    assert(globalMemCounter.checkOutstandingNewEq(1));65    RTTI_ASSERT(f.target<A>());66    RTTI_ASSERT(f.target<int (*)(int)>() == 0);67    std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(),68                               std::move(f));69    assert(A::count == 1);70    assert(globalMemCounter.checkOutstandingNewEq(1));71    RTTI_ASSERT(f2.target<A>());72    RTTI_ASSERT(f2.target<int (*)(int)>() == 0);73    RTTI_ASSERT(f.target<A>() == 0);74    RTTI_ASSERT(f.target<int (*)(int)>() == 0);75  }76    assert(globalMemCounter.checkOutstandingNewEq(0));77    {78        // Test that moving a function constructed from a reference wrapper79        // is done without allocating.80        DisableAllocationGuard g;81        using Ref = std::reference_wrapper<A>;82        A a;83        Ref aref(a);84        std::function<int(int)> f(aref);85        assert(A::count == 1);86        RTTI_ASSERT(f.target<A>() == nullptr);87        RTTI_ASSERT(f.target<Ref>());88        std::function<int(int)> f2(std::allocator_arg, std::allocator<int>{},89                                   std::move(f));90        assert(A::count == 1);91        RTTI_ASSERT(f2.target<A>() == nullptr);92        RTTI_ASSERT(f2.target<Ref>());93        RTTI_ASSERT(f.target<Ref>()); // f is unchanged because the target is small94    }95    {96        // Test that moving a function constructed from a function pointer97        // is done without allocating98        DisableAllocationGuard guard;99        using Ptr = int(*)(int);100        Ptr p = g;101        std::function<int(int)> f(p);102        RTTI_ASSERT(f.target<A>() == nullptr);103        RTTI_ASSERT(f.target<Ptr>());104        std::function<int(int)> f2(std::allocator_arg, std::allocator<int>(),105                                   std::move(f));106        RTTI_ASSERT(f2.target<A>() == nullptr);107        RTTI_ASSERT(f2.target<Ptr>());108        RTTI_ASSERT(f.target<Ptr>()); // f is unchanged because the target is small109    }110 111  return 0;112}113