call_traits_test.cpp 15 KB

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