// tuple_test_bench.cpp -------------------------------- // Defining any of E1 to E5 or E7 to E11 opens some illegal code that // should cause the compliation to fail. #define BOOST_INCLUDE_MAIN // for testing, include rather than link #include // see "Header Implementation Option" #include "boost/tuple/tuple.hpp" #include "boost/tuple/tuple_comparison.hpp" #include #include #include #include #include #include using namespace std; using namespace boost; template void dummy(const T&) {} class A {}; class B {}; class C {}; typedef int(t)(float); // some arbitrary tuple definitions typedef tuple t1; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) typedef tuple t2; typedef tuple t3; typedef tuple > t4; typedef tuple, bool, void*> t5; typedef tuple t6; # if !defined(__BORLANDC__) || __BORLAND__ > 0x0551 typedef tuple t7; #endif #endif // A non-copyable class class no_copy { no_copy(const no_copy&) {} public: no_copy() {}; }; no_copy y; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) tuple x = tuple(y); // ok #endif #ifdef E1 tuple v1; // should faild #endif char cs[10]; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) tuple v2(cs); // ok #endif #ifdef E2 tuple v3; // should fail, arrays must be stored as references #endif // -tuple construction tests ------------------------------------ // a class without a public default constructor class no_def_constructor { no_def_constructor() {} public: no_def_constructor(std::string) {} // can be constructed with a string }; void foo1() { #ifdef E3 dummy(tuple()); // should fail #endif dummy( tuple( std::string("Jaba"), // ok, since the default std::string("Daba"), // constructor is not used std::string("Doo"))); } void foo2() { // testing default values dummy(tuple()); dummy(tuple(1)); dummy(tuple(1,3.14)); #ifdef E4 dummy(tuple()); // should fail, not defaults for references dummy(tuple()); // likewise #endif double dd = 5; #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) dummy(tuple(dd)); // ok #endif #ifdef E5 dummy(tuple(dd+3.14)); // should fail, temporary to non-const reference #endif #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) dummy(tuple(dd+3.14)); // ok, but potentially dangerous #endif } // make_tuple ------------------------------------------ void foo3() { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) A a; B b; const A ca = a; make_tuple(cref(a), b); make_tuple(ref(a), b); make_tuple(ref(a), cref(b)); make_tuple(ref(ca)); #endif #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) make_tuple("Donald", "Daisy"); // should work; #endif #ifdef E7 std::make_pair("Doesn't","Work"); // fails #endif // You can store a reference to a function in a tuple #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) tuple adf(foo3); dummy(adf); // avoid warning for unused variable #endif // But make_tuple doesn't work // with function references, since it creates a const qualified function type // make_tuple(foo3); // With function pointers, make_tuple works just fine #if !defined(__BORLANDC__) || __BORLAND__ > 0x0551 make_tuple(&foo3); #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 (&foo3type) (void); // foo3type foo3ref = static_cast(ref(foo3)); // works fine // foo3type foo3ref = ref(foo3); // error // This is probably not a very common situation, so currently // I don't know how which compiler is right (JJ) } // - testing element access void foo4() { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) double d = 2.7; A a; tuple t(1, d, a); const tuple ct = t; int i = get<0>(t); int j = get<0>(ct); BOOST_TEST(i == 1 && j == 1); get<0>(t) = 5; BOOST_TEST(t.head == 5); #ifdef E8 get<0>(ct) = 5; // can't assign to const #endif double e = get<1>(t); BOOST_TEST(e > 2.69 && e < 2.71); get<1>(t) = 3.14+i; BOOST_TEST(get<1>(t) > 4.13 && get<1>(t) < 4.15); #ifdef E9 get<4>(t) = A(); // can't assign to const #endif #ifdef E10 dummy(get<5>(ct)); // illegal index #endif ++get<0>(t); BOOST_TEST(get<0>(t) == 6); dummy(i); dummy(j); dummy(e); // avoid warns for unused variables #endif } // testing copy and assignment with implicit conversions between elements // testing tie class AA {}; class BB : public AA {}; struct CC { CC() {} CC(const BB& b) {} }; struct DD { operator CC() const { return CC(); }; }; void foo5() { tuple t; tuple a(t); a = t; } void foo6() { int i; char c; double d; tie(i, c, d) = make_tuple(1, 'a', 5.5); BOOST_TEST(i==1); BOOST_TEST(c=='a'); BOOST_TEST(d==5.5); } // testing tie // testing assignment from std::pair void foo7() { #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) int i, j; tie (i, j) = std::make_pair(1, 2); BOOST_TEST(i == 1 && j == 2); #endif tuple a; #ifdef E11 a = std::make_pair(1, 2); // should fail, tuple is of length 3, not 2 #endif // the result of make_tuple is assignable: BOOST_TEST(make_tuple(2, 4, 6) == (make_tuple(1, 2, 3) = make_tuple(2, 4, 6))); dummy(a); } // -------------------------------- // ---------------------------- int test_main(int, char *[]) { foo1(); foo2(); foo3(); foo4(); foo5(); foo6(); foo7(); return 0; }