1 | // Boost.Function library |
2 | |
3 | // Copyright Douglas Gregor 2001-2003. Use, modification and |
4 | // distribution is subject to the Boost Software License, Version |
5 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt) |
7 | |
8 | // For more information, see http://www.boost.org |
9 | |
10 | #include <boost/function.hpp> |
11 | #include <boost/core/lightweight_test.hpp> |
12 | #include <cassert> |
13 | #include <functional> |
14 | |
15 | using namespace std; |
16 | using namespace boost; |
17 | |
18 | static int alloc_count = 0; |
19 | static int dealloc_count = 0; |
20 | |
21 | template<typename T> |
22 | struct counting_allocator : public std::allocator<T> |
23 | { |
24 | template<typename U> |
25 | struct rebind |
26 | { |
27 | typedef counting_allocator<U> other; |
28 | }; |
29 | |
30 | counting_allocator() |
31 | { |
32 | } |
33 | |
34 | template<typename U> |
35 | counting_allocator( counting_allocator<U> ) |
36 | { |
37 | } |
38 | |
39 | T* allocate(std::size_t n) |
40 | { |
41 | alloc_count++; |
42 | return std::allocator<T>::allocate(n); |
43 | } |
44 | |
45 | void deallocate(T* p, std::size_t n) |
46 | { |
47 | dealloc_count++; |
48 | std::allocator<T>::deallocate(p, n); |
49 | } |
50 | }; |
51 | |
52 | struct enable_small_object_optimization |
53 | { |
54 | }; |
55 | |
56 | struct disable_small_object_optimization |
57 | { |
58 | int unused_state_data[32]; |
59 | }; |
60 | |
61 | template <typename base> |
62 | struct plus_int: base |
63 | { |
64 | int operator()(int x, int y) const { return x + y; } |
65 | }; |
66 | |
67 | static int do_minus(int x, int y) { return x-y; } |
68 | |
69 | template <typename base> |
70 | struct DoNothing: base |
71 | { |
72 | void operator()() const {} |
73 | }; |
74 | |
75 | static void do_nothing() {} |
76 | |
77 | int main() |
78 | { |
79 | function2<int, int, int> f; |
80 | f.assign( f: plus_int<disable_small_object_optimization>(), a: counting_allocator<int>() ); |
81 | f.clear(); |
82 | BOOST_TEST_EQ( alloc_count, 1 ); |
83 | BOOST_TEST_EQ( dealloc_count, 1 ); |
84 | alloc_count = 0; |
85 | dealloc_count = 0; |
86 | f.assign( f: plus_int<enable_small_object_optimization>(), a: counting_allocator<int>() ); |
87 | f.clear(); |
88 | BOOST_TEST_EQ( alloc_count, 0 ); |
89 | BOOST_TEST_EQ( dealloc_count, 0 ); |
90 | f.assign( f: plus_int<disable_small_object_optimization>(), a: std::allocator<int>() ); |
91 | f.clear(); |
92 | f.assign( f: plus_int<enable_small_object_optimization>(), a: std::allocator<int>() ); |
93 | f.clear(); |
94 | |
95 | alloc_count = 0; |
96 | dealloc_count = 0; |
97 | f.assign( f: &do_minus, a: counting_allocator<int>() ); |
98 | f.clear(); |
99 | BOOST_TEST_EQ( alloc_count, 0 ); |
100 | BOOST_TEST_EQ( dealloc_count, 0 ); |
101 | f.assign( f: &do_minus, a: std::allocator<int>() ); |
102 | f.clear(); |
103 | |
104 | function0<void> fv; |
105 | alloc_count = 0; |
106 | dealloc_count = 0; |
107 | fv.assign( f: DoNothing<disable_small_object_optimization>(), a: counting_allocator<int>() ); |
108 | fv.clear(); |
109 | BOOST_TEST_EQ( alloc_count, 1 ); |
110 | BOOST_TEST_EQ( dealloc_count, 1 ); |
111 | alloc_count = 0; |
112 | dealloc_count = 0; |
113 | fv.assign( f: DoNothing<enable_small_object_optimization>(), a: counting_allocator<int>() ); |
114 | fv.clear(); |
115 | BOOST_TEST_EQ( alloc_count, 0 ); |
116 | BOOST_TEST_EQ( dealloc_count, 0 ); |
117 | fv.assign( f: DoNothing<disable_small_object_optimization>(), a: std::allocator<int>() ); |
118 | fv.clear(); |
119 | fv.assign( f: DoNothing<enable_small_object_optimization>(), a: std::allocator<int>() ); |
120 | fv.clear(); |
121 | |
122 | alloc_count = 0; |
123 | dealloc_count = 0; |
124 | fv.assign( f: &do_nothing, a: counting_allocator<int>() ); |
125 | fv.clear(); |
126 | BOOST_TEST_EQ( alloc_count, 0 ); |
127 | BOOST_TEST_EQ( dealloc_count, 0 ); |
128 | fv.assign( f: &do_nothing, a: std::allocator<int>() ); |
129 | fv.clear(); |
130 | |
131 | function0<void> fv2; |
132 | fv.assign(f: &do_nothing, a: std::allocator<int>() ); |
133 | fv2.assign(f: fv, a: std::allocator<int>() ); |
134 | |
135 | return boost::report_errors(); |
136 | } |
137 | |