1 | // constructor_tests.cpp -- The Boost Lambda Library ------------------ |
2 | // |
3 | // Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) |
4 | // Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com) |
5 | // |
6 | // Distributed under the Boost Software License, Version 1.0. (See |
7 | // accompanying file LICENSE_1_0.txt or copy at |
8 | // http://www.boost.org/LICENSE_1_0.txt) |
9 | // |
10 | // For more information, see www.boost.org |
11 | |
12 | // ----------------------------------------------------------------------- |
13 | |
14 | |
15 | #include <boost/test/minimal.hpp> // see "Header Implementation Option" |
16 | |
17 | |
18 | #include "boost/lambda/lambda.hpp" |
19 | #include "boost/lambda/bind.hpp" |
20 | |
21 | #include "boost/lambda/construct.hpp" |
22 | |
23 | #include <iostream> |
24 | #include <algorithm> |
25 | #include <vector> |
26 | |
27 | #ifdef BOOST_MSVC |
28 | #pragma warning(disable:4512) |
29 | #endif |
30 | |
31 | using namespace boost::lambda; |
32 | namespace bl = boost::lambda; |
33 | |
34 | template<class T> |
35 | bool check_tuple(int n, const T& t) |
36 | { |
37 | return (t.get_head() == n) && check_tuple(n+1, t.get_tail()); |
38 | } |
39 | |
40 | template <> |
41 | bool check_tuple(int /*n*/, const null_type& ) { return true; } |
42 | |
43 | |
44 | void constructor_all_lengths() |
45 | { |
46 | bool ok; |
47 | ok = check_tuple( |
48 | n: 1, |
49 | t: bind(a1: constructor<tuple<int> >(), |
50 | a2: 1)() |
51 | ); |
52 | BOOST_CHECK(ok); |
53 | |
54 | ok = check_tuple( |
55 | n: 1, |
56 | t: bind(a1: constructor<tuple<int, int> >(), |
57 | a2: 1, a3: 2)() |
58 | ); |
59 | BOOST_CHECK(ok); |
60 | |
61 | ok = check_tuple( |
62 | n: 1, |
63 | t: bind(a1: constructor<tuple<int, int, int> >(), |
64 | a2: 1, a3: 2, a4: 3)() |
65 | ); |
66 | BOOST_CHECK(ok); |
67 | |
68 | ok = check_tuple( |
69 | n: 1, |
70 | t: bind(a1: constructor<tuple<int, int, int, int> >(), |
71 | a2: 1, a3: 2, a4: 3, a5: 4)() |
72 | ); |
73 | BOOST_CHECK(ok); |
74 | |
75 | ok = check_tuple( |
76 | n: 1, |
77 | t: bind(a1: constructor<tuple<int, int, int, int, int> >(), |
78 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5)() |
79 | ); |
80 | BOOST_CHECK(ok); |
81 | |
82 | ok = check_tuple( |
83 | n: 1, |
84 | t: bind(a1: constructor<tuple<int, int, int, int, int, int> >(), |
85 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6)() |
86 | ); |
87 | BOOST_CHECK(ok); |
88 | |
89 | ok = check_tuple( |
90 | n: 1, |
91 | t: bind(a1: constructor<tuple<int, int, int, int, int, int, int> >(), |
92 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6, a8: 7)() |
93 | ); |
94 | BOOST_CHECK(ok); |
95 | |
96 | ok = check_tuple( |
97 | n: 1, |
98 | t: bind(a1: constructor<tuple<int, int, int, int, int, int, int, int> >(), |
99 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6, a8: 7, a9: 8)() |
100 | ); |
101 | BOOST_CHECK(ok); |
102 | |
103 | ok = check_tuple( |
104 | n: 1, |
105 | t: bind(a1: constructor<tuple<int, int, int, int, int, int, int, int, int> >(), |
106 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6, a8: 7, a9: 8, a10: 9)() |
107 | ); |
108 | BOOST_CHECK(ok); |
109 | |
110 | } |
111 | |
112 | void new_ptr_all_lengths() |
113 | { |
114 | bool ok; |
115 | ok = check_tuple( |
116 | n: 1, |
117 | t: *(bind(a1: new_ptr<tuple<int> >(), |
118 | a2: 1))() |
119 | ); |
120 | BOOST_CHECK(ok); |
121 | |
122 | ok = check_tuple( |
123 | n: 1, |
124 | t: *(bind(a1: new_ptr<tuple<int, int> >(), |
125 | a2: 1, a3: 2))() |
126 | ); |
127 | BOOST_CHECK(ok); |
128 | |
129 | ok = check_tuple( |
130 | n: 1, |
131 | t: *(bind(a1: new_ptr<tuple<int, int, int> >(), |
132 | a2: 1, a3: 2, a4: 3))() |
133 | ); |
134 | BOOST_CHECK(ok); |
135 | |
136 | ok = check_tuple( |
137 | n: 1, |
138 | t: *(bind(a1: new_ptr<tuple<int, int, int, int> >(), |
139 | a2: 1, a3: 2, a4: 3, a5: 4))() |
140 | ); |
141 | BOOST_CHECK(ok); |
142 | |
143 | ok = check_tuple( |
144 | n: 1, |
145 | t: *(bind(a1: new_ptr<tuple<int, int, int, int, int> >(), |
146 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5))() |
147 | ); |
148 | BOOST_CHECK(ok); |
149 | |
150 | ok = check_tuple( |
151 | n: 1, |
152 | t: *(bind(a1: new_ptr<tuple<int, int, int, int, int, int> >(), |
153 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6))() |
154 | ); |
155 | BOOST_CHECK(ok); |
156 | |
157 | ok = check_tuple( |
158 | n: 1, |
159 | t: *(bind(a1: new_ptr<tuple<int, int, int, int, int, int, int> >(), |
160 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6, a8: 7))() |
161 | ); |
162 | BOOST_CHECK(ok); |
163 | |
164 | ok = check_tuple( |
165 | n: 1, |
166 | t: *(bind(a1: new_ptr<tuple<int, int, int, int, int, int, int, int> >(), |
167 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6, a8: 7, a9: 8))() |
168 | ); |
169 | BOOST_CHECK(ok); |
170 | |
171 | ok = check_tuple( |
172 | n: 1, |
173 | t: *(bind(a1: new_ptr<tuple<int, int, int, int, int, int, int, int, int> >(), |
174 | a2: 1, a3: 2, a4: 3, a5: 4, a6: 5, a7: 6, a8: 7, a9: 8, a10: 9))() |
175 | ); |
176 | BOOST_CHECK(ok); |
177 | |
178 | } |
179 | |
180 | class is_destructor_called { |
181 | bool& b; |
182 | public: |
183 | is_destructor_called(bool& bb) : b(bb) { b = false; } |
184 | ~is_destructor_called() { b = true; } |
185 | }; |
186 | |
187 | void test_destructor () |
188 | { |
189 | char space[sizeof(is_destructor_called)]; |
190 | bool flag = false; |
191 | |
192 | is_destructor_called* idc = new(space) is_destructor_called(flag); |
193 | BOOST_CHECK(flag == false); |
194 | bind(a1: destructor(), a2: _1)(idc); |
195 | BOOST_CHECK(flag == true); |
196 | |
197 | idc = new(space) is_destructor_called(flag); |
198 | BOOST_CHECK(flag == false); |
199 | bind(a1: destructor(), a2: _1)(*idc); |
200 | BOOST_CHECK(flag == true); |
201 | } |
202 | |
203 | |
204 | class count_deletes { |
205 | public: |
206 | static int count; |
207 | ~count_deletes() { ++count; } |
208 | }; |
209 | |
210 | int count_deletes::count = 0; |
211 | |
212 | void test_news_and_deletes () |
213 | { |
214 | int* i[10]; |
215 | std::for_each(first: i, last: i+10, f: _1 = bind(a1: new_ptr<int>(), a2: 2)); |
216 | int count_errors = 0; |
217 | |
218 | std::for_each(first: i, last: i+10, f: (*_1 == 2) || ++var(t&: count_errors)); |
219 | BOOST_CHECK(count_errors == 0); |
220 | |
221 | |
222 | count_deletes* ct[10]; |
223 | std::for_each(first: ct, last: ct+10, f: _1 = bind(a1: new_ptr<count_deletes>())); |
224 | count_deletes::count = 0; |
225 | std::for_each(first: ct, last: ct+10, f: bind(a1: delete_ptr(), a2: _1)); |
226 | BOOST_CHECK(count_deletes::count == 10); |
227 | |
228 | } |
229 | |
230 | void test_array_new_and_delete() |
231 | { |
232 | count_deletes* c; |
233 | (_1 = bind(a1: new_array<count_deletes>(), a2: 5))(c); |
234 | count_deletes::count = 0; |
235 | |
236 | bind(a1: delete_array(), a2: _1)(c); |
237 | BOOST_CHECK(count_deletes::count == 5); |
238 | } |
239 | |
240 | |
241 | void delayed_construction() |
242 | { |
243 | std::vector<int> x(3); |
244 | std::vector<int> y(3); |
245 | |
246 | std::fill(first: x.begin(), last: x.end(), value: 0); |
247 | std::fill(first: y.begin(), last: y.end(), value: 1); |
248 | |
249 | std::vector<std::pair<int, int> > v; |
250 | |
251 | std::transform(first1: x.begin(), last1: x.end(), first2: y.begin(), result: std::back_inserter(x&: v), |
252 | binary_op: bl::bind(a1: constructor<std::pair<int, int> >(), a2: _1, a3: _2) ); |
253 | } |
254 | |
255 | int test_main(int, char *[]) { |
256 | |
257 | constructor_all_lengths(); |
258 | new_ptr_all_lengths(); |
259 | delayed_construction(); |
260 | test_destructor(); |
261 | test_news_and_deletes(); |
262 | test_array_new_and_delete(); |
263 | |
264 | return 0; |
265 | } |
266 | |