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>
check_tuple(int n,const T & 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 <>
check_tuple(int,const null_type &)41 bool check_tuple(int /*n*/, const null_type& ) { return true; }
42
43
constructor_all_lengths()44 void 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
new_ptr_all_lengths()112 void 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
180 class is_destructor_called {
181 bool& b;
182 public:
is_destructor_called(bool & bb)183 is_destructor_called(bool& bb) : b(bb) { b = false; }
~is_destructor_called()184 ~is_destructor_called() { b = true; }
185 };
186
test_destructor()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(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
204 class count_deletes {
205 public:
206 static int count;
~count_deletes()207 ~count_deletes() { ++count; }
208 };
209
210 int count_deletes::count = 0;
211
test_news_and_deletes()212 void 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
test_array_new_and_delete()230 void 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
delayed_construction()241 void 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
test_main(int,char * [])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