diff --git a/doc/design_decisions_rationale.html b/doc/design_decisions_rationale.html deleted file mode 100644 index ec05494..0000000 --- a/doc/design_decisions_rationale.html +++ /dev/null @@ -1,153 +0,0 @@ - - -Design decisions rationale for Boost Tuple Library - - - -C++ Boost - -

Tuple Library : design decisions rationale

- -

About namespaces

- -

-There was a discussion about whether tuples should be in a separate namespace or directly in the boost namespace. -The common principle is that domain libraries (like graph, python) should be on a separate -subnamespace, while utility like libraries directly in the boost namespace. -Tuples are somewhere in between, as the tuple template is clearly a general utility, but the library introduces quite a lot of names in addition to just the tuple template. -Tuples were originally under a subnamespace. -As a result of the discussion, tuple definitions were moved directly under the boost namespace. -As a result of a continued discussion, the subnamespace was reintroduced. -The final (I truly hope so) solution is now to have all definitions in namespace ::boost::tuples, and the most common names in the ::boost namespace as well. -This is accomplished with using declarations (suggested by Dave Abrahams): -

namespace boost {
-  namespace tuples {
-      ...      
-    // All library code
-      ...
-  }
-  using tuples::tuple; 
-  using tuples::make_tuple;
-  using tuples::tie;
-  using tuples::get;
-}
-
-With this arrangement, tuple creation with direct constructor calls, make_tuple or tie functions do not need the namespace qualifier. -Further, all functions that manipulate tuples are found with Koenig-lookup. -The only exceptions are the get<N> functions, which are always called with an explicitly qualified template argument, and thus Koenig-lookup does not apply. -Therefore, get is lifted to ::boost namespace with a using declaration. -Hence, the interface for an application programmer is in practice under the namespace ::boost. -

-

-The other names, forming an interface for library writers (cons lists, metafunctions manipulating cons lists, ...) remain in the subnamespace ::boost::tuples. -Note, that the names ignore, set_open, set_close and set_delimiter are considered to be part of the application programmer's interface, but are still not under boost namespace. -The reason being the danger for name clashes for these common names. -Further, the usage of these features is probably not very frequent. -

- -

For those who are really interested in namespaces

- -

-The subnamespace name tuples raised some discussion. -The rationale for not using the most natural name 'tuple' is to avoid having an identical name with the tuple template. -Namespace names are, however, not generally in plural form in boost libraries. -First, no real trouble was reported for using the same name for a namespace and a class and we considered changing the name 'tuples' to 'tuple'. -But we found some trouble after all. -Both gcc and edg compilers reject using declarations where the namespace and class names are identical: - -

namespace boost {
-  namespace tuple {
-    ... tie(...);
-    class tuple; 
-      ...
-  }
-  using tuple::tie; // ok
-  using tuple::tuple; // error
-    ...
-}
-
- -Note, however, that a corresponding using declaration in the global namespace seems to be ok: - -
-using boost::tuple::tuple; // ok;
-
- - -

The end mark of the cons list (nil, null_type, ...)

- -

-Tuples are internally represented as cons lists: - -

tuple<int, int>
-
-inherits from -
cons<int, cons<int, null_type> >
-
- -null_type is the end mark of the list. Original proposition was nil, but the name is used in MacOS, and might have caused problems, so null_type was chosen instead. -Other names considered were null_t and unit (the empty tuple type in SML). -

-Note that null_type is the internal representation of an empty tuple: tuple<> inherits from null_type. -

- -

Element indexing

- -

-Whether to use 0- or 1-based indexing was discussed more than thoroughly, and the following observations were made: - -

-Tuple access with the syntax get<N>(a), or a.get<N>() (where a is a tuple and N an index), was considered to be of the first category, hence, the index of the first element in a tuple is 0. - -

-A suggestion to provide 1-based 'name like' indexing with constants like _1st, _2nd, _3rd, ... was made. -By suitably chosen constant types, this would allow alternative syntaxes: - -

a.get<0>() == a.get(_1st) == a[_1st] == a(_1st);
-
- -We chose not to provide more than one indexing method for the following reasons: - - - -

Tuple comparison

