• 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 
9 // standalone test program for <boost/call_traits.hpp>
10 // 18 Mar 2002:
11 //    Changed some names to prevent conflicts with some new type_traits additions.
12 // 03 Oct 2000:
13 //    Enabled extra tests for VC6.
14 
15 #include <iostream>
16 #include <iomanip>
17 #include <algorithm>
18 #include <typeinfo>
19 #include <boost/call_traits.hpp>
20 
21 #include <libs/type_traits/test/test.hpp>
22 #include <libs/type_traits/test/check_type.hpp>
23 
24 #ifdef BOOST_MSVC
25 #pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored
26 #endif
27 
28 // a way prevent warnings for unused variables
unused_variable(const T &)29 template<class T> inline void unused_variable(const T&) {}
30 
31 //
32 // struct contained models a type that contains a type (for example std::pair)
33 // arrays are contained by value, and have to be treated as a special case:
34 //
35 template <class T>
36 struct contained
37 {
38    // define our typedefs first, arrays are stored by value
39    // so value_type is not the same as result_type:
40    typedef typename boost::call_traits<T>::param_type       param_type;
41    typedef typename boost::call_traits<T>::reference        reference;
42    typedef typename boost::call_traits<T>::const_reference  const_reference;
43    typedef T                                                value_type;
44    typedef typename boost::call_traits<T>::value_type       result_type;
45 
46    // stored value:
47    value_type v_;
48 
49    // constructors:
containedcontained50    contained() {}
containedcontained51    contained(param_type p) : v_(p){}
52    // return byval:
valuecontained53    result_type value()const { return v_; }
54    // return by_ref:
getcontained55    reference get() { return v_; }
const_getcontained56    const_reference const_get()const { return v_; }
57    // pass value:
callcontained58    void call(param_type){}
59 private:
60    contained& operator=(const contained&);
61 };
62 
63 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
64 template <class T, std::size_t N>
65 struct contained<T[N]>
66 {
67    typedef typename boost::call_traits<T[N]>::param_type       param_type;
68    typedef typename boost::call_traits<T[N]>::reference        reference;
69    typedef typename boost::call_traits<T[N]>::const_reference  const_reference;
70    typedef T                                                   value_type[N];
71    typedef typename boost::call_traits<T[N]>::value_type       result_type;
72 
73    value_type v_;
74 
containedcontained75    contained(param_type p)
76    {
77       std::copy(p, p+N, v_);
78    }
79    // return byval:
valuecontained80    result_type value()const { return v_; }
81    // return by_ref:
getcontained82    reference get() { return v_; }
const_getcontained83    const_reference const_get()const { return v_; }
callcontained84    void call(param_type){}
85 private:
86    contained& operator=(const contained&);
87 };
88 #endif
89 
90 template <class T>
test_wrap_type(const T & t)91 contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t)
92 {
93    typedef typename boost::call_traits<T>::value_type ct;
94    return contained<ct>(t);
95 }
96 
97 namespace test{
98 
99 template <class T1, class T2>
100 std::pair<
101    typename boost::call_traits<T1>::value_type,
102    typename boost::call_traits<T2>::value_type>
make_pair(const T1 & t1,const T2 & t2)103       make_pair(const T1& t1, const T2& t2)
104 {
105    return std::pair<
106       typename boost::call_traits<T1>::value_type,
107       typename boost::call_traits<T2>::value_type>(t1, t2);
108 }
109 
110 } // namespace test
111 
112 using namespace std;
113 
114 //
115 // struct call_traits_checker:
116 // verifies behaviour of contained example:
117 //
118 template <class T>
119 struct call_traits_checker
120 {
121    typedef typename boost::call_traits<T>::param_type param_type;
122    void operator()(param_type);
123 };
124 
125 template <class T>
operator ()(param_type p)126 void call_traits_checker<T>::operator()(param_type p)
127 {
128    T t(p);
129    contained<T> c(t);
130    cout << "checking contained<" << typeid(T).name() << ">..." << endl;
131    BOOST_CHECK(t == c.value());
132    BOOST_CHECK(t == c.get());
133    BOOST_CHECK(t == c.const_get());
134 #ifndef __ICL
135    //cout << "typeof contained<" << typeid(T).name() << ">::v_ is:           " << typeid(&contained<T>::v_).name() << endl;
136    cout << "typeof contained<" << typeid(T).name() << ">::value() is:      " << typeid(&contained<T>::value).name() << endl;
137    cout << "typeof contained<" << typeid(T).name() << ">::get() is:        " << typeid(&contained<T>::get).name() << endl;
138    cout << "typeof contained<" << typeid(T).name() << ">::const_get() is:  " << typeid(&contained<T>::const_get).name() << endl;
139    cout << "typeof contained<" << typeid(T).name() << ">::call() is:       " << typeid(&contained<T>::call).name() << endl;
140    cout << endl;
141 #endif
142 }
143 
144 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
145 template <class T, std::size_t N>
146 struct call_traits_checker<T[N]>
147 {
148    typedef typename boost::call_traits<T[N]>::param_type param_type;
operator ()call_traits_checker149    void operator()(param_type t)
150    {
151       contained<T[N]> c(t);
152       cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
153       unsigned int i = 0;
154       for(i = 0; i < N; ++i)
155          BOOST_CHECK(t[i] == c.value()[i]);
156       for(i = 0; i < N; ++i)
157          BOOST_CHECK(t[i] == c.get()[i]);
158       for(i = 0; i < N; ++i)
159          BOOST_CHECK(t[i] == c.const_get()[i]);
160 
161       cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is:         " << typeid(&contained<T[N]>::v_).name() << endl;
162       cout << "typeof contained<" << typeid(T[N]).name() << ">::value is:      " << typeid(&contained<T[N]>::value).name() << endl;
163       cout << "typeof contained<" << typeid(T[N]).name() << ">::get is:        " << typeid(&contained<T[N]>::get).name() << endl;
164       cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is:  " << typeid(&contained<T[N]>::const_get).name() << endl;
165       cout << "typeof contained<" << typeid(T[N]).name() << ">::call is:       " << typeid(&contained<T[N]>::call).name() << endl;
166       cout << endl;
167    }
168 };
169 #endif
170 
171 //
172 // check_wrap:
173 template <class W, class U>
check_wrap(const W & w,const U & u)174 void check_wrap(const W& w, const U& u)
175 {
176    cout << "checking " << typeid(W).name() << "..." << endl;
177    BOOST_CHECK(w.value() == u);
178 }
179 
180 //
181 // check_make_pair:
182 // verifies behaviour of "make_pair":
183 //
184 template <class T, class U, class V>
check_make_pair(T c,U u,V v)185 void check_make_pair(T c, U u, V v)
186 {
187    cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl;
188    BOOST_CHECK(c.first == u);
189    BOOST_CHECK(c.second == v);
190    cout << endl;
191 }
192 
193 
194 struct comparible_UDT
195 {
196    int i_;
comparible_UDTcomparible_UDT197    comparible_UDT() : i_(2){}
comparible_UDTcomparible_UDT198    comparible_UDT(const comparible_UDT& other) : i_(other.i_){}
operator =comparible_UDT199    comparible_UDT& operator=(const comparible_UDT& other)
200    {
201       i_ = other.i_;
202       return *this;
203    }
operator ==comparible_UDT204    bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
205 };
206 
main()207 int main()
208 {
209    call_traits_checker<comparible_UDT> c1;
210    comparible_UDT u;
211    c1(u);
212    call_traits_checker<int> c2;
213    call_traits_checker<enum_UDT> c2b;
214    int i = 2;
215    c2(i);
216    c2b(one);
217    int* pi = &i;
218    int a[2] = {1,2};
219 #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
220    call_traits_checker<int*> c3;
221    c3(pi);
222    call_traits_checker<int&> c4;
223    c4(i);
224    call_traits_checker<const int&> c5;
225    c5(i);
226 #if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC)
227    call_traits_checker<int[2]> c6;
228    c6(a);
229 #endif
230 #endif
231 
232    check_wrap(test_wrap_type(2), 2);
233 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
234    check_wrap(test_wrap_type(a), a);
235    check_make_pair(test::make_pair(a, a), a, a);
236 #endif
237 
238    // cv-qualifiers applied to reference types should have no effect
239    // declare these here for later use with is_reference and remove_reference:
240    typedef int& r_type;
241    typedef const r_type cr_type;
242 
243    BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type);
244    BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference);
245    BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference);
246    BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type);
247    BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type);
248    BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference);
249    BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference);
250    BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type);
251    BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type);
252    BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference);
253    BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference);
254    BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type);
255 #if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
256    BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type);
257    BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference);
258    BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference);
259    BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type);
260 #if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
261    BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type);
262    BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference);
263    BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference);
264    BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type);
265 #else
266    std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl;
267 #endif
268    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type);
269    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference);
270    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference);
271    BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type);
272 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
273    BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type);
274    BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference);
275    BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference);
276    BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type);
277    BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type);
278    BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference);
279    BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference);
280    BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type);
281    // test with abstract base class:
282    BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type);
283    BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference);
284    BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference);
285    BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type);
286 #else
287    std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl;
288 #endif
289 #else
290    std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl;
291 #endif
292    // test with an incomplete type:
293    BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type);
294    BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
295    BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
296    BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
297    // test enum:
298    BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type);
299    BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference);
300    BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference);
301    BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type);
302    return 0;
303 }
304 
305 //
306 // define call_traits tests to check that the assertions in the docs do actually work
307 // this is an compile-time only set of tests:
308 //
309 template <typename T, bool isarray = false>
310 struct call_traits_test
311 {
312    typedef ::boost::call_traits<T> ct;
313    typedef typename ct::param_type param_type;
314    typedef typename ct::reference reference;
315    typedef typename ct::const_reference const_reference;
316    typedef typename ct::value_type value_type;
317    static void assert_construct(param_type val);
318 };
319 
320 template <typename T, bool isarray>
assert_construct(typename call_traits_test<T,isarray>::param_type val)321 void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val)
322 {
323    //
324    // this is to check that the call_traits assertions are valid:
325    T t(val);
326    value_type v(t);
327    reference r(t);
328    const_reference cr(t);
329    param_type p(t);
330    value_type v2(v);
331    value_type v3(r);
332    value_type v4(p);
333    reference r2(v);
334    reference r3(r);
335    const_reference cr2(v);
336    const_reference cr3(r);
337    const_reference cr4(cr);
338    const_reference cr5(p);
339    param_type p2(v);
340    param_type p3(r);
341    param_type p4(p);
342 
343    unused_variable(v2);
344    unused_variable(v3);
345    unused_variable(v4);
346    unused_variable(r2);
347    unused_variable(r3);
348    unused_variable(cr2);
349    unused_variable(cr3);
350    unused_variable(cr4);
351    unused_variable(cr5);
352    unused_variable(p2);
353    unused_variable(p3);
354    unused_variable(p4);
355 }
356 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
357 template <typename T>
358 struct call_traits_test<T, true>
359 {
360    typedef ::boost::call_traits<T> ct;
361    typedef typename ct::param_type param_type;
362    typedef typename ct::reference reference;
363    typedef typename ct::const_reference const_reference;
364    typedef typename ct::value_type value_type;
365    static void assert_construct(param_type val);
366 };
367 
368 template <typename T>
assert_construct(typename boost::call_traits<T>::param_type val)369 void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val)
370 {
371    //
372    // this is to check that the call_traits assertions are valid:
373    T t;
374    value_type v(t);
375    value_type v5(val);
376    reference r = t;
377    const_reference cr = t;
378    reference r2 = r;
379    #ifndef BOOST_BORLANDC
380    // C++ Builder buglet:
381    const_reference cr2 = r;
382    #endif
383    param_type p(t);
384    value_type v2(v);
385    const_reference cr3 = cr;
386    value_type v3(r);
387    value_type v4(p);
388    param_type p2(v);
389    param_type p3(r);
390    param_type p4(p);
391 
392    unused_variable(v2);
393    unused_variable(v3);
394    unused_variable(v4);
395    unused_variable(v5);
396 #ifndef BOOST_BORLANDC
397    unused_variable(r2);
398    unused_variable(cr2);
399 #endif
400    unused_variable(cr3);
401    unused_variable(p2);
402    unused_variable(p3);
403    unused_variable(p4);
404 }
405 #endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
406 //
407 // now check call_traits assertions by instantiating call_traits_test:
408 template struct call_traits_test<int>;
409 template struct call_traits_test<const int>;
410 template struct call_traits_test<int*>;
411 #if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
412 template struct call_traits_test<int&>;
413 template struct call_traits_test<const int&>;
414 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
415 template struct call_traits_test<int[2], true>;
416 #endif
417 #endif
418 
419