Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83091 - in sandbox/tuple-move: boost/tuple/detail libs/tuple/test
From: adam.wulkiewicz_at_[hidden]
Date: 2013-02-22 19:50:18


Author: awulkiew
Date: 2013-02-22 19:50:17 EST (Fri, 22 Feb 2013)
New Revision: 83091
URL: http://svn.boost.org/trac/boost/changeset/83091

Log:
movable tuple: fixed compilation error in c++11 for tuples storing references.
This was caused by remove_reference<T>::type && move(...).
This workaround uses T& if is_reference<stored_head_type>::value is true or remove_reference<T>::type && if it isn't.
Added:
   sandbox/tuple-move/libs/tuple/test/another_tuple_test_bench.cpp (contents, props changed)
   sandbox/tuple-move/libs/tuple/test/io_test.cpp (contents, props changed)
   sandbox/tuple-move/libs/tuple/test/tuple_test_bench.cpp (contents, props changed)
Text files modified:
   sandbox/tuple-move/boost/tuple/detail/tuple_basic.hpp | 29 +++++++++++++++++++++++++++--
   sandbox/tuple-move/libs/tuple/test/Jamfile.v2 | 9 ++++++---
   sandbox/tuple-move/libs/tuple/test/tuple_move.cpp | 6 +++---
   3 files changed, 36 insertions(+), 8 deletions(-)

Modified: sandbox/tuple-move/boost/tuple/detail/tuple_basic.hpp
==============================================================================
--- sandbox/tuple-move/boost/tuple/detail/tuple_basic.hpp (original)
+++ sandbox/tuple-move/boost/tuple/detail/tuple_basic.hpp 2013-02-22 19:50:17 EST (Fri, 22 Feb 2013)
@@ -252,6 +252,29 @@
   typedef non_storeable_type<void> type;
 };
 
+// These templates return reference if IsRef (stored type) is a reference
+// or rval reference if it isn't
+
+template <bool Cond, class T1, class T2> struct if_c { typedef T1 type; };
+template <class T1, class T2> struct if_c<false, T1, T2> { typedef T2 type; };
+
+template <bool IsRef> struct ref_or_move {
+ template <class T> inline static
+ T & apply(T & t) { return t; }
+};
+
+template <> struct ref_or_move<false> {
+ template <class T> inline static
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ typename if_c<
+ ::boost::has_move_emulation_enabled<T>::value, rv<T>&, T&
+ >::type
+#else
+ typename ::boost::remove_reference<T>::type &&
+#endif
+ apply(T & t) { return ::boost::move(t); }
+};
+
 } // detail
 
 template <class HT, class TT>
@@ -340,7 +363,9 @@
 
   // implicit version may be deleted in C++11
   cons( const cons& u ) : head(u.head), tail(u.tail) {}