- -The comparison operator implements lexicographical order. -Other orderings were considered, mainly dominance (a < b iff for each i a(i) < b(i)). -Our belief is, that lexicographical ordering, though not mathematically the most natural one, is the most frequently needed ordering in everyday programming. - -

Streaming

- -

-The characters specified with tuple stream manipulators are stored within the space allocated by ios_base::xalloc, which allocates storage for long type objects. -static_cast is used in casting between long and the stream's character type. -Streams that have character types not convertible back and forth to long thus fail to compile. - -This may be revisited at some point. The two possible solutions are: -

- -Back to the user's guide -

© Copyright Jaakko Järvi 2001. - - - diff --git a/doc/tuple_advanced_interface.html b/doc/tuple_advanced_interface.html deleted file mode 100644 index 4eb3ed8..0000000 --- a/doc/tuple_advanced_interface.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - Tuple library advanced features - - -C++ Boost - - - - -

Tuple library advanced features

- -The advanced features described in this document are all under namespace ::boost::tuples - -

Metafunctions for tuple types

-

-Suppose T is a tuple type, and N is a constant integral expression. - -

element<N, T>::type
- -gives the type of the Nth element in the tuple type T. If T is const, the resulting type is const qualified as well. -Note that the constness of T does not affect reference type -elements. -

- -
length<T>::value
- -gives the length of the tuple type T. -

- -

Cons lists

- -

-Tuples are internally represented as cons lists. -For example, the tuple - -

tuple<A, B, C, D>
- - inherits from the type -
cons<A, cons<B, cons<C, cons<D, null_type> > > >
-
- -The tuple template provides the typedef inherited to access the cons list representation. E.g.: -tuple<A>::inherited is the type cons<A, null_type>. -

- -

Empty tuple

-

-The internal representation of the empty tuple tuple<> is null_type. -

- -

Head and tail

-

-Both tuple template and the cons templates provide the typedefs head_type and tail_type. -The head_type typedef gives the type of the first element of the tuple (or the cons list). -The -tail_type typedef gives the remaining cons list after removing the first element. -The head element is stored in the member variable head and the tail list in the member variable tail. -Cons lists provide the member function get_head() for getting a reference to the head of a cons list, and get_tail() for getting a reference to the tail. -There are const and non-const versions of both functions. -

-

-Note that in a one element tuple, tail_type equals null_type and the get_tail() function returns an object of type null_type. -

-

-The empty tuple (null_type) has no head or tail, hence the get_head and get_tail functions are not provided. -

- -

-Treating tuples as cons lists gives a convenient means to define generic functions to manipulate tuples. For example, the following pair of function templates assign 0 to each element of a tuple (obviously, the assignments must be valid operations for the element types): - -

inline void set_to_zero(const null_type&) {};
-
-template <class H, class T>
-inline void set_to_zero(cons<H, T>& x) { x.get_head() = 0; set_to_zero(x.get_tail()); }
-
-

- -

Constructing cons lists

- -

-A cons list can be default constructed provided that all its elements can be default constructed. -

-

-A cons list can be constructed from its head and tail. The prototype of the constructor is: -

cons(typename access_traits<head_type>::parameter_type h,
-     const tail_type& t)
-
-The traits template for the head parameter selects correct parameter types for different kinds of element types (for reference elements the parameter type equals the element type, for non-reference types the parameter type is a reference to const non-volatile element type). -

-

-For a one-element cons list the tail argument (null_type) can be omitted. -

- - -

Traits classes for tuple element types

- -

access_traits

-

-The template access_traits defines three type functions. Let T be a type of an element in a tuple: -

    -
  1. access_traits<T>::type maps T to the return type of the non-const access functions (nonmeber and member get functions, and the get_head function).
  2. -
  3. access_traits<T>::const_type maps T to the return type of the const access functions.
  4. -
  5. access_traits<T>::parameter_type maps T to the parameter type of the tuple constructor.
  6. -
-

make_tuple_traits

- -The element types of the tuples that are created with the make_tuple functions are computed with the type function make_tuple_traits. -The type function call make_tuple_traits<T>::type implements the following type mapping: - - -Objects of type reference_wrapper are created with the ref and cref functions (see The make_tuple function.) -

- -

