tuple_test_bench.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 478 行
CPP
478 行
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)// For more information, see http://www.boost.org// tuple_test_bench.cpp --------------------------------#define BOOST_INCLUDE_MAIN // for testing, include rather than link#include <boost/test/test_tools.hpp> // see "Header Implementation Option"#include "boost/tuple/tuple.hpp"#include "boost/tuple/tuple_comparison.hpp"#include "boost/type_traits/is_const.hpp"#include "boost/ref.hpp"#include <string>#include <utility>using namespace std;using namespace boost;// ----------------------------------------------------------------------------// helpers // ----------------------------------------------------------------------------class A {}; class B {}; class C {};// classes with different kinds of conversionsclass AA {};class BB : public AA {}; struct CC { CC() {} CC(const BB&) {} };struct DD { operator CC() const { return CC(); }; };// something to prevent warnings for unused variablestemplate<class T> void dummy(const T&) {}// no public default constructorclass foo {public: explicit foo(int v) : val(v) {} bool operator==(const foo& other) const { return val == other.val; }private: foo() {} int val;};// another class without a public default constructorclass no_def_constructor { no_def_constructor() {}public: no_def_constructor(std::string) {}};// A non-copyable class class no_copy { no_copy(const no_copy&) {}public: no_copy() {};};// ----------------------------------------------------------------------------// Testing different element types --------------------------------------------// ----------------------------------------------------------------------------typedef tuple<int> t1;typedef tuple<double&, const double&, const double, double*, const double*> t2;typedef tuple<A, int(*)(char, int), C> t3;typedef tuple<std::string, std::pair<A, B> > t4;typedef tuple<A*, tuple<const A*, const B&, C>, bool, void*> t5;typedef tuple<volatile int, const volatile char&, int(&)(float) > t6;# if !defined(__BORLANDC__) || __BORLAND__ > 0x0551typedef tuple<B(A::*)(C&), A&> t7;#endif// -----------------------------------------------------------------------// -tuple construction tests ---------------------------------------------// -----------------------------------------------------------------------no_copy y;tuple<no_copy&> x = tuple<no_copy&>(y); // okchar cs[10];tuple<char(&)[10]> v2(cs); // okvoidconstruction_test(){ // Note, the get function can be called without the tuples:: qualifier, // as it is lifted to namespace boost with a "using tuples::get" but // MSVC 6.0 just cannot find get without the namespace qualifier tuple<int> t1; BOOST_CHECK(get<0>(t1) == int()); tuple<float> t2(5.5f); BOOST_CHECK(get<0>(t2) > 5.4f && get<0>(t2) < 5.6f); tuple<foo> t3(foo(12)); BOOST_CHECK(get<0>(t3) == foo(12)); tuple<double> t4(t2); BOOST_CHECK(get<0>(t4) > 5.4 && get<0>(t4) < 5.6); tuple<int, float> t5; BOOST_CHECK(get<0>(t5) == int()); BOOST_CHECK(get<1>(t5) == float()); tuple<int, float> t6(12, 5.5f); BOOST_CHECK(get<0>(t6) == 12); BOOST_CHECK(get<1>(t6) > 5.4f && get<1>(t6) < 5.6f); tuple<int, float> t7(t6); BOOST_CHECK(get<0>(t7) == 12); BOOST_CHECK(get<1>(t7) > 5.4f && get<1>(t7) < 5.6f); tuple<long, double> t8(t6); BOOST_CHECK(get<0>(t8) == 12); BOOST_CHECK(get<1>(t8) > 5.4f && get<1>(t8) < 5.6f); dummy( tuple<no_def_constructor, no_def_constructor, no_def_constructor>( std::string("Jaba"), // ok, since the default std::string("Daba"), // constructor is not used std::string("Doo") ) );// testing default values dummy(tuple<int, double>()); dummy(tuple<int, double>(1)); dummy(tuple<int, double>(1,3.14)); // dummy(tuple<double&>()); // should fail, not defaults for references // dummy(tuple<const double&>()); // likewise double dd = 5; dummy(tuple<double&>(dd)); // ok dummy(tuple<const double&>(dd+3.14)); // ok, but dangerous // dummy(tuple<double&>(dd+3.14)); // should fail, // // temporary to non-const reference}// ----------------------------------------------------------------------------// - testing element access ---------------------------------------------------// ----------------------------------------------------------------------------void element_access_test(){ double d = 2.7; A a; tuple<int, double&, const A&, int> t(1, d, a, 2); const tuple<int, double&, const A, int> ct = t; int i = get<0>(t); int i2 = get<3>(t); BOOST_CHECK(i == 1 && i2 == 2); int j = get<0>(ct); BOOST_CHECK(j == 1); get<0>(t) = 5; BOOST_CHECK(t.head == 5); // get<0>(ct) = 5; // can't assign to const double e = get<1>(t); BOOST_CHECK(e > 2.69 && e < 2.71); get<1>(t) = 3.14+i; BOOST_CHECK(get<1>(t) > 4.13 && get<1>(t) < 4.15); // get<4>(t) = A(); // can't assign to const // dummy(get<5>(ct)); // illegal index ++get<0>(t); BOOST_CHECK(get<0>(t) == 6); BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<0, tuple<int, float> >::type>::value != true));#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<0, const tuple<int, float> >::type>::value));#endif BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<1, tuple<int, float> >::type>::value != true));#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<1, const tuple<int, float> >::type>::value));#endif dummy(i); dummy(i2); dummy(j); dummy(e); // avoid warns for unused variables}// ----------------------------------------------------------------------------// - copying tuples -----------------------------------------------------------// ----------------------------------------------------------------------------voidcopy_test(){ tuple<int, char> t1(4, 'a'); tuple<int, char> t2(5, 'b'); t2 = t1; BOOST_CHECK(get<0>(t1) == get<0>(t2)); BOOST_CHECK(get<1>(t1) == get<1>(t2)); tuple<long, std::string> t3(2, "a"); t3 = t1; BOOST_CHECK((double)get<0>(t1) == get<0>(t3)); BOOST_CHECK(get<1>(t1) == get<1>(t3)[0]);// testing copy and assignment with implicit conversions between elements// testing tie tuple<char, BB*, BB, DD> t; tuple<int, AA*, CC, CC> a(t); a = t; int i; char c; double d; tie(i, c, d) = make_tuple(1, 'a', 5.5); BOOST_CHECK(i==1); BOOST_CHECK(c=='a'); BOOST_CHECK(d>5.4 && d<5.6);}voidmutate_test(){ tuple<int, float, bool, foo> t1(5, 12.2f, true, foo(4)); get<0>(t1) = 6; get<1>(t1) = 2.2f; get<2>(t1) = false; get<3>(t1) = foo(5); BOOST_CHECK(get<0>(t1) == 6); BOOST_CHECK(get<1>(t1) > 2.1f && get<1>(t1) < 2.3f); BOOST_CHECK(get<2>(t1) == false); BOOST_CHECK(get<3>(t1) == foo(5));}// ----------------------------------------------------------------------------// make_tuple tests -----------------------------------------------------------// ----------------------------------------------------------------------------voidmake_tuple_test(){ tuple<int, char> t1 = make_tuple(5, 'a'); BOOST_CHECK(get<0>(t1) == 5); BOOST_CHECK(get<1>(t1) == 'a'); tuple<int, std::string> t2; t2 = make_tuple((short int)2, std::string("Hi")); BOOST_CHECK(get<0>(t2) == 2); BOOST_CHECK(get<1>(t2) == "Hi"); A a = A(); B b; const A ca = a; make_tuple(boost::cref(a), b); make_tuple(boost::ref(a), b); make_tuple(boost::ref(a), boost::cref(b)); make_tuple(boost::ref(ca)); // the result of make_tuple is assignable: BOOST_CHECK(make_tuple(2, 4, 6) == (make_tuple(1, 2, 3) = make_tuple(2, 4, 6)));#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION make_tuple("Donald", "Daisy"); // should work;#endif // std::make_pair("Doesn't","Work"); // fails// You can store a reference to a function in a tuple tuple<void(&)()> adf(make_tuple_test); dummy(adf); // avoid warning for unused variable // But make_tuple doesn't work // with function references, since it creates a const qualified function type// make_tuple(make_tuple_test); // With function pointers, make_tuple works just fine#if !defined(__BORLANDC__) || __BORLAND__ > 0x0551 make_tuple(&make_tuple_test);#endif // NOTE://// wrapping it the function reference with ref helps on gcc 2.95.2.// on edg 2.43. it results in a catastrophic error?// make_tuple(ref(foo3));// It seems that edg can't use implicitly the ref's conversion operator, e.g.:// typedef void (&func_t) (void);// func_t fref = static_cast<func_t>(ref(make_tuple_test)); // works fine // func_t fref = ref(make_tuple_test); // error// This is probably not a very common situation, so currently// I don't know how which compiler is right (JJ)}voidtie_test(){ int a; char b; foo c(5); tie(a, b, c) = make_tuple(2, 'a', foo(3)); BOOST_CHECK(a == 2); BOOST_CHECK(b == 'a'); BOOST_CHECK(c == foo(3)); tie(a, tuples::ignore, c) = make_tuple((short int)5, false, foo(5)); BOOST_CHECK(a == 5); BOOST_CHECK(b == 'a'); BOOST_CHECK(c == foo(5));// testing assignment from std::pair int i, j; tie (i, j) = std::make_pair(1, 2); BOOST_CHECK(i == 1 && j == 2); tuple<int, int, float> ta;#ifdef E11 ta = std::make_pair(1, 2); // should fail, tuple is of length 3, not 2#endif dummy(ta);}// ----------------------------------------------------------------------------// - testing tuple equality -------------------------------------------------// ----------------------------------------------------------------------------voidequality_test(){ tuple<int, char> t1(5, 'a'); tuple<int, char> t2(5, 'a'); BOOST_CHECK(t1 == t2); tuple<int, char> t3(5, 'b'); tuple<int, char> t4(2, 'a'); BOOST_CHECK(t1 != t3); BOOST_CHECK(t1 != t4); BOOST_CHECK(!(t1 != t2));}// ----------------------------------------------------------------------------// - testing tuple comparisons -----------------------------------------------// ----------------------------------------------------------------------------voidordering_test(){ tuple<int, float> t1(4, 3.3f); tuple<short, float> t2(5, 3.3f); tuple<long, double> t3(5, 4.4); BOOST_CHECK(t1 < t2); BOOST_CHECK(t1 <= t2); BOOST_CHECK(t2 > t1); BOOST_CHECK(t2 >= t1); BOOST_CHECK(t2 < t3); BOOST_CHECK(t2 <= t3); BOOST_CHECK(t3 > t2); BOOST_CHECK(t3 >= t2);}// ----------------------------------------------------------------------------// - testing cons lists -------------------------------------------------------// ----------------------------------------------------------------------------void cons_test(){ using tuples::cons; using tuples::null_type; cons<volatile float, null_type> a(1, null_type()); cons<const int, cons<volatile float, null_type> > b(2,a); int i = 3; cons<int&, cons<const int, cons<volatile float, null_type> > > c(i, b); BOOST_CHECK(make_tuple(3,2,1)==c); cons<char, cons<int, cons<float, null_type> > > x; dummy(x);}// ----------------------------------------------------------------------------// - testing const tuples -----------------------------------------------------// ----------------------------------------------------------------------------void const_tuple_test(){ const tuple<int, float> t1(5, 3.3f); BOOST_CHECK(get<0>(t1) == 5); BOOST_CHECK(get<1>(t1) == 3.3f);}// ----------------------------------------------------------------------------// - testing length -----------------------------------------------------------// ----------------------------------------------------------------------------void tuple_length_test(){ typedef tuple<int, float, double> t1; using tuples::cons; typedef cons<int, cons< float, cons <double, tuples::null_type> > > t1_cons; typedef tuple<> t2; typedef tuples::null_type t3; BOOST_STATIC_ASSERT(tuples::length<t1>::value == 3); BOOST_STATIC_ASSERT(tuples::length<t1_cons>::value == 3); BOOST_STATIC_ASSERT(tuples::length<t2>::value == 0); BOOST_STATIC_ASSERT(tuples::length<t3>::value == 0);}// ----------------------------------------------------------------------------// - main ---------------------------------------------------------------------// ----------------------------------------------------------------------------int test_main(int, char *[]) { construction_test(); element_access_test(); copy_test(); mutate_test(); make_tuple_test(); tie_test(); equality_test(); ordering_test(); cons_test(); const_tuple_test(); tuple_length_test(); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?