15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier
95a83710eSEric Fiselier // <functional>
105a83710eSEric Fiselier
115a83710eSEric Fiselier // class function<R(ArgTypes...)>
125a83710eSEric Fiselier
135a83710eSEric Fiselier // template<class F>
145a83710eSEric Fiselier // requires CopyConstructible<F> && Callable<F, ArgTypes..>
155a83710eSEric Fiselier // && Convertible<Callable<F, ArgTypes...>::result_type
165a83710eSEric Fiselier // operator=(F f);
175a83710eSEric Fiselier
18b4fb705eSLouis Dionne // This test runs in C++03, but we have deprecated using std::function in C++03.
19*c475e31aSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
20b4fb705eSLouis Dionne
215a83710eSEric Fiselier #include <functional>
225a83710eSEric Fiselier #include <cassert>
235a83710eSEric Fiselier
24790df145SEric Fiselier #include "test_macros.h"
25cc89063bSNico Weber #include "count_new.h"
265a83710eSEric Fiselier
275a83710eSEric Fiselier class A
285a83710eSEric Fiselier {
295a83710eSEric Fiselier int data_[10];
305a83710eSEric Fiselier public:
315a83710eSEric Fiselier static int count;
325a83710eSEric Fiselier
A()335a83710eSEric Fiselier A()
345a83710eSEric Fiselier {
355a83710eSEric Fiselier ++count;
365a83710eSEric Fiselier for (int i = 0; i < 10; ++i)
375a83710eSEric Fiselier data_[i] = i;
385a83710eSEric Fiselier }
395a83710eSEric Fiselier
A(const A &)405a83710eSEric Fiselier A(const A&) {++count;}
415a83710eSEric Fiselier
~A()425a83710eSEric Fiselier ~A() {--count;}
435a83710eSEric Fiselier
operator ()(int i) const445a83710eSEric Fiselier int operator()(int i) const
455a83710eSEric Fiselier {
465a83710eSEric Fiselier for (int j = 0; j < 10; ++j)
475a83710eSEric Fiselier i += data_[j];
485a83710eSEric Fiselier return i;
495a83710eSEric Fiselier }
505a83710eSEric Fiselier
foo(int) const515a83710eSEric Fiselier int foo(int) const {return 1;}
525a83710eSEric Fiselier };
535a83710eSEric Fiselier
545a83710eSEric Fiselier int A::count = 0;
555a83710eSEric Fiselier
g(int)565a83710eSEric Fiselier int g(int) {return 0;}
575a83710eSEric Fiselier
58790df145SEric Fiselier #if TEST_STD_VER >= 11
59790df145SEric Fiselier struct RValueCallable {
60790df145SEric Fiselier template <class ...Args>
operator ()RValueCallable61790df145SEric Fiselier void operator()(Args&&...) && {}
62790df145SEric Fiselier };
63790df145SEric Fiselier struct LValueCallable {
64790df145SEric Fiselier template <class ...Args>
operator ()LValueCallable65790df145SEric Fiselier void operator()(Args&&...) & {}
66790df145SEric Fiselier };
67790df145SEric Fiselier #endif
68790df145SEric Fiselier
main(int,char **)692df59c50SJF Bastien int main(int, char**)
705a83710eSEric Fiselier {
719c5d0ea6SDan Albert globalMemCounter.reset();
722cbc654dSEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
735a83710eSEric Fiselier {
745a83710eSEric Fiselier std::function<int(int)> f;
755a83710eSEric Fiselier f = A();
765a83710eSEric Fiselier assert(A::count == 1);
772cbc654dSEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(1));
78bb09ef95SLouis Dionne RTTI_ASSERT(f.target<A>());
79bb09ef95SLouis Dionne RTTI_ASSERT(f.target<int(*)(int)>() == 0);
805a83710eSEric Fiselier }
815a83710eSEric Fiselier assert(A::count == 0);
822cbc654dSEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
835a83710eSEric Fiselier {
845a83710eSEric Fiselier std::function<int(int)> f;
855a83710eSEric Fiselier f = g;
862cbc654dSEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
87bb09ef95SLouis Dionne RTTI_ASSERT(f.target<int(*)(int)>());
88bb09ef95SLouis Dionne RTTI_ASSERT(f.target<A>() == 0);
895a83710eSEric Fiselier }
902cbc654dSEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
915a83710eSEric Fiselier {
925a83710eSEric Fiselier std::function<int(int)> f;
935a83710eSEric Fiselier f = (int (*)(int))0;
945a83710eSEric Fiselier assert(!f);
952cbc654dSEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
96bb09ef95SLouis Dionne RTTI_ASSERT(f.target<int(*)(int)>() == 0);
97bb09ef95SLouis Dionne RTTI_ASSERT(f.target<A>() == 0);
985a83710eSEric Fiselier }
995a83710eSEric Fiselier {
1005a83710eSEric Fiselier std::function<int(const A*, int)> f;
1015a83710eSEric Fiselier f = &A::foo;
1025a83710eSEric Fiselier assert(f);
1032cbc654dSEric Fiselier assert(globalMemCounter.checkOutstandingNewEq(0));
104bb09ef95SLouis Dionne RTTI_ASSERT(f.target<int (A::*)(int) const>() != 0);
1055a83710eSEric Fiselier }
10654519a6bSEric Fiselier {
10754519a6bSEric Fiselier std::function<void(int)> f;
10854519a6bSEric Fiselier f = &g;
10954519a6bSEric Fiselier assert(f);
110bb09ef95SLouis Dionne RTTI_ASSERT(f.target<int(*)(int)>() != 0);
11154519a6bSEric Fiselier f(1);
11254519a6bSEric Fiselier }
113790df145SEric Fiselier #if TEST_STD_VER >= 11
114790df145SEric Fiselier {
115790df145SEric Fiselier using Fn = std::function<void(int, int, int)>;
116790df145SEric Fiselier static_assert(std::is_assignable<Fn&, LValueCallable&>::value, "");
117790df145SEric Fiselier static_assert(std::is_assignable<Fn&, LValueCallable>::value, "");
118790df145SEric Fiselier static_assert(!std::is_assignable<Fn&, RValueCallable&>::value, "");
119790df145SEric Fiselier static_assert(!std::is_assignable<Fn&, RValueCallable>::value, "");
120790df145SEric Fiselier }
1218aa2266fSzoecarver {
1228aa2266fSzoecarver using Fn = std::function<void(int, int, int)>;
1238aa2266fSzoecarver static_assert(std::is_assignable<Fn&, Fn&&>::value, "");
1248aa2266fSzoecarver }
1258aa2266fSzoecarver {
1268aa2266fSzoecarver using F1 = std::function<void(int, int)>;
1278aa2266fSzoecarver using F2 = std::function<void(int, int, int)>;
1288aa2266fSzoecarver static_assert(!std::is_assignable<F1&, F2&&>::value, "");
1298aa2266fSzoecarver }
1308aa2266fSzoecarver {
1318aa2266fSzoecarver using F1 = std::function<int(int, int)>;
1328aa2266fSzoecarver using F2 = std::function<A (int, int)>;
1338aa2266fSzoecarver static_assert(!std::is_assignable<F1&, F2&&>::value, "");
1348aa2266fSzoecarver static_assert(!std::is_assignable<F2&, F1&&>::value, "");
1358aa2266fSzoecarver }
136790df145SEric Fiselier #endif
1372df59c50SJF Bastien
1382df59c50SJF Bastien return 0;
1395a83710eSEric Fiselier }
140