Reference wrappers were originally part of the tuple library, but they are now a general utility of boost. -The reference_wrapper template and the ref and cref functions are defined in a separate file ref.hpp in the main boost include directory; and directly in the boost namespace. -

- -Back to the user's guide -
- -

© Copyright Jaakko Järvi 2001.

- - diff --git a/doc/tuple_users_guide.html b/doc/tuple_users_guide.html deleted file mode 100644 index e794a8e..0000000 --- a/doc/tuple_users_guide.html +++ /dev/null @@ -1,529 +0,0 @@ - - -The Boost Tuple Library - - - -C++ Boost - -

The Boost Tuple Library

- -

-A tuple (or n-tuple) is a fixed size collection of elements. -Pairs, triples, quadruples etc. are tuples. -In a programming language, a tuple is a data object containing other objects as elements. -These element objects may be of different types. -

- -

Tuples are convenient in many circumstances. -For instance, tuples make it easy to define functions that return more than one value. -

- -

-Some programming languages, such as ML, Python and Haskell, have built-in tuple constructs. -Unfortunately C++ does not. -To compensate for this "deficiency", the Boost Tuple Library implements a tuple construct using templates. -

- -

Table of Contents

- -
    -
  1. Using the library
  2. -
  3. Tuple types
  4. -
  5. Constructing tuples
  6. -
  7. Accessing tuple elements
  8. -
  9. Copy construction and tuple assignment
  10. -
  11. Relational operators
  12. -
  13. Tiers
  14. -
  15. Streaming
  16. -
  17. Performance
  18. -
  19. Portability
  20. -
  21. Acknowledgements
  22. -
  23. References
  24. -
- -

More details

- -

-Advanced features (describes some metafunctions etc.).

-

-Rationale behind some design/implementation decisions.

- - -

Using the library

- -

To use the library, just include: - -

#include "boost/tuple/tuple.hpp"
- -

Comparison operators can be included with: -

#include "boost/tuple/tuple_comparison.hpp"
- -

To use tuple input and output operators, - -

#include "boost/tuple/tuple_io.hpp"
- -Both tuple_io.hpp and tuple_comparison.hpp include tuple.hpp. - -

All definitions are in namespace ::boost::tuples, but the most common names are lifted to namespace ::boost with using declarations. These names are: tuple, make_tuple, tie and get. Further, ref and cref are defined directly under the ::boost namespace. - -

Tuple types

- -

A tuple type is an instantiation of the tuple template. -The template parameters specify the types of the tuple elements. -The current version supports tuples with 0-10 elements. -If necessary, the upper limit can be increased up to, say, a few dozen elements. -The data element can be any C++ type. -Note that void and plain function types are valid -C++ types, but objects of such types cannot exist. -Hence, if a tuple type contains such types as elements, the tuple type -can exist, but not an object of that type. -There are natural limitations for element types that cannot -be be copied, or that are not default constructible (see 'Constructing tuples' - below). - -

-For example, the following definitions are valid tuple instantiations (A, B and C are some user defined classes): - -

tuple<int>
-tuple<double&, const double&, const double, double*, const double*>
-tuple<A, int(*)(char, int), B(A::*)(C&), C>
-tuple<std::string, std::pair<A, B> >
-tuple<A*, tuple<const A*, const B&, C>, bool, void*>
-
- -

Constructing tuples

- -

-The tuple constructor takes the tuple elements as arguments. -For an n-element tuple, the constructor can be invoked with k arguments, where 0 <= k <= n. -For example: -

tuple<int, double>() 
-tuple<int, double>(1) 
-tuple<int, double>(1, 3.14)
-
- -

-If no initial value for an element is provided, it is default initialized (and hence must be default initializable). -For example. - -

class X {
-  X(); 
-public:
-  X(std::string);
-};
-
-tuple<X,X,X>()                                              // error: no default constructor for X
-tuple<X,X,X>(string("Jaba"), string("Daba"), string("Duu")) // ok
-
- -In particular, reference types do not have a default initialization: - -
tuple<double&>()                // error: reference must be 
-                                // initialized explicitly
-
-double d = 5; 
-tuple<double&>(d)               // ok
-
-tuple<double&>(d+3.14)          // error: cannot initialize 
-                                // non-const reference with a temporary
-
-tuple<const double&>(d+3.14)    // ok, but dangerous: 
-                                // the element becomes a dangling reference 
-
- -

