• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/core/lightweight_test.hpp>
18 
19 using namespace boost;
20 
21 struct empty_UDT
22 {
~empty_UDTempty_UDT23    ~empty_UDT(){};
operator =empty_UDT24    empty_UDT& operator=(const empty_UDT&){ return *this; }
operator ==empty_UDT25    bool operator==(const empty_UDT&)const
26    { return true; }
27 };
28 struct empty_POD_UDT
29 {
operator =empty_POD_UDT30    empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
operator ==empty_POD_UDT31    bool operator==(const empty_POD_UDT&)const
32    { return true; }
33 };
34 
35 struct non_empty1
36 {
37    int i;
non_empty1non_empty138    non_empty1() : i(1){}
non_empty1non_empty139    non_empty1(int v) : i(v){}
operator ==(const non_empty1 & a,const non_empty1 & b)40    friend bool operator==(const non_empty1& a, const non_empty1& b)
41    { return a.i == b.i; }
42 };
43 
44 struct non_empty2
45 {
46    int i;
non_empty2non_empty247    non_empty2() : i(3){}
non_empty2non_empty248    non_empty2(int v) : i(v){}
operator ==(const non_empty2 & a,const non_empty2 & b)49    friend bool operator==(const non_empty2& a, const non_empty2& b)
50    { return a.i == b.i; }
51 };
52 
53 #ifdef __GNUC__
54 using std::swap;
55 #endif
56 
57 template <class T1, class T2>
58 struct 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 
69 template <class T1, class T2>
test(first_param_type p1,second_param_type p2,first_param_type p3,second_param_type p4)70 void 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_TEST(cp2.first() == p1);
83    BOOST_TEST(cp2.second() == p2);
84    // second param construct:
85    boost::compressed_pair<T1,T2> cp3(p2);
86    cp3.first() = p1;
87    BOOST_TEST(cp3.second() == p2);
88    BOOST_TEST(cp3.first() == p1);
89    // both param construct:
90    boost::compressed_pair<T1,T2> cp4(p1, p2);
91    BOOST_TEST(cp4.first() == p1);
92    BOOST_TEST(cp4.second() == p2);
93    boost::compressed_pair<T1,T2> cp5(p3, p4);
94    BOOST_TEST(cp5.first() == p3);
95    BOOST_TEST(cp5.second() == p4);
96    // check const members:
97    const boost::compressed_pair<T1,T2>& cpr1 = cp4;
98    BOOST_TEST(cpr1.first() == p1);
99    BOOST_TEST(cpr1.second() == p2);
100 
101    // copy construct:
102    boost::compressed_pair<T1,T2> cp6(cp4);
103    BOOST_TEST(cp6.first() == p1);
104    BOOST_TEST(cp6.second() == p2);
105    // assignment:
106    cp1 = cp4;
107    BOOST_TEST(cp1.first() == p1);
108    BOOST_TEST(cp1.second() == p2);
109    cp1 = cp5;
110    BOOST_TEST(cp1.first() == p3);
111    BOOST_TEST(cp1.second() == p4);
112    // swap:
113    cp4.swap(cp5);
114    BOOST_TEST(cp4.first() == p3);
115    BOOST_TEST(cp4.second() == p4);
116    BOOST_TEST(cp5.first() == p1);
117    BOOST_TEST(cp5.second() == p2);
118    swap(cp4,cp5);
119    BOOST_TEST(cp4.first() == p1);
120    BOOST_TEST(cp4.second() == p2);
121    BOOST_TEST(cp5.first() == p3);
122    BOOST_TEST(cp5.second() == p4);
123 }
124 
125 //
126 // tests for case where one or both
127 // parameters are reference types:
128 //
129 template <class T1, class T2>
130 struct 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 
141 template <class T1, class T2>
test(first_param_type p1,second_param_type p2,first_param_type p3,second_param_type p4)142 void 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_TEST(cp4.first() == p1);
152    BOOST_TEST(cp4.second() == p2);
153    boost::compressed_pair<T1,T2> cp5(p3, p4);
154    BOOST_TEST(cp5.first() == p3);
155    BOOST_TEST(cp5.second() == p4);
156    // check const members:
157    const boost::compressed_pair<T1,T2>& cpr1 = cp4;
158    BOOST_TEST(cpr1.first() == p1);
159    BOOST_TEST(cpr1.second() == p2);
160 
161    // copy construct:
162    boost::compressed_pair<T1,T2> cp6(cp4);
163    BOOST_TEST(cp6.first() == p1);
164    BOOST_TEST(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_TEST(cp4.first() == p3);
178    BOOST_TEST(cp4.second() == p4);
179 }
180 //
181 // supplimentary tests for case where first arg only is a reference type:
182 //
183 template <class T1, class T2>
184 struct 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 
195 template <class T1, class T2>
test(first_param_type p1,second_param_type p2,first_param_type,second_param_type)196 void 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_TEST(cp2.first() == p1);
203    BOOST_TEST(cp2.second() == p2);
204 #endif
205 }
206 //
207 // supplimentary tests for case where second arg only is a reference type:
208 //
209 template <class T1, class T2>
210 struct 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 
221 template <class T1, class T2>
test(first_param_type p1,second_param_type p2,first_param_type,second_param_type)222 void 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_TEST(cp3.second() == p2);
229    BOOST_TEST(cp3.first() == p1);
230 #endif
231 }
232 
233 //
234 // tests for where one or the other parameter is an array:
235 //
236 template <class T1, class T2>
237 struct 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 
248 template <class T1, class T2>
test(first_param_type p1,second_param_type p2,first_param_type,second_param_type)249 void 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_TEST(cp3.second() == p2);
257    BOOST_TEST(cp3.first()[0] == p1[0]);
258    // check const members:
259    const boost::compressed_pair<T1,T2>& cpr1 = cp3;
260    BOOST_TEST(cpr1.first()[0] == p1[0]);
261    BOOST_TEST(cpr1.second() == p2);
262 
263    BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
264 }
265 
266 template <class T1, class T2>
267 struct 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 
278 template <class T1, class T2>
test(first_param_type p1,second_param_type p2,first_param_type,second_param_type)279 void 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_TEST(cp2.first() == p1);
287    BOOST_TEST(cp2.second()[0] == p2[0]);
288    // check const members:
289    const boost::compressed_pair<T1,T2>& cpr1 = cp2;
290    BOOST_TEST(cpr1.first() == p1);
291    BOOST_TEST(cpr1.second()[0] == p2[0]);
292 
293    BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
294 }
295 
296 template <class T1, class T2>
297 struct 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 
308 template <class T1, class T2>
test(first_param_type p1,second_param_type p2,first_param_type,second_param_type)309 void 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_TEST(cp1.first()[0] == p1[0]);
316    BOOST_TEST(cp1.second()[0] == p2[0]);
317    // check const members:
318    const boost::compressed_pair<T1,T2>& cpr1 = cp1;
319    BOOST_TEST(cpr1.first()[0] == p1[0]);
320    BOOST_TEST(cpr1.second()[0] == p2[0]);
321 
322    BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
323    BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
324 }
325 
main()326 int main()
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(ne1, ne3, ne2, ne4);
338    // T1 != T2, T2 empty
339    compressed_pair_tester<non_empty1,empty_POD_UDT>::test(ne1, e1, ne2, e1);
340    // T1 != T2, T1 empty
341    compressed_pair_tester<empty_POD_UDT,non_empty2>::test(e1, ne3, e1, ne4);
342    // T1 != T2, both empty
343    compressed_pair_tester<empty_POD_UDT,empty_UDT>::test(e1, e2, e1, e2);
344    // T1 == T2, both non-empty
345    compressed_pair_tester<non_empty1,non_empty1>::test(ne1, ne1, ne2, ne2);
346    // T1 == T2, both empty
347    compressed_pair_tester<empty_UDT,empty_UDT>::test(e2, e2, e2, e2);
348 
349 
350    // test references:
351 
352    // T1 != T2, both non-empty
353    compressed_pair_reference_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
354    compressed_pair_reference_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
355    compressed_pair_reference1_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
356    compressed_pair_reference2_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
357    // T1 != T2, T2 empty
358    compressed_pair_reference_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
359    compressed_pair_reference1_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
360    // T1 != T2, T1 empty
361    compressed_pair_reference_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
362    compressed_pair_reference2_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
363    // T1 == T2, both non-empty
364    compressed_pair_reference_tester<non_empty1&,non_empty1&>::test(ne1, ne1, ne2, 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(nea1, ne3, nea2, ne4);
378    compressed_pair_array2_tester<non_empty1,non_empty2[2]>::test(ne1, nea3, ne2, nea4);
379    compressed_pair_array_tester<non_empty1[2],non_empty2[2]>::test(nea1, nea3, nea2, nea4);
380    // T1 != T2, T2 empty
381    compressed_pair_array1_tester<non_empty1[2],empty_POD_UDT>::test(nea1, e1, nea2, e1);
382    // T1 != T2, T1 empty
383    compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4);
384    // T1 == T2, both non-empty
385    compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2);
386    return boost::report_errors();
387 }
388