- cons( BOOST_RV_REF(cons) u ) : head(::boost::move(u.head)), tail(::boost::move(u.tail)) {}
+ cons( BOOST_RV_REF(cons) u )
+ : head(detail::ref_or_move< ::boost::is_reference<stored_head_type>::value >::apply(u.head))
+ , tail(::boost::move(u.tail)) {}
 
   template <class HT2, class TT2>
   cons& operator=( BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(cons, HT2, TT2) u ) {
@@ -455,7 +480,7 @@
 
   // implicit version may be deleted in C++11
   cons( const cons& u ) : head(u.head) {}
- cons( BOOST_RV_REF(cons) u ) : head(::boost::move(u.head)) {}
+ cons( BOOST_RV_REF(cons) u ) : head(detail::ref_or_move< ::boost::is_reference<stored_head_type>::value >::apply(u.head)) {}
 
   template <class HT2>
   cons& operator=(BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(cons, HT2, null_type) u )

Modified: sandbox/tuple-move/libs/tuple/test/Jamfile.v2
==============================================================================
--- sandbox/tuple-move/libs/tuple/test/Jamfile.v2 (original)
+++ sandbox/tuple-move/libs/tuple/test/Jamfile.v2 2013-02-22 19:50:17 EST (Fri, 22 Feb 2013)
@@ -8,16 +8,19 @@
 
 import testing ;
 
-project boost-tuple-move-test
+project boost-tuple-test
     :
     requirements
         <include>.
         <include>..
         <include>../..
         <include>../../..
+ <library>/boost/test//boost_test_exec_monitor
     ;
 
-test-suite boost-tuple-move
- :
+test-suite tuple :
+ [ run tuple_test_bench.cpp ]
+ [ run io_test.cpp ]
+ [ run another_tuple_test_bench.cpp ]
     [ run tuple_move.cpp ]
     ;

Added: sandbox/tuple-move/libs/tuple/test/another_tuple_test_bench.cpp
==============================================================================
--- (empty file)
+++ sandbox/tuple-move/libs/tuple/test/another_tuple_test_bench.cpp 2013-02-22 19:50:17 EST (Fri, 22 Feb 2013)
@@ -0,0 +1,163 @@
+// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi_at_[hidden])
+//
+// 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
+
+
+// another_test_bench.cpp --------------------------------
+
+// This file has various tests to see that things that shouldn't
+// compile, don't compile.
+
+// 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 <boost/test/test_tools.hpp> // see "Header Implementation Option"
+
+#include "boost/tuple/tuple.hpp"
+
+#include <string>
+#include <utility>
+
+using namespace boost;
+using namespace boost::tuples;
+
+
+template<class T> void dummy(const T&) {}
+
+class A {}; class B {}; class C {};
+
+// A non-copyable class
+class no_copy {
+ no_copy(const no_copy&) {}
+public:
+ no_copy() {};
+};
+
+no_copy y;
+
+#ifdef E1
+tuple<no_copy> v1; // should faild
+#endif
+
+
+#ifdef E2
+char cs[10];
+tuple<char[10]> v3; // should fail, arrays must be stored as references
+#endif
+
+// 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<no_def_constructor, no_def_constructor, no_def_constructor>());
+ // should fail
+
+#endif
+}
+
+void foo2() {
+// testing default values
+#ifdef E4
+ dummy(tuple<double&>()); // should fail, not defaults for references
+ dummy(tuple<const double&>()); // likewise
+#endif
+
+#ifdef E5
+ double dd = 5;
+ dummy(tuple<double&>(dd+3.14)); // should fail, temporary to non-const reference
+#endif
+}
+
+
+
+// make_tuple ------------------------------------------
+
+
+ void foo3() {
+#ifdef E7
+ std::make_pair("Doesn't","Work"); // fails
+#endif
+ // make_tuple("Does", "Work"); // this should work
+}
+
+
+
+// - testing element access
+
+void foo4()
+{
+ double d = 2.7;
+ A a;
+ tuple<int, double&, const A&> t(1, d, a);
+ const tuple<int, double&, const A> ct = t;
+ (void)ct;
+#ifdef E8
+ get<0>(ct) = 5; // can't assign to const
+#endif
+
+#ifdef E9
+ get<4>(t) = A(); // can't assign to const
+#endif
+#ifdef E10
+ dummy(get<5>(ct)); // illegal index
+#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<char, BB*, BB, DD> t;
+ (void)t;
+ tuple<char, char> aaa;
+ tuple<int, int> bbb(aaa);
+ (void)bbb;
+ // tuple<int, AA*, CC, CC> a = t;
+ // a = t;
+ }
+
+
+// testing tie
+// testing assignment from std::pair
+void foo7() {
+
+ tuple<int, int, float> a;
+#ifdef E11
+ a = std::make_pair(1, 2); // should fail, tuple is of length 3, not 2
+#endif
+
+ dummy(a);
+}
+
+
+
+// --------------------------------
+// ----------------------------
+int test_main(int, char *[]) {
+
+ foo1();
+ foo2();
+ foo3();
+ foo4();
+ foo5();
+
+ foo7();
+
+ return 0;
+}