Using an initial value for an element that cannot be copied, is a compile -time error: - -

class Y { 
-  Y(const Y&); 
-public:
-  Y();
-};
-
-char a[10];
-
-tuple<char[10], Y>(a, Y()); // error, neither arrays nor Y can be copied
-tuple<char[10], Y>();       // ok
-
- -Note particularly that the following is perfectly ok: -
Y y;
-tuple<char(&)[10], Y&>(a, y); 
-
- -It is possible to come up with a tuple type that cannot be constructed. -This occurs if an element that cannot be initialized has a lower -index than an element that requires initialization. -For example: tuple<char[10], int&>. - -

In sum, the tuple construction is semantically just a group of individual elementary constructions. -

- -

The make_tuple function

- -

-Tuples can also be constructed using the make_tuple (cf. std::make_pair) helper functions. -This makes the construction more convenient, saving the programmer from explicitly specifying the element types: -

tuple<int, int, double> add_multiply_divide(int a, int b) {
-  return make_tuple(a+b, a*b, double(a)/double(b));
-}
-
- -

-By default, the element types are deduced to the plain non-reference types. E.g: -

void foo(const A& a, B& b) { 
-  ...
-  make_tuple(a, b);
-
-The make_tuple invocation results in a tuple of type tuple<A, B>. - -

-Sometimes the plain non-reference type is not desired, e.g. if the element type cannot be copied. -Therefore, the programmer can control the type deduction and state that a reference to const or reference to -non-const type should be used as the element type instead. -This is accomplished with two helper template functions: ref and cref. -Any argument can be wrapped with these functions to get the desired type. -The mechanism does not compromise const correctness since a const object wrapped with ref results in a tuple element with const reference type (see the fifth code line below). -For example: - -

A a; B b; const A ca = a;
-make_tuple(cref(a), b);      // creates tuple<const A&, B>
-make_tuple(ref(a), b);       // creates tuple<A&, B>
-make_tuple(ref(a), cref(b)); // creates tuple<A&, const B&>
-make_tuple(cref(ca));        // creates tuple<const A&>
-make_tuple(ref(ca));         // creates tuple<const A&>
-
- - -

-Array arguments to make_tuple functions are deduced to reference to const types by default; there is no need to wrap them with cref. For example: -

make_tuple("Donald", "Daisy");
-
- -This creates an object of type tuple<const char (&)[7], const char (&)[6]> -(note that the type of a string literal is an array of const characters, not const char*). -However, to get make_tuple to create a tuple with an element of a -non-const array type one must use the ref wrapper. - -

-Function pointers are deduced to the plain non-reference type, that is, to plain function pointer. -A tuple can also hold a reference to a function, -but such a tuple cannot be constructed with make_tuple (a const qualified function type would result, which is illegal): -

void f(int i);
-  ...
-make_tuple(&f); // tuple<void (*)(int)>
-  ...
-tuple<tuple<void (&)(int)> > a(f) // ok
-make_tuple(f);                    // not ok
-
- -

Accessing tuple elements

- -

-Tuple elements are accessed with the expression: - -

t.get<N>()
-
-or -
get<N>(t)
-
-where t is a tuple object and N is a constant integral expression specifying the index of the element to be accessed. -Depending on whether t is const or not, get returns the Nth element as a reference to const or -non-const type. -The index of the first element is 0 and thus -N must be between 0 and k-1, where k is the number of elements in the tuple. -Violations of these constrains are detected at compile time. Examples: - -
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); i = t.get<0>();        // ok
-int j = get<0>(ct);                       // ok
-get<0>(t) = 5;                            // ok 
-get<0>(ct) = 5;                           // error, can't assign to const 
-  ...
-double e = get<1>(t); // ok   
-get<1>(t) = 3.14;     // ok 
-get<2>(t) = A();      // error, can't assign to const 
-A aa = get<3>(t);     // error: index out of bounds 
-  ...
-++get<0>(t);  // ok, can be used as any variable
-
- -Note! The member get functions are not supported with MS Visual C++ compiler. -Further, the compiler has trouble with finding the non-member get functions without an explicit namespace qualifier. -Hence, all get calls should be qualified as: tuples::get<N>(a_tuple) when writing code that shoud compile with MSVC++ 6.0. - -

