1// boost::compressed_pair test program
2
3// (C) Copyright John Maddock 2000.
4// Use, modification and distribution are subject to the Boost Software License,
5// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt).
7
8// standalone test program for <boost/compressed_pair.hpp>
9// Revised 03 Oct 2000:
10// Enabled tests for VC6.
11
12#include <iostream>
13#include <typeinfo>
14#include <cassert>
15
16#include <boost/compressed_pair.hpp>
17#include <boost/test/test_tools.hpp>
18
19using namespace boost;
20
21struct empty_UDT
22{
23 ~empty_UDT(){};
24 empty_UDT& operator=(const empty_UDT&){ return *this; }
25 bool operator==(const empty_UDT&)const
26 { return true; }
27};
28struct empty_POD_UDT
29{
30 empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
31 bool operator==(const empty_POD_UDT&)const
32 { return true; }
33};
34
35struct non_empty1
36{
37 int i;
38 non_empty1() : i(1){}
39 non_empty1(int v) : i(v){}
40 friend bool operator==(const non_empty1& a, const non_empty1& b)
41 { return a.i == b.i; }
42};
43
44struct non_empty2
45{
46 int i;
47 non_empty2() : i(3){}
48 non_empty2(int v) : i(v){}
49 friend bool operator==(const non_empty2& a, const non_empty2& b)
50 { return a.i == b.i; }
51};
52
53#ifdef __GNUC__
54using std::swap;
55#endif
56
57template <class T1, class T2>
58struct compressed_pair_tester
59{
60 // define the types we need:
61 typedef T1 first_type;
62 typedef T2 second_type;
63 typedef typename call_traits<first_type>::param_type first_param_type;
64 typedef typename call_traits<second_type>::param_type second_param_type;
65 // define our test proc:
66 static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
67};
68
69template <class T1, class T2>
70void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
71{
72#ifndef __GNUC__
73 // gcc 2.90 can't cope with function scope using
74 // declarations, and generates an internal compiler error...
75 using std::swap;
76#endif
77 // default construct:
78 boost::compressed_pair<T1,T2> cp1;
79 // first param construct:
80 boost::compressed_pair<T1,T2> cp2(p1);
81 cp2.second() = p2;
82 BOOST_CHECK(cp2.first() == p1);
83 BOOST_CHECK(cp2.second() == p2);
84 // second param construct:
85 boost::compressed_pair<T1,T2> cp3(p2);
86 cp3.first() = p1;
87 BOOST_CHECK(cp3.second() == p2);
88 BOOST_CHECK(cp3.first() == p1);
89 // both param construct:
90 boost::compressed_pair<T1,T2> cp4(p1, p2);
91 BOOST_CHECK(cp4.first() == p1);
92 BOOST_CHECK(cp4.second() == p2);
93 boost::compressed_pair<T1,T2> cp5(p3, p4);
94 BOOST_CHECK(cp5.first() == p3);
95 BOOST_CHECK(cp5.second() == p4);
96 // check const members:
97 const boost::compressed_pair<T1,T2>& cpr1 = cp4;
98 BOOST_CHECK(cpr1.first() == p1);
99 BOOST_CHECK(cpr1.second() == p2);
100
101 // copy construct:
102 boost::compressed_pair<T1,T2> cp6(cp4);
103 BOOST_CHECK(cp6.first() == p1);
104 BOOST_CHECK(cp6.second() == p2);
105 // assignment:
106 cp1 = cp4;
107 BOOST_CHECK(cp1.first() == p1);
108 BOOST_CHECK(cp1.second() == p2);
109 cp1 = cp5;
110 BOOST_CHECK(cp1.first() == p3);
111 BOOST_CHECK(cp1.second() == p4);
112 // swap:
113 cp4.swap(cp5);
114 BOOST_CHECK(cp4.first() == p3);
115 BOOST_CHECK(cp4.second() == p4);
116 BOOST_CHECK(cp5.first() == p1);
117 BOOST_CHECK(cp5.second() == p2);
118 swap(cp4,cp5);
119 BOOST_CHECK(cp4.first() == p1);
120 BOOST_CHECK(cp4.second() == p2);
121 BOOST_CHECK(cp5.first() == p3);
122 BOOST_CHECK(cp5.second() == p4);
123}
124
125//
126// tests for case where one or both
127// parameters are reference types:
128//
129template <class T1, class T2>
130struct compressed_pair_reference_tester
131{
132 // define the types we need:
133 typedef T1 first_type;
134 typedef T2 second_type;
135 typedef typename call_traits<first_type>::param_type first_param_type;
136 typedef typename call_traits<second_type>::param_type second_param_type;
137 // define our test proc:
138 static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
139};
140
141template <class T1, class T2>
142void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
143{
144#ifndef __GNUC__
145 // gcc 2.90 can't cope with function scope using
146 // declarations, and generates an internal compiler error...
147 using std::swap;
148#endif
149 // both param construct:
150 boost::compressed_pair<T1,T2> cp4(p1, p2);
151 BOOST_CHECK(cp4.first() == p1);
152 BOOST_CHECK(cp4.second() == p2);
153 boost::compressed_pair<T1,T2> cp5(p3, p4);
154 BOOST_CHECK(cp5.first() == p3);
155 BOOST_CHECK(cp5.second() == p4);
156 // check const members:
157 const boost::compressed_pair<T1,T2>& cpr1 = cp4;
158 BOOST_CHECK(cpr1.first() == p1);
159 BOOST_CHECK(cpr1.second() == p2);
160
161 // copy construct:
162 boost::compressed_pair<T1,T2> cp6(cp4);
163 BOOST_CHECK(cp6.first() == p1);
164 BOOST_CHECK(cp6.second() == p2);
165 // assignment:
166 // VC6 bug:
167 // When second() is an empty class, VC6 performs the
168 // assignment by doing a memcpy - even though the empty
169 // class is really a zero sized base class, the result
170 // is that the memory of first() gets trampled over.
171 // Similar arguments apply to the case that first() is
172 // an empty base class.
173 // Strangely the problem is dependent upon the compiler
174 // settings - some generate the problem others do not.
175 cp4.first() = p3;
176 cp4.second() = p4;
177 BOOST_CHECK(cp4.first() == p3);
178 BOOST_CHECK(cp4.second() == p4);
179}
180//
181// supplimentary tests for case where first arg only is a reference type:
182//
183template <class T1, class T2>
184struct compressed_pair_reference1_tester
185{
186 // define the types we need:
187 typedef T1 first_type;
188 typedef T2 second_type;
189 typedef typename call_traits<first_type>::param_type first_param_type;
190 typedef typename call_traits<second_type>::param_type second_param_type;
191 // define our test proc:
192 static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
193};
194
195template <class T1, class T2>
196void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
197{
198#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
199 // first param construct:
200 boost::compressed_pair<T1,T2> cp2(p1);
201 cp2.second() = p2;
202 BOOST_CHECK(cp2.first() == p1);
203 BOOST_CHECK(cp2.second() == p2);
204#endif
205}
206//
207// supplimentary tests for case where second arg only is a reference type:
208//
209template <class T1, class T2>
210struct compressed_pair_reference2_tester
211{
212 // define the types we need:
213 typedef T1 first_type;
214 typedef T2 second_type;
215 typedef typename call_traits<first_type>::param_type first_param_type;
216 typedef typename call_traits<second_type>::param_type second_param_type;
217 // define our test proc:
218 static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
219};
220
221template <class T1, class T2>
222void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
223{
224#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
225 // second param construct:
226 boost::compressed_pair<T1,T2> cp3(p2);
227 cp3.first() = p1;
228 BOOST_CHECK(cp3.second() == p2);
229 BOOST_CHECK(cp3.first() == p1);
230#endif
231}
232
233//
234// tests for where one or the other parameter is an array:
235//
236template <class T1, class T2>
237struct compressed_pair_array1_tester
238{
239 // define the types we need:
240 typedef T1 first_type;
241 typedef T2 second_type;
242 typedef typename call_traits<first_type>::param_type first_param_type;
243 typedef typename call_traits<second_type>::param_type second_param_type;
244 // define our test proc:
245 static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
246};
247
248template <class T1, class T2>
249void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
250{
251 // default construct:
252 boost::compressed_pair<T1,T2> cp1;
253 // second param construct:
254 boost::compressed_pair<T1,T2> cp3(p2);
255 cp3.first()[0] = p1[0];
256 BOOST_CHECK(cp3.second() == p2);
257 BOOST_CHECK(cp3.first()[0] == p1[0]);
258 // check const members:
259 const boost::compressed_pair<T1,T2>& cpr1 = cp3;
260 BOOST_CHECK(cpr1.first()[0] == p1[0]);
261 BOOST_CHECK(cpr1.second() == p2);
262
263 BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
264}
265
266template <class T1, class T2>
267struct compressed_pair_array2_tester
268{
269 // define the types we need:
270 typedef T1 first_type;
271 typedef T2 second_type;
272 typedef typename call_traits<first_type>::param_type first_param_type;
273 typedef typename call_traits<second_type>::param_type second_param_type;
274 // define our test proc:
275 static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
276};
277
278template <class T1, class T2>
279void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
280{
281 // default construct:
282 boost::compressed_pair<T1,T2> cp1;
283 // first param construct:
284 boost::compressed_pair<T1,T2> cp2(p1);
285 cp2.second()[0] = p2[0];
286 BOOST_CHECK(cp2.first() == p1);
287 BOOST_CHECK(cp2.second()[0] == p2[0]);
288 // check const members:
289 const boost::compressed_pair<T1,T2>& cpr1 = cp2;
290 BOOST_CHECK(cpr1.first() == p1);
291 BOOST_CHECK(cpr1.second()[0] == p2[0]);
292
293 BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
294}
295
296template <class T1, class T2>
297struct compressed_pair_array_tester
298{
299 // define the types we need:
300 typedef T1 first_type;
301 typedef T2 second_type;
302 typedef typename call_traits<first_type>::param_type first_param_type;
303 typedef typename call_traits<second_type>::param_type second_param_type;
304 // define our test proc:
305 static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
306};
307
308template <class T1, class T2>
309void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
310{
311 // default construct:
312 boost::compressed_pair<T1,T2> cp1;
313 cp1.first()[0] = p1[0];
314 cp1.second()[0] = p2[0];
315 BOOST_CHECK(cp1.first()[0] == p1[0]);
316 BOOST_CHECK(cp1.second()[0] == p2[0]);
317 // check const members:
318 const boost::compressed_pair<T1,T2>& cpr1 = cp1;
319 BOOST_CHECK(cpr1.first()[0] == p1[0]);
320 BOOST_CHECK(cpr1.second()[0] == p2[0]);
321
322 BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
323 BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
324}
325
326int test_main(int, char *[])
327{
328 // declare some variables to pass to the tester:
329 non_empty1 ne1(2);
330 non_empty1 ne2(3);
331 non_empty2 ne3(4);
332 non_empty2 ne4(5);
333 empty_POD_UDT e1;
334 empty_UDT e2;
335
336 // T1 != T2, both non-empty
337 compressed_pair_tester<non_empty1,non_empty2>::test(p1: ne1, p2: ne3, p3: ne2, p4: ne4);
338 // T1 != T2, T2 empty
339 compressed_pair_tester<non_empty1,empty_POD_UDT>::test(p1: ne1, p2: e1, p3: ne2, p4: e1);
340 // T1 != T2, T1 empty
341 compressed_pair_tester<empty_POD_UDT,non_empty2>::test(p1: e1, p2: ne3, p3: e1, p4: ne4);
342 // T1 != T2, both empty
343 compressed_pair_tester<empty_POD_UDT,empty_UDT>::test(p1: e1, p2: e2, p3: e1, p4: e2);
344 // T1 == T2, both non-empty
345 compressed_pair_tester<non_empty1,non_empty1>::test(p1: ne1, p2: ne1, p3: ne2, p4: ne2);
346 // T1 == T2, both empty
347 compressed_pair_tester<empty_UDT,empty_UDT>::test(p1: e2, p2: e2, p3: e2, p4: e2);
348
349
350 // test references:
351
352 // T1 != T2, both non-empty
353 compressed_pair_reference_tester<non_empty1&,non_empty2>::test(p1&: ne1, p2: ne3, p3&: ne2, p4: ne4);
354 compressed_pair_reference_tester<non_empty1,non_empty2&>::test(p1: ne1, p2&: ne3, p3: ne2, p4&: ne4);
355 compressed_pair_reference1_tester<non_empty1&,non_empty2>::test(p1&: ne1, p2: ne3, ne2, ne4);
356 compressed_pair_reference2_tester<non_empty1,non_empty2&>::test(p1: ne1, p2&: ne3, ne2, ne4);
357 // T1 != T2, T2 empty
358 compressed_pair_reference_tester<non_empty1&,empty_POD_UDT>::test(p1&: ne1, p2: e1, p3&: ne2, p4: e1);
359 compressed_pair_reference1_tester<non_empty1&,empty_POD_UDT>::test(p1&: ne1, p2: e1, ne2, e1);
360 // T1 != T2, T1 empty
361 compressed_pair_reference_tester<empty_POD_UDT,non_empty2&>::test(p1: e1, p2&: ne3, p3: e1, p4&: ne4);
362 compressed_pair_reference2_tester<empty_POD_UDT,non_empty2&>::test(p1: e1, p2&: ne3, e1, ne4);
363 // T1 == T2, both non-empty
364 compressed_pair_reference_tester<non_empty1&,non_empty1&>::test(p1&: ne1, p2&: ne1, p3&: ne2, p4&: ne2);
365
366 // tests arrays:
367 non_empty1 nea1[2];
368 non_empty1 nea2[2];
369 non_empty2 nea3[2];
370 non_empty2 nea4[2];
371 nea1[0] = non_empty1(5);
372 nea2[0] = non_empty1(6);
373 nea3[0] = non_empty2(7);
374 nea4[0] = non_empty2(8);
375
376 // T1 != T2, both non-empty
377 compressed_pair_array1_tester<non_empty1[2],non_empty2>::test(p1: nea1, p2: ne3, nea2, ne4);
378 compressed_pair_array2_tester<non_empty1,non_empty2[2]>::test(p1: ne1, p2: nea3, ne2, nea4);
379 compressed_pair_array_tester<non_empty1[2],non_empty2[2]>::test(p1: nea1, p2: nea3, nea2, nea4);
380 // T1 != T2, T2 empty
381 compressed_pair_array1_tester<non_empty1[2],empty_POD_UDT>::test(p1: nea1, p2: e1, nea2, e1);
382 // T1 != T2, T1 empty
383 compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(p1: e1, p2: nea3, e1, nea4);
384 // T1 == T2, both non-empty
385 compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(p1: nea1, p2: nea1, nea2, nea2);
386 return 0;
387}
388
389
390unsigned int expected_failures = 0;
391
392
393
394
395
396

source code of boost/libs/utility/compressed_pair_test.cpp