139 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// template<class F>16// requires CopyConstructible<F> && Callable<F, ArgTypes..>17// && Convertible<Callable<F, ArgTypes...>::result_type18// operator=(F f);19 20#include <functional>21#include <cassert>22 23#include "test_macros.h"24#include "count_new.h"25 26class A27{28 int data_[10];29public:30 static int count;31 32 A()33 {34 ++count;35 for (int i = 0; i < 10; ++i)36 data_[i] = i;37 }38 39 A(const A&) {++count;}40 41 ~A() {--count;}42 43 int operator()(int i) const44 {45 for (int j = 0; j < 10; ++j)46 i += data_[j];47 return i;48 }49 50 int foo(int) const {return 1;}51};52 53int A::count = 0;54 55int g(int) {return 0;}56 57#if TEST_STD_VER >= 1158struct RValueCallable {59 template <class ...Args>60 void operator()(Args&&...) && {}61};62struct LValueCallable {63 template <class ...Args>64 void operator()(Args&&...) & {}65};66#endif67 68int main(int, char**)69{70 globalMemCounter.reset();71 assert(globalMemCounter.checkOutstandingNewEq(0));72 {73 std::function<int(int)> f;74 f = A();75 assert(A::count == 1);76 assert(globalMemCounter.checkOutstandingNewEq(1));77 RTTI_ASSERT(f.target<A>());78 RTTI_ASSERT(f.target<int(*)(int)>() == 0);79 }80 assert(A::count == 0);81 assert(globalMemCounter.checkOutstandingNewEq(0));82 {83 std::function<int(int)> f;84 f = g;85 assert(globalMemCounter.checkOutstandingNewEq(0));86 RTTI_ASSERT(f.target<int(*)(int)>());87 RTTI_ASSERT(f.target<A>() == 0);88 }89 assert(globalMemCounter.checkOutstandingNewEq(0));90 {91 std::function<int(int)> f;92 f = (int (*)(int))0;93 assert(!f);94 assert(globalMemCounter.checkOutstandingNewEq(0));95 RTTI_ASSERT(f.target<int(*)(int)>() == 0);96 RTTI_ASSERT(f.target<A>() == 0);97 }98 {99 std::function<int(const A*, int)> f;100 f = &A::foo;101 assert(f);102 assert(globalMemCounter.checkOutstandingNewEq(0));103 RTTI_ASSERT(f.target<int (A::*)(int) const>() != 0);104 }105 {106 std::function<void(int)> f;107 f = &g;108 assert(f);109 RTTI_ASSERT(f.target<int(*)(int)>() != 0);110 f(1);111 }112#if TEST_STD_VER >= 11113 {114 using Fn = std::function<void(int, int, int)>;115 static_assert(std::is_assignable<Fn&, LValueCallable&>::value, "");116 static_assert(std::is_assignable<Fn&, LValueCallable>::value, "");117 static_assert(!std::is_assignable<Fn&, RValueCallable&>::value, "");118 static_assert(!std::is_assignable<Fn&, RValueCallable>::value, "");119 }120 {121 using Fn = std::function<void(int, int, int)>;122 static_assert(std::is_assignable<Fn&, Fn&&>::value, "");123 }124 {125 using F1 = std::function<void(int, int)>;126 using F2 = std::function<void(int, int, int)>;127 static_assert(!std::is_assignable<F1&, F2&&>::value, "");128 }129 {130 using F1 = std::function<int(int, int)>;131 using F2 = std::function<A (int, int)>;132 static_assert(!std::is_assignable<F1&, F2&&>::value, "");133 static_assert(!std::is_assignable<F2&, F1&&>::value, "");134 }135#endif136 137 return 0;138}139