Copy construction and tuple assignment

- -

-A tuple can be copy constructed from another tuple, provided that the element types are element-wise copy constructible. -Analogously, a tuple can be assigned to another tuple, provided that the element types are element-wise assignable. -For example: - -

class A {};
-class B : public A {};
-struct C { C(); C(const B&); };
-struct D { operator C() const; };
-tuple<char, B*, B, D> t;
-  ...
-tuple<int, A*, C, C> a(t); // ok 
-a = t;                     // ok 
-
- -In both cases, the conversions performed are: char -> int, B* -> A* (derived class pointer to base class pointer), B -> C (a user defined conversion) and D -> C (a user defined conversion). - -

-Note that assignment is also defined from std::pair types: - -

tuple<float, int> a = std::make_pair(1, 'a');
-
- -

Relational operators

-

-Tuples reduce the operators ==, !=, <, >, <= and >= to the corresponding elementary operators. -This means, that if any of these operators is defined between all elements of two tuples, then the same operator is defined between the tuples as well. - -The equality operators for two tuples a and b are defined as: -

- -The operators <, >, <= and >= implement a lexicographical ordering. - -

-Note that an attempt to compare two tuples of different lengths results in a compile time error.

-Also, the comparison operators are "short-circuited": elementary comparisons start from the first elements and are performed only until the result is clear. - -

Examples: - -

tuple<std::string, int, A> t1(std::string("same?"), 2, A());
-tuple<std::string, long, A> t2(std::string("same?"), 2, A());
-tuple<std::string, long, A> t3(std::string("different"), 3, A());
-
-bool operator==(A, A) { std::cout << "All the same to me..."; return true; }
-
-t1 == t2; 		// true
-t1 == t3;               // false, does not print "All the..."
-
- - -

Tiers

- -

-Tiers are tuples, where all elements are of non-const reference types. -They are constructed with a call to the tie function template (cf. make_tuple): - -

int i; char c; double d; 
-  ...
-tie(i, c, a);
-
- -

-The above tie function creates a tuple of type tuple<int&, char&, double&>. -The same result could be achieved with the call make_tuple(ref(i), ref(c), ref(a)). -

- -

-A tuple that contains non-const references as elements can be used to 'unpack' another tuple into variables. E.g.: - -

int i; char c; double d; 
-tie(i, c, d) = make_tuple(1,'a', 5.5);
-std::cout << i << " " <<  c << " " << d;
-
-This code prints 1 a 5.5 to the standard output stream. - -A tuple unpacking operation like this is found for example in ML and Python. -It is convenient when calling functions which return tuples. - -

-The tying mechanism works with std::pair templates as well: - -

int i; char c;
-tie(i, c) = std::make_pair(1, 'a');
-
-

Ignore

-There is also an object called ignore which allows you to ignore an element assigned by a tuple. -The idea is that a function may return a tuple, only part of which you are interested in. For example (note, that ignore is under the tuples subnamespace): - -
char c;
-tie(tuples::ignore, c) = std::make_pair(1, 'a');
-
- -

Streaming

- -

-The global operator<< has been overloaded for std::ostream such that tuples are -output by recursively calling operator<< for each element. -

- -

-Analogously, the global operator>> has been overloaded to extract tuples from std::istream by recursively calling operator>> for each element. -

- -

-The default delimiter between the elements is space, and the tuple is enclosed -in parenthesis. -For Example: - -

