tuple_test_bench.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // For more information, see http://www.boost.org
  7. // tuple_test_bench.cpp --------------------------------
  8. #define BOOST_INCLUDE_MAIN // for testing, include rather than link
  9. #include <boost/test/test_tools.hpp> // see "Header Implementation Option"
  10. #include "boost/tuple/tuple.hpp"
  11. #include "boost/tuple/tuple_comparison.hpp"
  12. #include "boost/type_traits/is_const.hpp"
  13. #include "boost/ref.hpp"
  14. #include <string>
  15. #include <utility>
  16. using namespace boost;
  17. // ----------------------------------------------------------------------------
  18. // helpers
  19. // ----------------------------------------------------------------------------
  20. class A {};
  21. class B {};
  22. class C {};
  23. // classes with different kinds of conversions
  24. class AA {};
  25. class BB : public AA {};
  26. struct CC { CC() {} CC(const BB&) {} };
  27. struct DD { operator CC() const { return CC(); }; };
  28. // something to prevent warnings for unused variables
  29. template<class T> void dummy(const T&) {}
  30. // no public default constructor
  31. class foo {
  32. public:
  33. explicit foo(int v) : val(v) {}
  34. bool operator==(const foo& other) const {
  35. return val == other.val;
  36. }
  37. private:
  38. foo() {}
  39. int val;
  40. };
  41. // another class without a public default constructor
  42. class no_def_constructor {
  43. no_def_constructor() {}
  44. public:
  45. no_def_constructor(std::string) {}
  46. };
  47. // A non-copyable class
  48. class no_copy {
  49. no_copy(const no_copy&) {}
  50. public:
  51. no_copy() {};
  52. };
  53. // ----------------------------------------------------------------------------
  54. // Testing different element types --------------------------------------------
  55. // ----------------------------------------------------------------------------
  56. typedef tuple<int> t1;
  57. typedef tuple<double&, const double&, const double, double*, const double*> t2;
  58. typedef tuple<A, int(*)(char, int), C> t3;
  59. typedef tuple<std::string, std::pair<A, B> > t4;
  60. typedef tuple<A*, tuple<const A*, const B&, C>, bool, void*> t5;
  61. typedef tuple<volatile int, const volatile char&, int(&)(float) > t6;
  62. # if !defined(__BORLANDC__) || __BORLAND__ > 0x0551
  63. typedef tuple<B(A::*)(C&), A&> t7;
  64. #endif
  65. // -----------------------------------------------------------------------
  66. // -tuple construction tests ---------------------------------------------
  67. // -----------------------------------------------------------------------
  68. no_copy y;
  69. tuple<no_copy&> x = tuple<no_copy&>(y); // ok
  70. char cs[10];
  71. tuple<char(&)[10]> v2(cs); // ok
  72. void
  73. construction_test()
  74. {
  75. // Note, the get function can be called without the tuples:: qualifier,
  76. // as it is lifted to namespace boost with a "using tuples::get" but
  77. // MSVC 6.0 just cannot find get without the namespace qualifier
  78. tuple<int> t1;
  79. BOOST_CHECK(get<0>(t1) == int());
  80. tuple<float> t2(5.5f);
  81. BOOST_CHECK(get<0>(t2) > 5.4f && get<0>(t2) < 5.6f);
  82. tuple<foo> t3(foo(12));
  83. BOOST_CHECK(get<0>(t3) == foo(12));
  84. tuple<double> t4(t2);
  85. BOOST_CHECK(get<0>(t4) > 5.4 && get<0>(t4) < 5.6);
  86. tuple<int, float> t5;
  87. BOOST_CHECK(get<0>(t5) == int());
  88. BOOST_CHECK(get<1>(t5) == float());
  89. tuple<int, float> t6(12, 5.5f);
  90. BOOST_CHECK(get<0>(t6) == 12);
  91. BOOST_CHECK(get<1>(t6) > 5.4f && get<1>(t6) < 5.6f);
  92. tuple<int, float> t7(t6);
  93. BOOST_CHECK(get<0>(t7) == 12);
  94. BOOST_CHECK(get<1>(t7) > 5.4f && get<1>(t7) < 5.6f);
  95. tuple<long, double> t8(t6);
  96. BOOST_CHECK(get<0>(t8) == 12);
  97. BOOST_CHECK(get<1>(t8) > 5.4f && get<1>(t8) < 5.6f);
  98. dummy(
  99. tuple<no_def_constructor, no_def_constructor, no_def_constructor>(
  100. std::string("Jaba"), // ok, since the default
  101. std::string("Daba"), // constructor is not used
  102. std::string("Doo")
  103. )
  104. );
  105. // testing default values
  106. dummy(tuple<int, double>());
  107. dummy(tuple<int, double>(1));
  108. dummy(tuple<int, double>(1,3.14));
  109. // dummy(tuple<double&>()); // should fail, not defaults for references
  110. // dummy(tuple<const double&>()); // likewise
  111. double dd = 5;
  112. dummy(tuple<double&>(dd)); // ok
  113. dummy(tuple<const double&>(dd+3.14)); // ok, but dangerous
  114. // dummy(tuple<double&>(dd+3.14)); // should fail,
  115. // // temporary to non-const reference
  116. }
  117. // ----------------------------------------------------------------------------
  118. // - testing element access ---------------------------------------------------
  119. // ----------------------------------------------------------------------------
  120. void element_access_test()
  121. {
  122. double d = 2.7;
  123. A a;
  124. tuple<int, double&, const A&, int> t(1, d, a, 2);
  125. const tuple<int, double&, const A, int> ct = t;
  126. int i = get<0>(t);
  127. int i2 = get<3>(t);
  128. BOOST_CHECK(i == 1 && i2 == 2);
  129. int j = get<0>(ct);
  130. BOOST_CHECK(j == 1);
  131. get<0>(t) = 5;
  132. BOOST_CHECK(t.head == 5);
  133. // get<0>(ct) = 5; // can't assign to const
  134. double e = get<1>(t);
  135. BOOST_CHECK(e > 2.69 && e < 2.71);
  136. get<1>(t) = 3.14+i;
  137. BOOST_CHECK(get<1>(t) > 4.13 && get<1>(t) < 4.15);
  138. // get<4>(t) = A(); // can't assign to const
  139. // dummy(get<5>(ct)); // illegal index
  140. ++get<0>(t);
  141. BOOST_CHECK(get<0>(t) == 6);
  142. BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<0, tuple<int, float> >::type>::value != true));
  143. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  144. BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<0, const tuple<int, float> >::type>::value));
  145. #endif
  146. BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<1, tuple<int, float> >::type>::value != true));
  147. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  148. BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<1, const tuple<int, float> >::type>::value));
  149. #endif
  150. dummy(i); dummy(i2); dummy(j); dummy(e); // avoid warns for unused variables
  151. }
  152. // ----------------------------------------------------------------------------
  153. // - copying tuples -----------------------------------------------------------
  154. // ----------------------------------------------------------------------------
  155. void
  156. copy_test()
  157. {
  158. tuple<int, char> t1(4, 'a');
  159. tuple<int, char> t2(5, 'b');
  160. t2 = t1;
  161. BOOST_CHECK(get<0>(t1) == get<0>(t2));
  162. BOOST_CHECK(get<1>(t1) == get<1>(t2));
  163. tuple<long, std::string> t3(2, "a");
  164. t3 = t1;
  165. BOOST_CHECK((double)get<0>(t1) == get<0>(t3));
  166. BOOST_CHECK(get<1>(t1) == get<1>(t3)[0]);
  167. // testing copy and assignment with implicit conversions between elements
  168. // testing tie
  169. tuple<char, BB*, BB, DD> t;
  170. tuple<int, AA*, CC, CC> a(t);
  171. a = t;
  172. int i; char c; double d;
  173. tie(i, c, d) = make_tuple(1, 'a', 5.5);
  174. BOOST_CHECK(i==1);
  175. BOOST_CHECK(c=='a');
  176. BOOST_CHECK(d>5.4 && d<5.6);
  177. }
  178. void
  179. mutate_test()
  180. {
  181. tuple<int, float, bool, foo> t1(5, 12.2f, true, foo(4));
  182. get<0>(t1) = 6;
  183. get<1>(t1) = 2.2f;
  184. get<2>(t1) = false;
  185. get<3>(t1) = foo(5);
  186. BOOST_CHECK(get<0>(t1) == 6);
  187. BOOST_CHECK(get<1>(t1) > 2.1f && get<1>(t1) < 2.3f);
  188. BOOST_CHECK(get<2>(t1) == false);
  189. BOOST_CHECK(get<3>(t1) == foo(5));
  190. }
  191. // ----------------------------------------------------------------------------
  192. // make_tuple tests -----------------------------------------------------------
  193. // ----------------------------------------------------------------------------
  194. void
  195. make_tuple_test()
  196. {
  197. tuple<int, char> t1 = make_tuple(5, 'a');
  198. BOOST_CHECK(get<0>(t1) == 5);
  199. BOOST_CHECK(get<1>(t1) == 'a');
  200. tuple<int, std::string> t2;
  201. t2 = boost::make_tuple((short int)2, std::string("Hi"));
  202. BOOST_CHECK(get<0>(t2) == 2);
  203. BOOST_CHECK(get<1>(t2) == "Hi");
  204. A a = A(); B b;
  205. const A ca = a;
  206. make_tuple(boost::cref(a), b);
  207. make_tuple(boost::ref(a), b);
  208. make_tuple(boost::ref(a), boost::cref(b));
  209. make_tuple(boost::ref(ca));
  210. // the result of make_tuple is assignable:
  211. BOOST_CHECK(make_tuple(2, 4, 6) ==
  212. (make_tuple(1, 2, 3) = make_tuple(2, 4, 6)));
  213. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  214. make_tuple("Donald", "Daisy"); // should work;
  215. #endif
  216. // std::make_pair("Doesn't","Work"); // fails
  217. // You can store a reference to a function in a tuple
  218. tuple<void(&)()> adf(make_tuple_test);
  219. dummy(adf); // avoid warning for unused variable
  220. // But make_tuple doesn't work
  221. // with function references, since it creates a const qualified function type
  222. // make_tuple(make_tuple_test);
  223. // With function pointers, make_tuple works just fine
  224. #if !defined(__BORLANDC__) || __BORLAND__ > 0x0551
  225. make_tuple(&make_tuple_test);
  226. #endif
  227. // NOTE:
  228. //
  229. // wrapping it the function reference with ref helps on gcc 2.95.2.
  230. // on edg 2.43. it results in a catastrophic error?
  231. // make_tuple(ref(foo3));
  232. // It seems that edg can't use implicitly the ref's conversion operator, e.g.:
  233. // typedef void (&func_t) (void);
  234. // func_t fref = static_cast<func_t>(ref(make_tuple_test)); // works fine
  235. // func_t fref = ref(make_tuple_test); // error
  236. // This is probably not a very common situation, so currently
  237. // I don't know how which compiler is right (JJ)
  238. }
  239. void
  240. tie_test()
  241. {
  242. int a;
  243. char b;
  244. foo c(5);
  245. tie(a, b, c) = make_tuple(2, 'a', foo(3));
  246. BOOST_CHECK(a == 2);
  247. BOOST_CHECK(b == 'a');
  248. BOOST_CHECK(c == foo(3));
  249. tie(a, tuples::ignore, c) = make_tuple((short int)5, false, foo(5));
  250. BOOST_CHECK(a == 5);
  251. BOOST_CHECK(b == 'a');
  252. BOOST_CHECK(c == foo(5));
  253. // testing assignment from std::pair
  254. int i, j;
  255. tie (i, j) = std::make_pair(1, 2);
  256. BOOST_CHECK(i == 1 && j == 2);
  257. tuple<int, int, float> ta;
  258. #ifdef E11
  259. ta = std::make_pair(1, 2); // should fail, tuple is of length 3, not 2
  260. #endif
  261. dummy(ta);
  262. }
  263. // ----------------------------------------------------------------------------
  264. // - testing tuple equality -------------------------------------------------
  265. // ----------------------------------------------------------------------------
  266. void
  267. equality_test()
  268. {
  269. tuple<int, char> t1(5, 'a');
  270. tuple<int, char> t2(5, 'a');
  271. BOOST_CHECK(t1 == t2);
  272. tuple<int, char> t3(5, 'b');
  273. tuple<int, char> t4(2, 'a');
  274. BOOST_CHECK(t1 != t3);
  275. BOOST_CHECK(t1 != t4);
  276. BOOST_CHECK(!(t1 != t2));
  277. }
  278. // ----------------------------------------------------------------------------
  279. // - testing tuple comparisons -----------------------------------------------
  280. // ----------------------------------------------------------------------------
  281. void
  282. ordering_test()
  283. {
  284. tuple<int, float> t1(4, 3.3f);
  285. tuple<short, float> t2(5, 3.3f);
  286. tuple<long, double> t3(5, 4.4);
  287. BOOST_CHECK(t1 < t2);
  288. BOOST_CHECK(t1 <= t2);
  289. BOOST_CHECK(t2 > t1);
  290. BOOST_CHECK(t2 >= t1);
  291. BOOST_CHECK(t2 < t3);
  292. BOOST_CHECK(t2 <= t3);
  293. BOOST_CHECK(t3 > t2);
  294. BOOST_CHECK(t3 >= t2);
  295. }
  296. // ----------------------------------------------------------------------------
  297. // - testing cons lists -------------------------------------------------------
  298. // ----------------------------------------------------------------------------
  299. void cons_test()
  300. {
  301. using tuples::cons;
  302. using tuples::null_type;
  303. cons<volatile float, null_type> a(1, null_type());
  304. cons<const int, cons<volatile float, null_type> > b(2,a);
  305. int i = 3;
  306. cons<int&, cons<const int, cons<volatile float, null_type> > > c(i, b);
  307. BOOST_CHECK(make_tuple(3,2,1)==c);
  308. cons<char, cons<int, cons<float, null_type> > > x;
  309. dummy(x);
  310. }
  311. // ----------------------------------------------------------------------------
  312. // - testing const tuples -----------------------------------------------------
  313. // ----------------------------------------------------------------------------
  314. void const_tuple_test()
  315. {
  316. const tuple<int, float> t1(5, 3.3f);
  317. BOOST_CHECK(get<0>(t1) == 5);
  318. BOOST_CHECK(get<1>(t1) == 3.3f);
  319. }
  320. // ----------------------------------------------------------------------------
  321. // - testing length -----------------------------------------------------------
  322. // ----------------------------------------------------------------------------
  323. void tuple_length_test()
  324. {
  325. typedef tuple<int, float, double> t1;
  326. using tuples::cons;
  327. typedef cons<int, cons< float, cons <double, tuples::null_type> > > t1_cons;
  328. typedef tuple<> t2;
  329. typedef tuples::null_type t3;
  330. BOOST_STATIC_ASSERT(tuples::length<t1>::value == 3);
  331. BOOST_STATIC_ASSERT(tuples::length<t1_cons>::value == 3);
  332. BOOST_STATIC_ASSERT(tuples::length<t2>::value == 0);
  333. BOOST_STATIC_ASSERT(tuples::length<t3>::value == 0);
  334. }
  335. // ----------------------------------------------------------------------------
  336. // - testing swap -----------------------------------------------------------
  337. // ----------------------------------------------------------------------------
  338. void tuple_swap_test()
  339. {
  340. tuple<int, float, double> t1(1, 2.0f, 3.0), t2(4, 5.0f, 6.0);
  341. swap(t1, t2);
  342. BOOST_CHECK(get<0>(t1) == 4);
  343. BOOST_CHECK(get<1>(t1) == 5.0f);
  344. BOOST_CHECK(get<2>(t1) == 6.0);
  345. BOOST_CHECK(get<0>(t2) == 1);
  346. BOOST_CHECK(get<1>(t2) == 2.0f);
  347. BOOST_CHECK(get<2>(t2) == 3.0);
  348. int i = 1,j = 2;
  349. boost::tuple<int&> t3(i), t4(j);
  350. swap(t3, t4);
  351. BOOST_CHECK(i == 2);
  352. BOOST_CHECK(j == 1);
  353. }
  354. // ----------------------------------------------------------------------------
  355. // - main ---------------------------------------------------------------------
  356. // ----------------------------------------------------------------------------
  357. int test_main(int, char *[]) {
  358. construction_test();
  359. element_access_test();
  360. copy_test();
  361. mutate_test();
  362. make_tuple_test();
  363. tie_test();
  364. equality_test();
  365. ordering_test();
  366. cons_test();
  367. const_tuple_test();
  368. tuple_length_test();
  369. tuple_swap_test();
  370. return 0;
  371. }