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 <MoveConstructible  R, MoveConstructible ... ArgTypes>
14089d54b5SMarshall Clow //   void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
155a83710eSEric Fiselier 
16b4fb705eSLouis Dionne // This test runs in C++03, but we have deprecated using std::function in C++03.
17*c475e31aSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
185a83710eSEric Fiselier 
195a83710eSEric Fiselier #include <functional>
205a83710eSEric Fiselier #include <cstdlib>
215a83710eSEric Fiselier #include <cassert>
225a83710eSEric Fiselier 
23089d54b5SMarshall Clow #include "test_macros.h"
24cc89063bSNico Weber #include "count_new.h"
255a83710eSEric Fiselier 
265a83710eSEric Fiselier class A
275a83710eSEric Fiselier {
285a83710eSEric Fiselier     int data_[10];
295a83710eSEric Fiselier public:
305a83710eSEric Fiselier     static int count;
315a83710eSEric Fiselier 
A(int j)325a83710eSEric Fiselier     explicit A(int j)
335a83710eSEric Fiselier     {
345a83710eSEric Fiselier         ++count;
355a83710eSEric Fiselier         data_[0] = j;
365a83710eSEric Fiselier     }
375a83710eSEric Fiselier 
A(const A & a)385a83710eSEric Fiselier     A(const A& a)
395a83710eSEric Fiselier     {
405a83710eSEric Fiselier         ++count;
415a83710eSEric Fiselier         for (int i = 0; i < 10; ++i)
425a83710eSEric Fiselier             data_[i] = a.data_[i];
435a83710eSEric Fiselier     }
445a83710eSEric Fiselier 
~A()455a83710eSEric Fiselier     ~A() {--count;}
465a83710eSEric Fiselier 
operator ()(int i) const475a83710eSEric Fiselier     int operator()(int i) const
485a83710eSEric Fiselier     {
495a83710eSEric Fiselier         for (int j = 0; j < 10; ++j)
505a83710eSEric Fiselier             i += data_[j];
515a83710eSEric Fiselier         return i;
525a83710eSEric Fiselier     }
535a83710eSEric Fiselier 
id() const545a83710eSEric Fiselier     int id() const {return data_[0];}
555a83710eSEric Fiselier };
565a83710eSEric Fiselier 
575a83710eSEric Fiselier int A::count = 0;
585a83710eSEric Fiselier 
g(int)595a83710eSEric Fiselier int g(int) {return 0;}
h(int)605a83710eSEric Fiselier int h(int) {return 1;}
615a83710eSEric Fiselier 
main(int,char **)622df59c50SJF Bastien int main(int, char**)
635a83710eSEric Fiselier {
649c5d0ea6SDan Albert     globalMemCounter.reset();
652cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
665a83710eSEric Fiselier     {
675a83710eSEric Fiselier     std::function<int(int)> f1 = A(1);
685a83710eSEric Fiselier     std::function<int(int)> f2 = A(2);
69089d54b5SMarshall Clow #if TEST_STD_VER >= 11
70089d54b5SMarshall Clow     static_assert(noexcept(swap(f1, f2)), "" );
71089d54b5SMarshall Clow #endif
725a83710eSEric Fiselier     assert(A::count == 2);
732cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(2));
74bb09ef95SLouis Dionne     RTTI_ASSERT(f1.target<A>()->id() == 1);
75bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>()->id() == 2);
765a83710eSEric Fiselier     swap(f1, f2);
775a83710eSEric Fiselier     assert(A::count == 2);
782cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(2));
79bb09ef95SLouis Dionne     RTTI_ASSERT(f1.target<A>()->id() == 2);
80bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>()->id() == 1);
815a83710eSEric Fiselier     }
825a83710eSEric Fiselier     assert(A::count == 0);
832cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
845a83710eSEric Fiselier     {
855a83710eSEric Fiselier     std::function<int(int)> f1 = A(1);
865a83710eSEric Fiselier     std::function<int(int)> f2 = g;
87089d54b5SMarshall Clow #if TEST_STD_VER >= 11
88089d54b5SMarshall Clow     static_assert(noexcept(swap(f1, f2)), "" );
89089d54b5SMarshall Clow #endif
905a83710eSEric Fiselier     assert(A::count == 1);
912cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(1));
92bb09ef95SLouis Dionne     RTTI_ASSERT(f1.target<A>()->id() == 1);
93bb09ef95SLouis Dionne     RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
945a83710eSEric Fiselier     swap(f1, f2);
955a83710eSEric Fiselier     assert(A::count == 1);
962cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(1));
97bb09ef95SLouis Dionne     RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
98bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>()->id() == 1);
995a83710eSEric Fiselier     }
1005a83710eSEric Fiselier     assert(A::count == 0);
1012cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
1025a83710eSEric Fiselier     {
1035a83710eSEric Fiselier     std::function<int(int)> f1 = g;
1045a83710eSEric Fiselier     std::function<int(int)> f2 = A(1);
105089d54b5SMarshall Clow #if TEST_STD_VER >= 11
106089d54b5SMarshall Clow     static_assert(noexcept(swap(f1, f2)), "" );
107089d54b5SMarshall Clow #endif
1085a83710eSEric Fiselier     assert(A::count == 1);
1092cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(1));
110bb09ef95SLouis Dionne     RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
111bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>()->id() == 1);
1125a83710eSEric Fiselier     swap(f1, f2);
1135a83710eSEric Fiselier     assert(A::count == 1);
1142cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(1));
115bb09ef95SLouis Dionne     RTTI_ASSERT(f1.target<A>()->id() == 1);
116bb09ef95SLouis Dionne     RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
1175a83710eSEric Fiselier     }
1185a83710eSEric Fiselier     assert(A::count == 0);
1192cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
1205a83710eSEric Fiselier     {
1215a83710eSEric Fiselier     std::function<int(int)> f1 = g;
1225a83710eSEric Fiselier     std::function<int(int)> f2 = h;
123089d54b5SMarshall Clow #if TEST_STD_VER >= 11
124089d54b5SMarshall Clow     static_assert(noexcept(swap(f1, f2)), "" );
125089d54b5SMarshall Clow #endif
1265a83710eSEric Fiselier     assert(A::count == 0);
1272cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
128bb09ef95SLouis Dionne     RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
129bb09ef95SLouis Dionne     RTTI_ASSERT(*f2.target<int(*)(int)>() == h);
1305a83710eSEric Fiselier     swap(f1, f2);
1315a83710eSEric Fiselier     assert(A::count == 0);
1322cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
133bb09ef95SLouis Dionne     RTTI_ASSERT(*f1.target<int(*)(int)>() == h);
134bb09ef95SLouis Dionne     RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
1355a83710eSEric Fiselier     }
1365a83710eSEric Fiselier     assert(A::count == 0);
1372cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
1382df59c50SJF Bastien 
1392df59c50SJF Bastien   return 0;
1405a83710eSEric Fiselier }
141