tuple<float, int, std::string> a(1.0f,  2, std::string("Howdy folks!");
-
-cout << a; 
-
-outputs the tuple as: (1.0 2 Howdy folks!) - -

-The library defines three manipulators for changing the default behavior: -

- -Note, that these manipulators are defined in the tuples subnamespace. -For example: -
cout << tuples::set_open('[') << tuples::set_close(']') << tuples::set_delimiter(',') << a; 
-
-outputs the same tuple a as: [1.0,2,Howdy folks!] - -

The same manipulators work with operator>> and istream as well. Suppose the cin stream contains the following data: - -

(1 2 3) [4:5]
- -The code: - -
tuple<int, int, int> i;
-tuple<int, int> j;
-
-cin >> i;
-cin >> tuples::set_open('[') >> tuples::set_close(']') >> tules::set_delimiter(':');
-cin >> j;
-
- -reads the data into the tuples i and j. - -

-Note that extracting tuples with std::string or C-style string -elements does not generally work, since the streamed tuple representation may not be unambiguously -parseable. -

- -

Performance

- -All tuple access and construction functions are small inlined one-liners. -Therefore, a decent compiler can eliminate any extra cost of using tuples compared to using hand written tuple like classes. -Particularly, with a decent compiler there is no performance difference between this code: - -
class hand_made_tuple { 
-  A a; B b; C c;
-public:
-  hand_made_tuple(const A& aa, const B& bb, const C& cc) 
-    : a(aa), b(bb), c(cc) {};
-  A& getA() { return a; };
-  B& getB() { return b; };
-  C& getC() { return c; };
-};
-
-hand_made_tuple hmt(A(), B(), C()); 
-hmt.getA(); hmt.getB(); hmt.getC();
-
- -and this code: - -
tuple<A, B, C> t(A(), B(), C());
-t.get<0>(); t.get<1>(); t.get<2>(); 
-
- -

Note, that there are widely used compilers (e.g. bcc 5.5.1) which fail to optimize this kind of tuple usage. -

-

-Depending on the optimizing ability of the compiler, the tier mechanism may have a small performance penalty compared to using -non-const reference parameters as a mechanism for returning multiple values from a function. -For example, suppose that the following functions f1 and f2 have equivalent functionalities: - -

void f1(int&, double&);
-tuple<int, double> f2();
-
- -Then, the call #1 may be slightly faster than #2 in the code below: - -
int i; double d;
-  ...
-f1(i,d);         // #1
-tie(i,d) = f2(); // #2
-
-See -[1, -2] - for more in-depth discussions about efficiency. - -

Effect on Compile Time

- -

-Compiling tuples can be slow due to the excessive amount of template instantiations. -Depending on the compiler and the tuple length, it may be more than 10 times slower to compile a tuple construct, compared to compiling an equivalent explicitly written class, such as the hand_made_tuple class above. -However, as a realistic program is likely to contain a lot of code in addition to tuple definitions, the difference is probably unnoticeable. -Compile time increases between 5 to 10 percentages were measured for programs which used tuples very frequently. -With the same test programs, memory consumption of compiling increased between 22% to 27%. See -[1, -2] -for details. -

- -

Portability

- -

The library code is(?) standard C++ and thus the library works with a standard conforming compiler. -Below is a list of compilers and known problems with each compiler: -

- - - - - - - -
CompilerProblems
gcc 2.95-
edg 2.44-
Borland 5.5Can't use function pointers or member pointers as tuple elements
Metrowerks 6.2Can't use ref and cref wrappers
MS Visual C++No reference elements (tie still works). Can't use ref and cref wrappers
- -

Acknowledgements

-Gary Powell has been an indispensable helping hand. In particular, stream manipulators for tuples were his idea. Doug Gregor came up with a working version for MSVC, David Abrahams found a way to get rid of most of the restrictions for compilers not supporting partial specialization. Thanks to Jeremy Siek, William Kempf and Jens Maurer for their help and suggestions. -The comments by Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes, David Abrahams and Hartmut Kaiser helped to improve the -library. -The idea for the tie mechanism came from an old usenet article by Ian McCulloch, where he proposed something similar for std::pairs. -

References

- -

-[1] -Järvi J.: Tuples and multiple return values in C++, TUCS Technical Report No 249, 1999. -

- -

-[2] -Järvi J.: ML-Style Tuple Assignment in Standard C++ - Extending the Multiple Return Value Formalism, TUCS Technical Report No 267, 1999. -

- -

-[3] Järvi J.:Tuple Types and Multiple Return Values, C/C++ Users Journal, August 2001. -

- -
- -

Last modified 2003-09-07

- -

© Copyright Jaakko Järvi 2001. - -Permission to copy, use, modify, sell and distribute this software and its documentation is granted provided this copyright notice appears in all copies. -This software and its documentation is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. -

- - - - - - diff --git a/index.html b/index.html deleted file mode 100644 index 3b6f47e..0000000 --- a/index.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - -Automatic redirection failed, please go to doc/tuple_users_guide.html - - \ No newline at end of file diff --git a/test/Jamfile b/test/Jamfile deleted file mode 100644 index 16d0431..0000000 --- a/test/Jamfile +++ /dev/null @@ -1,20 +0,0 @@ -subproject libs/tuple/test ; - -unit-test tuple_test_bench - : tuple_test_bench.cpp - ../../test/build/boost_test_exec_monitor - : $(BOOST_ROOT) - ; - -unit-test io_test - : io_test.cpp - ../../test/build/boost_test_exec_monitor - : $(BOOST_ROOT) - ; - -unit-test another_tuple_test_bench - : another_tuple_test_bench.cpp - ../../test/build/boost_test_exec_monitor - : $(BOOST_ROOT) - ; - diff --git a/test/README b/test/README deleted file mode 100644 index 6047c49..0000000 --- a/test/README +++ /dev/null @@ -1,16 +0,0 @@ -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 - -The following is not true anymore: - - If you want to use tuple_io, you need to compile and link src/tuple.cpp: - g++ -I../../.. ../src/tuple.cpp io_test.cpp - -Thanks to Hartmut Kaiser's suggestion, the tuple.cpp is not needed anymore. diff --git a/test/another_tuple_test_bench.cpp b/test/another_tuple_test_bench.cpp deleted file mode 100644 index 34080d4..0000000 --- a/test/another_tuple_test_bench.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 1999, 2000 Jaakko Järvi (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 - - -// 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 // see "Header Implementation Option" - -#include "boost/tuple/tuple.hpp" - -#include -#include - -using namespace std; -using namespace boost; -using namespace boost::tuples; - - -template 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 v1; // should faild -#endif - - -#ifdef E2 -char cs[10]; -tuple 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()); - // should fail - -#endif -} - -void foo2() { -// testing default values -#ifdef E4 - dummy(tuple()); // should fail, not defaults for references - dummy(tuple()); // likewise -#endif - -#ifdef E5 - double dd = 5; - dummy(tuple(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 t(1, d, a); - const tuple 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 t; - (void)t; - tuple aaa; - tuple bbb(aaa); - (void)bbb; - // tuple a = t; - // a = t; - } - - -// testing tie -// testing assignment from std::pair -void foo7() { - - tuple 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; -} diff --git a/test/io_test.cpp b/test/io_test.cpp deleted file mode 100644 index d376534..0000000 --- a/test/io_test.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (C) 1999, 2000 Jaakko Järvi (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 - -// -- 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 -#include -#include -#include - -#if defined BOOST_NO_STRINGSTREAM -#include -#else -#include -#endif - -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[] ) { - (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]") ); - - 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 j; - -#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - tmp3 >> j; - BOOST_CHECK (tmp3.good() ); -#endif - - tmp3 >> set_delimiter(':'); - tuple i; - tmp3 >> i; - BOOST_CHECK (tmp3.good() ); - - tmp3.close(); - - - // reading tuple in format (a b c); - useThisIStringStream is("(100 200 300)"); - - tuple ti; - BOOST_CHECK(bool(is >> ti)); - BOOST_CHECK(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; -} - diff --git a/test/tuple_test_bench.cpp b/test/tuple_test_bench.cpp deleted file mode 100644 index 65e7695..0000000 --- a/test/tuple_test_bench.cpp +++ /dev/null @@ -1,477 +0,0 @@ -// Copyright (C) 1999, 2000 Jaakko Järvi (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 // 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 -#include - -using namespace std; -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 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 t1; - -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 - -// ----------------------------------------------------------------------- -// -tuple construction tests --------------------------------------------- -// ----------------------------------------------------------------------- - - -no_copy y; -tuple x = tuple(y); // ok - -char cs[10]; -tuple 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 t1; - BOOST_CHECK(get<0>(t1) == int()); - - tuple t2(5.5f); - BOOST_CHECK(get<0>(t2) > 5.4f && get<0>(t2) < 5.6f); - - tuple t3(foo(12)); - BOOST_CHECK(get<0>(t3) == foo(12)); - - tuple t4(t2); - BOOST_CHECK(get<0>(t4) > 5.4 && get<0>(t4) < 5.6); - - tuple t5; - BOOST_CHECK(get<0>(t5) == int()); - BOOST_CHECK(get<1>(t5) == float()); - - tuple t6(12, 5.5f); - BOOST_CHECK(get<0>(t6) == 12); - BOOST_CHECK(get<1>(t6) > 5.4f && get<1>(t6) < 5.6f); - - tuple t7(t6); - BOOST_CHECK(get<0>(t7) == 12); - BOOST_CHECK(get<1>(t7) > 5.4f && get<1>(t7) < 5.6f); - - tuple t8(t6); - BOOST_CHECK(get<0>(t8) == 12); - BOOST_CHECK(get<1>(t8) > 5.4f && get<1>(t8) < 5.6f); - - dummy( - tuple( - std::string("Jaba"), // ok, since the default - std::string("Daba"), // constructor is not used - std::string("Doo") - ) - ); - -// testing default values - dummy(tuple()); - dummy(tuple(1)); - dummy(tuple(1,3.14)); - - - // dummy(tuple()); // should fail, not defaults for references - // dummy(tuple()); // likewise - - double dd = 5; - dummy(tuple(dd)); // ok - - dummy(tuple(dd+3.14)); // ok, but dangerous - - // dummy(tuple(dd+3.14)); // should fail, - // // temporary to non-const reference -} - - -// ---------------------------------------------------------------------------- -// - testing element access --------------------------------------------------- -// ---------------------------------------------------------------------------- - -void element_access_test() -{ - double d = 2.7; - A a; - tuple t(1, d, a, 2); - const tuple 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 >::type>::value != true)); -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - BOOST_STATIC_ASSERT((boost::is_const >::type>::value)); -#endif - - BOOST_STATIC_ASSERT((boost::is_const >::type>::value != true)); -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - BOOST_STATIC_ASSERT((boost::is_const >::type>::value)); -#endif - - - dummy(i); dummy(i2); dummy(j); dummy(e); // avoid warns for unused variables -} - - -// ---------------------------------------------------------------------------- -// - copying tuples ----------------------------------------------------------- -// ---------------------------------------------------------------------------- - - - -void -copy_test() -{ - tuple t1(4, 'a'); - tuple t2(5, 'b'); - t2 = t1; - BOOST_CHECK(get<0>(t1) == get<0>(t2)); - BOOST_CHECK(get<1>(t1) == get<1>(t2)); - - tuple 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 t; - tuple 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 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 t1 = make_tuple(5, 'a'); - BOOST_CHECK(get<0>(t1) == 5); - BOOST_CHECK(get<1>(t1) == 'a'); - - tuple 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 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(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 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 t1(5, 'a'); - tuple t2(5, 'a'); - BOOST_CHECK(t1 == t2); - - tuple t3(5, 'b'); - tuple t4(2, 'a'); - BOOST_CHECK(t1 != t3); - BOOST_CHECK(t1 != t4); - BOOST_CHECK(!(t1 != t2)); -} - - -// ---------------------------------------------------------------------------- -// - testing tuple comparisons ----------------------------------------------- -// ---------------------------------------------------------------------------- - -void -ordering_test() -{ - tuple t1(4, 3.3f); - tuple t2(5, 3.3f); - tuple 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 a(1, null_type()); - cons > b(2,a); - int i = 3; - cons > > c(i, b); - BOOST_CHECK(make_tuple(3,2,1)==c); - - cons > > x; - dummy(x); -} - -// ---------------------------------------------------------------------------- -// - testing const tuples ----------------------------------------------------- -// ---------------------------------------------------------------------------- -void const_tuple_test() -{ - const tuple 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 t1; - using tuples::cons; - typedef cons > > t1_cons; - typedef tuple<> t2; - typedef tuples::null_type t3; - - BOOST_STATIC_ASSERT(tuples::length::value == 3); - BOOST_STATIC_ASSERT(tuples::length::value == 3); - BOOST_STATIC_ASSERT(tuples::length::value == 0); - BOOST_STATIC_ASSERT(tuples::length::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; -} - - - - - - -