Added: sandbox/tuple-move/libs/tuple/test/io_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/tuple-move/libs/tuple/test/io_test.cpp 2013-02-22 19:50:17 EST (Fri, 22 Feb 2013)
@@ -0,0 +1,143 @@
+// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi_at_[hidden])
+//
+// 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
+
+// -- io_test.cpp -----------------------------------------------
+//
+// Testing the I/O facilities of tuples
+
+#define BOOST_INCLUDE_MAIN // for testing, include rather than link
+#include "boost/test/test_tools.hpp" // see "Header Implementation Option"
+
+#include "boost/tuple/tuple_io.hpp"
+#include "boost/tuple/tuple_comparison.hpp"
+
+#include <fstream>
+#include <iterator>
+#include <algorithm>
+#include <string>
+#include <iomanip>
+
+#if defined BOOST_NO_STRINGSTREAM
+#include <strstream>
+#else
+#include <sstream>
+#endif
+
+using namespace boost;
+
+#if defined BOOST_NO_STRINGSTREAM
+typedef std::ostrstream useThisOStringStream;
+typedef std::istrstream useThisIStringStream;
+#else
+typedef std::ostringstream useThisOStringStream;
+typedef std::istringstream useThisIStringStream;
+#endif
+
+int test_main(int argc, char * argv[] ) {
+ (void)argc;
+ (void)argv;
+ using boost::tuples::set_close;
+ using boost::tuples::set_open;
+ using boost::tuples::set_delimiter;
+
+ useThisOStringStream os1;
+
+ // Set format [a, b, c] for os1
+ os1 << set_open('[');
+ os1 << set_close(']');
+ os1 << set_delimiter(',');
+ os1 << make_tuple(1, 2, 3);
+ BOOST_CHECK (os1.str() == std::string("[1,2,3]") );
+
+ {
+ useThisOStringStream os2;
+ // Set format (a:b:c) for os2;
+ os2 << set_open('(');
+ os2 << set_close(')');
+ os2 << set_delimiter(':');
+#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ os2 << make_tuple("TUPU", "HUPU", "LUPU", 4.5);
+ BOOST_CHECK (os2.str() == std::string("(TUPU:HUPU:LUPU:4.5)") );
+#endif
+ }
+
+ // The format is still [a, b, c] for os1
+ os1 << make_tuple(1, 2, 3);
+ BOOST_CHECK (os1.str() == std::string("[1,2,3][1,2,3]") );
+
+ // check empty tuple.
+ useThisOStringStream os3;
+ os3 << make_tuple();
+ BOOST_CHECK (os3.str() == std::string("()") );
+ os3 << set_open('[');
+ os3 << set_close(']');
+ os3 << make_tuple();
+ BOOST_CHECK (os3.str() == std::string("()[]") );
+
+ // check width
+ useThisOStringStream os4;
+ os4 << std::setw(10) << make_tuple(1, 2, 3);
+ BOOST_CHECK (os4.str() == std::string(" (1 2 3)") );
+
+ std::ofstream tmp("temp.tmp");
+
+#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ tmp << make_tuple("One", "Two", 3);
+#endif
+ tmp << set_delimiter(':');
+ tmp << make_tuple(1000, 2000, 3000) << std::endl;
+
+ tmp.close();
+
+ // When teading tuples from a stream, manipulators must be set correctly:
+ std::ifstream tmp3("temp.tmp");
+ tuple<std::string, std::string, int> j;
+
+#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ tmp3 >> j;
+ BOOST_CHECK (tmp3.good() );
+#endif
+
+ tmp3 >> set_delimiter(':');
+ tuple<int, int, int> i;
+ tmp3 >> i;
+ BOOST_CHECK (tmp3.good() );
+
+ tmp3.close();
+
+
+ // reading tuple<int, int, int> in format (a b c);
+ useThisIStringStream is1("(100 200 300)");
+
+ tuple<int, int, int> ti1;
+ BOOST_CHECK(bool(is1 >> ti1));
+ BOOST_CHECK(ti1 == make_tuple(100, 200, 300));
+
+ useThisIStringStream is2("()");
+ tuple<> ti2;
+ BOOST_CHECK(bool(is2 >> ti2));
+ useThisIStringStream is3("[]");
+ is3 >> set_open('[');
+ is3 >> set_close(']');
+ BOOST_CHECK(bool(is3 >> ti2));
+
+ // Make sure that whitespace between elements
+ // is skipped.
+ useThisIStringStream is4("(100 200 300)");
+
+ BOOST_CHECK(bool(is4 >> std::noskipws >> ti1));
+ BOOST_CHECK(ti1 == make_tuple(100, 200, 300));
+
+ // Note that strings are problematic:
+ // writing a tuple on a stream and reading it back doesn't work in
+ // general. If this is wanted, some kind of a parseable string class
+ // should be used.
+
+ return 0;
+}
+

Modified: sandbox/tuple-move/libs/tuple/test/tuple_move.cpp
==============================================================================
--- sandbox/tuple-move/libs/tuple/test/tuple_move.cpp (original)
+++ sandbox/tuple-move/libs/tuple/test/tuple_move.cpp 2013-02-22 19:50:17 EST (Fri, 22 Feb 2013)
@@ -7,10 +7,10 @@
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#define BOOST_INCLUDE_MAIN // for testing, include rather than link
+#include <boost/test/test_tools.hpp> // see "Header Implementation Option"
 
-#include <boost/test/included/test_exec_monitor.hpp>
-#include <boost/test/impl/execution_monitor.ipp>
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 
 #include <boost/tuple/tuple.hpp>
 

Added: sandbox/tuple-move/libs/tuple/test/tuple_test_bench.cpp
==============================================================================
--- (empty file)
+++ sandbox/tuple-move/libs/tuple/test/tuple_test_bench.cpp 2013-02-22 19:50:17 EST (Fri, 22 Feb 2013)
@@ -0,0 +1,497 @@
+// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi_at_[hidden])
+//
+// 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;
+}
+
+
+
+
+
+
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk