123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- // 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 boost;
- // ----------------------------------------------------------------------------
- // helpers
- // ----------------------------------------------------------------------------
- class A {};
- class B {};
- class C {};
- // classes with different kinds of conversions
- class AA {};
- class BB : public AA {};
- struct CC { CC() {} CC(const BB&) {} };
- struct DD { operator CC() const { return CC(); }; };
- // something to prevent warnings for unused variables
- template<class T> void dummy(const T&) {}
- // no public default constructor
- class 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 constructor
- class 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__ > 0x0551
- typedef tuple<B(A::*)(C&), A&> t7;
- #endif
- // -----------------------------------------------------------------------
- // -tuple construction tests ---------------------------------------------
- // -----------------------------------------------------------------------
- no_copy y;
- tuple<no_copy&> x = tuple<no_copy&>(y); // ok
- char cs[10];
- tuple<char(&)[10]> v2(cs); // ok
- void
- construction_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 -----------------------------------------------------------
- // ----------------------------------------------------------------------------
- void
- copy_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);
- }
- void
- mutate_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 -----------------------------------------------------------
- // ----------------------------------------------------------------------------
- void
- make_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 = boost::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)
- }
- void
- tie_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 -------------------------------------------------
- // ----------------------------------------------------------------------------
- void
- equality_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 -----------------------------------------------
- // ----------------------------------------------------------------------------
- void
- ordering_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);
- }
- // ----------------------------------------------------------------------------
- // - testing swap -----------------------------------------------------------
- // ----------------------------------------------------------------------------
- void tuple_swap_test()
- {
- tuple<int, float, double> t1(1, 2.0f, 3.0), t2(4, 5.0f, 6.0);
- swap(t1, t2);
- BOOST_CHECK(get<0>(t1) == 4);
- BOOST_CHECK(get<1>(t1) == 5.0f);
- BOOST_CHECK(get<2>(t1) == 6.0);
- BOOST_CHECK(get<0>(t2) == 1);
- BOOST_CHECK(get<1>(t2) == 2.0f);
- BOOST_CHECK(get<2>(t2) == 3.0);
- int i = 1,j = 2;
- boost::tuple<int&> t3(i), t4(j);
- swap(t3, t4);
- BOOST_CHECK(i == 2);
- BOOST_CHECK(j == 1);
- }
- // ----------------------------------------------------------------------------
- // - 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();
- tuple_swap_test();
- return 0;
- }
|