swap.pass.cpp revision f5256e16dfc425c1d466f6308d4026d529ce9e0b
1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <functional>
11
12// class function<R(ArgTypes...)>
13
14// template <MoveConstructible  R, MoveConstructible ... ArgTypes>
15//   void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&);
16
17#include <functional>
18#include <new>
19#include <cstdlib>
20#include <cassert>
21
22int new_called = 0;
23
24void* operator new(std::size_t s) throw(std::bad_alloc)
25{
26    ++new_called;
27    return std::malloc(s);
28}
29
30void  operator delete(void* p) throw()
31{
32    --new_called;
33    std::free(p);
34}
35
36class A
37{
38    int data_[10];
39public:
40    static int count;
41
42    explicit A(int j)
43    {
44        ++count;
45        data_[0] = j;
46    }
47
48    A(const A& a)
49    {
50        ++count;
51        for (int i = 0; i < 10; ++i)
52            data_[i] = a.data_[i];
53    }
54
55    ~A() {--count;}
56
57    int operator()(int i) const
58    {
59        for (int j = 0; j < 10; ++j)
60            i += data_[j];
61        return i;
62    }
63
64    int id() const {return data_[0];}
65};
66
67int A::count = 0;
68
69int g(int) {return 0;}
70int h(int) {return 1;}
71
72int main()
73{
74    assert(new_called == 0);
75    {
76    std::function<int(int)> f1 = A(1);
77    std::function<int(int)> f2 = A(2);
78    assert(A::count == 2);
79    assert(new_called == 2);
80    assert(f1.target<A>()->id() == 1);
81    assert(f2.target<A>()->id() == 2);
82    swap(f1, f2);
83    assert(A::count == 2);
84    assert(new_called == 2);
85    assert(f1.target<A>()->id() == 2);
86    assert(f2.target<A>()->id() == 1);
87    }
88    assert(A::count == 0);
89    assert(new_called == 0);
90    {
91    std::function<int(int)> f1 = A(1);
92    std::function<int(int)> f2 = g;
93    assert(A::count == 1);
94    assert(new_called == 1);
95    assert(f1.target<A>()->id() == 1);
96    assert(*f2.target<int(*)(int)>() == g);
97    swap(f1, f2);
98    assert(A::count == 1);
99    assert(new_called == 1);
100    assert(*f1.target<int(*)(int)>() == g);
101    assert(f2.target<A>()->id() == 1);
102    }
103    assert(A::count == 0);
104    assert(new_called == 0);
105    {
106    std::function<int(int)> f1 = g;
107    std::function<int(int)> f2 = A(1);
108    assert(A::count == 1);
109    assert(new_called == 1);
110    assert(*f1.target<int(*)(int)>() == g);
111    assert(f2.target<A>()->id() == 1);
112    swap(f1, f2);
113    assert(A::count == 1);
114    assert(new_called == 1);
115    assert(f1.target<A>()->id() == 1);
116    assert(*f2.target<int(*)(int)>() == g);
117    }
118    assert(A::count == 0);
119    assert(new_called == 0);
120    {
121    std::function<int(int)> f1 = g;
122    std::function<int(int)> f2 = h;
123    assert(A::count == 0);
124    assert(new_called == 0);
125    assert(*f1.target<int(*)(int)>() == g);
126    assert(*f2.target<int(*)(int)>() == h);
127    swap(f1, f2);
128    assert(A::count == 0);
129    assert(new_called == 0);
130    assert(*f1.target<int(*)(int)>() == h);
131    assert(*f2.target<int(*)(int)>() == g);
132    }
133    assert(A::count == 0);
134    assert(new_called == 0);
135}
136