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
31using namespace boost::lambda;
32namespace bl = boost::lambda;
33
34template<class T>
35bool check_tuple(int n, const T& t)
36{
37 return (t.get_head() == n) && check_tuple(n+1, t.get_tail());
38}
39
40template <>
41bool check_tuple(int /*n*/, const null_type& ) { return true; }
42
43
44void constructor_all_lengths()
45{
46 bool ok;
47 ok = check_tuple(
48 1,
49 bind(constructor<tuple<int> >(),
50 1)()
51 );
52 BOOST_CHECK(ok);
53
54 ok = check_tuple(
55 1,
56 bind(constructor<tuple<int, int> >(),
57 1, 2)()
58 );
59 BOOST_CHECK(ok);
60
61 ok = check_tuple(
62 1,
63 bind(constructor<tuple<int, int, int> >(),
64 1, 2, 3)()
65 );
66 BOOST_CHECK(ok);
67
68 ok = check_tuple(
69 1,
70 bind(constructor<tuple<int, int, int, int> >(),
71 1, 2, 3, 4)()
72 );
73 BOOST_CHECK(ok);
74
75 ok = check_tuple(
76 1,
77 bind(constructor<tuple<int, int, int, int, int> >(),
78 1, 2, 3, 4, 5)()
79 );
80 BOOST_CHECK(ok);
81
82 ok = check_tuple(
83 1,
84 bind(constructor<tuple<int, int, int, int, int, int> >(),
85 1, 2, 3, 4, 5, 6)()
86 );
87 BOOST_CHECK(ok);
88
89 ok = check_tuple(
90 1,
91 bind(constructor<tuple<int, int, int, int, int, int, int> >(),
92 1, 2, 3, 4, 5, 6, 7)()
93 );
94 BOOST_CHECK(ok);
95
96 ok = check_tuple(
97 1,
98 bind(constructor<tuple<int, int, int, int, int, int, int, int> >(),
99 1, 2, 3, 4, 5, 6, 7, 8)()
100 );
101 BOOST_CHECK(ok);
102
103 ok = check_tuple(
104 1,
105 bind(constructor<tuple<int, int, int, int, int, int, int, int, int> >(),
106 1, 2, 3, 4, 5, 6, 7, 8, 9)()
107 );
108 BOOST_CHECK(ok);
109
110}
111
112void new_ptr_all_lengths()
113{
114 bool ok;
115 ok = check_tuple(
116 1,
117 *(bind(new_ptr<tuple<int> >(),
118 1))()
119 );
120 BOOST_CHECK(ok);
121
122 ok = check_tuple(
123 1,
124 *(bind(new_ptr<tuple<int, int> >(),
125 1, 2))()
126 );
127 BOOST_CHECK(ok);
128
129 ok = check_tuple(
130 1,
131 *(bind(new_ptr<tuple<int, int, int> >(),
132 1, 2, 3))()
133 );
134 BOOST_CHECK(ok);
135
136 ok = check_tuple(
137 1,
138 *(bind(new_ptr<tuple<int, int, int, int> >(),
139 1, 2, 3, 4))()
140 );
141 BOOST_CHECK(ok);
142
143 ok = check_tuple(
144 1,
145 *(bind(new_ptr<tuple<int, int, int, int, int> >(),
146 1, 2, 3, 4, 5))()
147 );
148 BOOST_CHECK(ok);
149
150 ok = check_tuple(
151 1,
152 *(bind(new_ptr<tuple<int, int, int, int, int, int> >(),
153 1, 2, 3, 4, 5, 6))()
154 );
155 BOOST_CHECK(ok);
156
157 ok = check_tuple(
158 1,
159 *(bind(new_ptr<tuple<int, int, int, int, int, int, int> >(),
160 1, 2, 3, 4, 5, 6, 7))()
161 );
162 BOOST_CHECK(ok);
163
164 ok = check_tuple(
165 1,
166 *(bind(new_ptr<tuple<int, int, int, int, int, int, int, int> >(),
167 1, 2, 3, 4, 5, 6, 7, 8))()
168 );
169 BOOST_CHECK(ok);
170
171 ok = check_tuple(
172 1,
173 *(bind(new_ptr<tuple<int, int, int, int, int, int, int, int, int> >(),
174 1, 2, 3, 4, 5, 6, 7, 8, 9))()
175 );
176 BOOST_CHECK(ok);
177
178}
179
180class is_destructor_called {
181 bool& b;
182public:
183 is_destructor_called(bool& bb) : b(bb) { b = false; }
184 ~is_destructor_called() { b = true; }
185};
186
187void 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(destructor(), _1)(idc);
195 BOOST_CHECK(flag == true);
196
197 idc = new(space) is_destructor_called(flag);
198 BOOST_CHECK(flag == false);
199 bind(destructor(), _1)(*idc);
200 BOOST_CHECK(flag == true);
201}
202
203
204class count_deletes {
205public:
206 static int count;
207 ~count_deletes() { ++count; }
208};
209
210int count_deletes::count = 0;
211
212void test_news_and_deletes ()
213{
214 int* i[10];
215 std::for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
216 int count_errors = 0;
217
218 std::for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
219 BOOST_CHECK(count_errors == 0);
220
221
222 count_deletes* ct[10];
223 std::for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
224 count_deletes::count = 0;
225 std::for_each(ct, ct+10, bind(delete_ptr(), _1));
226 BOOST_CHECK(count_deletes::count == 10);
227
228}
229
230void test_array_new_and_delete()
231{
232 count_deletes* c;
233 (_1 = bind(new_array<count_deletes>(), 5))(c);
234 count_deletes::count = 0;
235
236 bind(delete_array(), _1)(c);
237 BOOST_CHECK(count_deletes::count == 5);
238}
239
240
241void delayed_construction()
242{
243 std::vector<int> x(3);
244 std::vector<int> y(3);
245
246 std::fill(x.begin(), x.end(), 0);
247 std::fill(y.begin(), y.end(), 1);
248
249 std::vector<std::pair<int, int> > v;
250
251 std::transform(x.begin(), x.end(), y.begin(), std::back_inserter(v),
252 bl::bind(constructor<std::pair<int, int> >(), _1, _2) );
253}
254
255int 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