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