brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 5afc3ad Raw
175 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 11// <functional>12 13// class function<R(ArgTypes...)>14 15// function(const function&  f);16// function(function&& f); // noexcept in C++2017 18#include <functional>19#include <memory>20#include <cstdlib>21#include <cassert>22#include <utility>23 24#include "test_macros.h"25#include "count_new.h"26 27class A28{29    int data_[10];30public:31    static int count;32 33    A()34    {35        ++count;36        for (int i = 0; i < 10; ++i)37            data_[i] = i;38    }39 40    A(const A&) {++count;}41 42    ~A() {--count;}43 44    int operator()(int i) const45    {46        for (int j = 0; j < 10; ++j)47            i += data_[j];48        return i;49    }50};51 52int A::count = 0;53 54int g(int) {return 0;}55 56int main(int, char**)57{58    globalMemCounter.reset();59    assert(globalMemCounter.checkOutstandingNewEq(0));60    {61    std::function<int(int)> f = A();62    assert(A::count == 1);63    assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));64    RTTI_ASSERT(f.target<A>());65    RTTI_ASSERT(f.target<int(*)(int)>() == 0);66    std::function<int(int)> f2 = f;67    assert(A::count == 2);68    assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(2));69    RTTI_ASSERT(f2.target<A>());70    RTTI_ASSERT(f2.target<int(*)(int)>() == 0);71    }72    assert(A::count == 0);73    assert(globalMemCounter.checkOutstandingNewEq(0));74    {75    std::function<int(int)> f = g;76    assert(globalMemCounter.checkOutstandingNewEq(0));77    RTTI_ASSERT(f.target<int(*)(int)>());78    RTTI_ASSERT(f.target<A>() == 0);79    std::function<int(int)> f2 = f;80    assert(globalMemCounter.checkOutstandingNewEq(0));81    RTTI_ASSERT(f2.target<int(*)(int)>());82    RTTI_ASSERT(f2.target<A>() == 0);83    }84    assert(globalMemCounter.checkOutstandingNewEq(0));85    {86    std::function<int(int)> f;87    assert(globalMemCounter.checkOutstandingNewEq(0));88    RTTI_ASSERT(f.target<int(*)(int)>() == 0);89    RTTI_ASSERT(f.target<A>() == 0);90    std::function<int(int)> f2 = f;91    assert(globalMemCounter.checkOutstandingNewEq(0));92    RTTI_ASSERT(f2.target<int(*)(int)>() == 0);93    RTTI_ASSERT(f2.target<A>() == 0);94    }95    {96    std::function<int(int)> f;97    assert(globalMemCounter.checkOutstandingNewEq(0));98    RTTI_ASSERT(f.target<int(*)(int)>() == 0);99    RTTI_ASSERT(f.target<A>() == 0);100    assert(!f);101    std::function<long(int)> g = f;102    assert(globalMemCounter.checkOutstandingNewEq(0));103    RTTI_ASSERT(g.target<long(*)(int)>() == 0);104    RTTI_ASSERT(g.target<A>() == 0);105    assert(!g);106    }107#if TEST_STD_VER >= 11108    assert(globalMemCounter.checkOutstandingNewEq(0));109    { // Test rvalue references110        std::function<int(int)> f = A();111        assert(A::count == 1);112        assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));113        RTTI_ASSERT(f.target<A>());114        RTTI_ASSERT(f.target<int(*)(int)>() == 0);115        LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));116#if TEST_STD_VER > 17117        ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));118#endif119        std::function<int(int)> f2 = std::move(f);120        assert(A::count == 1);121        assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));122        RTTI_ASSERT(f2.target<A>());123        RTTI_ASSERT(f2.target<int(*)(int)>() == 0);124        RTTI_ASSERT(f.target<A>() == 0);125        RTTI_ASSERT(f.target<int(*)(int)>() == 0);126    }127    assert(globalMemCounter.checkOutstandingNewEq(0));128    {129        // Test that moving a function constructed from a reference wrapper130        // is done without allocating.131        DisableAllocationGuard g;132        using Ref = std::reference_wrapper<A>;133        A a;134        Ref aref(a);135        std::function<int(int)> f(aref);136        assert(A::count == 1);137        RTTI_ASSERT(f.target<A>() == nullptr);138        RTTI_ASSERT(f.target<Ref>());139        LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));140#if TEST_STD_VER > 17141        ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));142#endif143        std::function<int(int)> f2(std::move(f));144        assert(A::count == 1);145        RTTI_ASSERT(f2.target<A>() == nullptr);146        RTTI_ASSERT(f2.target<Ref>());147#if defined(_LIBCPP_VERSION)148        RTTI_ASSERT(f.target<Ref>()); // f is unchanged because the target is small149#endif150    }151    {152        // Test that moving a function constructed from a function pointer153        // is done without allocating154        DisableAllocationGuard guard;155        using Ptr = int(*)(int);156        Ptr p = g;157        std::function<int(int)> f(p);158        RTTI_ASSERT(f.target<A>() == nullptr);159        RTTI_ASSERT(f.target<Ptr>());160        LIBCPP_ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));161#if TEST_STD_VER > 17162        ASSERT_NOEXCEPT(std::function<int(int)>(std::move(f)));163#endif164        std::function<int(int)> f2(std::move(f));165        RTTI_ASSERT(f2.target<A>() == nullptr);166        RTTI_ASSERT(f2.target<Ptr>());167#if defined(_LIBCPP_VERSION)168        RTTI_ASSERT(f.target<Ptr>()); // f is unchanged because the target is small169#endif170    }171#endif // TEST_STD_VER >= 11172 173  return 0;174}175