Adding the tuple library files

[SVN r10829]
This commit is contained in:
Jaakko Järvi
2001-08-10 11:48:57 +00:00
parent adeeed1f6d
commit c80a1d86d8
8 changed files with 1369 additions and 0 deletions

14
test/README Normal file
View File

@ -0,0 +1,14 @@
To compile the
libs/tuple/test/*.cpp
files, you need to set include paths
for boost.
For example, in libs/tuple/test directory you would type (using g++):
g++ -I../../.. tuple_test_bench.cpp
If you want to use tuple_io, you need to compile and link src/tuple.cpp:
g++ -I../../.. ../src/tuple.cpp io_test.cpp

View File

@ -0,0 +1,163 @@
// 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 <boost/test/test_tools.hpp> // see "Header Implementation Option"
#include "boost/tuple/tuple.hpp"
#include "boost/tuple/tuple_comparison.hpp"
using namespace std;
using namespace boost;
class foo
{
public:
explicit foo(int v) : val(v) {}
bool operator==(const foo& other) const
{
return val == other.val;
}
private:
foo() {}
int val;
};
void
construction_test()
{
tuple<int> t1;
BOOST_TEST(get<0>(t1) == int());
tuple<float> t2(5.5f);
BOOST_TEST(get<0>(t2) == 5.5f);
tuple<foo> t3(foo(12));
BOOST_TEST(get<0>(t3) == foo(12));
tuple<double> t4(t2);
BOOST_TEST(get<0>(t4) == 5.5);
tuple<int, float> t5;
BOOST_TEST(get<0>(t5) == int());
BOOST_TEST(get<1>(t5) == float());
tuple<int, float> t6(12, 5.5f);
BOOST_TEST(get<0>(t6) == 12);
BOOST_TEST(get<1>(t6) == 5.5f);
tuple<long, double> t7(t6);
BOOST_TEST(get<0>(t7) == 12);
BOOST_TEST(get<1>(t7) == 5.5f);
}
void
copy_test()
{
tuple<int, float> t1(4, 12.5f);
tuple<int, float> t2(5, 2.2f);
t2 = t1;
BOOST_TEST(get<0>(t1) == get<0>(t2));
BOOST_TEST(get<1>(t1) == get<1>(t2));
tuple<long, double> t3(2, 3.3);
t3 = t1;
BOOST_TEST((double)get<0>(t1) == get<0>(t3));
BOOST_TEST((double)get<1>(t1) == get<1>(t3));
}
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_TEST(get<0>(t1) == 6);
BOOST_TEST(get<1>(t1) == 2.2f);
BOOST_TEST(get<2>(t1) == false);
BOOST_TEST(get<3>(t1) == foo(5));
}
void
make_tuple_test()
{
tuple<int, float> t1 = make_tuple(5, 2.25f);
BOOST_TEST(get<0>(t1) == 5);
BOOST_TEST(get<1>(t1) == 2.25f);
tuple<int, double> t2;
t2 = make_tuple((short int)2, 2.25);
BOOST_TEST(get<0>(t2) == 2);
BOOST_TEST(get<1>(t2) == 2.25);
}
void
tie_test()
{
int a;
float b;
foo c(5);
tie(a, b, c) = make_tuple(2, 5.5f, foo(3));
BOOST_TEST(a == 2);
BOOST_TEST(b == 5.5f);
BOOST_TEST(c == foo(3));
tie(a, ignore, c) = make_tuple((short int)5, false, foo(5));
BOOST_TEST(a == 5);
BOOST_TEST(b == 5.5f);
BOOST_TEST(c == foo(5));
}
void
equality_test()
{
tuple<int, float> t1(5, 3.3f);
tuple<int, float> t2(5, 3.3f);
BOOST_TEST(t1 == t2);
tuple<int, float> t3(5, 2.2f);
tuple<int, float> t4(2, 3.3f);
BOOST_TEST(t1 != t3);
BOOST_TEST(t1 != t4);
}
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_TEST(t1 < t2);
BOOST_TEST(t1 <= t2);
BOOST_TEST(t2 > t1);
BOOST_TEST(t2 >= t1);
BOOST_TEST(t2 < t3);
BOOST_TEST(t2 <= t3);
BOOST_TEST(t3 > t2);
BOOST_TEST(t3 >= t2);
}
int
test_main(int, char *[])
{
construction_test();
copy_test();
mutate_test();
make_tuple_test();
tie_test();
equality_test();
ordering_test();
return 0;
}

104
test/io_test.cpp Normal file
View File

@ -0,0 +1,104 @@
// -- 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>
#if defined BOOST_NO_STRINGSTREAM
#include <strstream>
#else
#include <sstream>
#endif
#include "boost/config.hpp"
using namespace std;
using namespace boost;
#if defined BOOST_NO_STRINGSTREAM
typedef ostrstream useThisOStringStream;
typedef istrstream useThisIStringStream;
#else
typedef ostringstream useThisOStringStream;
typedef istringstream useThisIStringStream;
#endif
int test_main(int argc, char * argv[] ) {
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_TEST (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_TEST (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_TEST (os1.str() == std::string("[1,2,3][1,2,3]") );
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) << endl;
tmp.close();
// When teading tuples from a stream, manipulators must be set correctly:
ifstream tmp3("temp.tmp");
tuple<string, string, int> j;
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
tmp3 >> j;
BOOST_TEST (tmp3.good() );
#endif
tmp3 >> set_delimiter(':');
tuple<int, int, int> i;
tmp3 >> i;
BOOST_TEST (tmp3.good() );
tmp3.close();
// reading tuple<int, int, int> in format (a b c);
useThisIStringStream is("(100 200 300)");
tuple<int, int, int> ti;
BOOST_TEST(is >> ti);
BOOST_TEST(ti == 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;
}

279
test/tuple_test_bench.cpp Normal file
View File

@ -0,0 +1,279 @@
// 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 <boost/test/test_tools.hpp> // see "Header Implementation Option"
#include "boost/tuple/tuple.hpp"
#include "boost/tuple/tuple_comparison.hpp"
#include <string>
#include <utility>
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
using namespace std;
using namespace boost;
template<class T> void dummy(const T& t) {}
class A {}; class B {}; class C {};
typedef int(t)(float);
// some arbitrary tuple definitions
typedef tuple<int> t1;
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
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
#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<no_copy&> x = tuple<no_copy&>(y); // ok
#endif
#ifdef E1
tuple<no_copy> v1; // should faild
#endif
char cs[10];
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
tuple<char(&)[10]> v2(cs); // ok
#endif
#ifdef E2
tuple<char[10]> 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<no_def_constructor, no_def_constructor, no_def_constructor>());
// should fail
#endif
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")));
}
void foo2() {
// testing default values
dummy(tuple<int, double>());
dummy(tuple<int, double>(1));
dummy(tuple<int, double>(1,3.14));
#ifdef E4
dummy(tuple<double&>()); // should fail, not defaults for references
dummy(tuple<const double&>()); // likewise
#endif
double dd = 5;
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
dummy(tuple<double&>(dd)); // ok
#endif
#ifdef E5
dummy(tuple<double&>(dd+3.14)); // should fail, temporary to non-const reference
#endif
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
dummy(tuple<const double&>(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<void(&)()> 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<foo3type>(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<int, double&, const A&> t(1, d, a);
const tuple<int, double&, const A> 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<char, BB*, BB, DD> t;
tuple<int, AA*, CC, CC> 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<int, int, float> 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;
}