Blame libs/tuple/doc/tuple_users_guide.qbk

Packit 58578d
[/
Packit 58578d
 /  Copyright (c) 2001 Jaakko Järvi
Packit 58578d
 /
Packit 58578d
 / Distributed under the Boost Software License, Version 1.0. (See
Packit 58578d
 / accompanying file LICENSE_1_0.txt or copy at
Packit 58578d
 / http://www.boost.org/LICENSE_1_0.txt)
Packit 58578d
 /]
Packit 58578d
Packit 58578d
[library Boost.Tuple
Packit 58578d
  [quickbook 1.6]
Packit 58578d
  [id tuple]
Packit 58578d
  [copyright 2001 Jaakko J\u00E4rvi]
Packit 58578d
  [dirname tuple]
Packit 58578d
  [license Distributed under the
Packit 58578d
    [@http://boost.org/LICENSE_1_0.txt Boost Software License,
Packit 58578d
      Version 1.0].
Packit 58578d
  ]
Packit 58578d
]
Packit 58578d
Packit 58578d
[include tuple_advanced_interface.qbk]
Packit 58578d
[include design_decisions_rationale.qbk]
Packit 58578d
Packit 58578d
[template simplesect[title]
Packit 58578d
[block '''<simplesect><title>'''[title]'''</title>''']]
Packit 58578d
Packit 58578d
[template endsimplesect[]
Packit 58578d
[block '''</simplesect>''']]
Packit 58578d
Packit 58578d
A tuple (or n-tuple) is a fixed size collection of elements. Pairs, triples,
Packit 58578d
quadruples etc. are tuples. In a programming language, a tuple is a data
Packit 58578d
object containing other objects as elements. These element objects may be of
Packit 58578d
different types.
Packit 58578d
Packit 58578d
Tuples are convenient in many circumstances. For instance, tuples make it easy
Packit 58578d
to define functions that return more than one value.
Packit 58578d
Packit 58578d
Some programming languages, such as ML, Python and Haskell, have built-in
Packit 58578d
tuple constructs. Unfortunately C++ does not. To compensate for this
Packit 58578d
"deficiency", the Boost Tuple Library implements a tuple construct using
Packit 58578d
templates.
Packit 58578d
Packit 58578d
[section:using_library Using the Library]
Packit 58578d
Packit 58578d
To use the library, just include:
Packit 58578d
Packit 58578d
    #include "boost/tuple/tuple.hpp"
Packit 58578d
Packit 58578d
Comparison operators can be included with:
Packit 58578d
Packit 58578d
    #include "boost/tuple/tuple_comparison.hpp"
Packit 58578d
Packit 58578d
To use tuple input and output operators,
Packit 58578d
Packit 58578d
    #include "boost/tuple/tuple_io.hpp"
Packit 58578d
Packit 58578d
Both `tuple_io.hpp` and `tuple_comparison.hpp` include `tuple.hpp`.
Packit 58578d
Packit 58578d
All definitions are in namespace `::boost::tuples`, but the most common names
Packit 58578d
are lifted to namespace `::boost` with using declarations. These names are:
Packit 58578d
`tuple`, `make_tuple`, `tie` and `get`. Further, `ref` and `cref` are defined
Packit 58578d
directly under the `::boost` namespace.
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:tuple_types Tuple Types]
Packit 58578d
Packit 58578d
A tuple type is an instantiation of the `tuple` template. The template
Packit 58578d
parameters specify the types of the tuple elements. The current version
Packit 58578d
supports tuples with 0-10 elements. If necessary, the upper limit can be
Packit 58578d
increased up to, say, a few dozen elements. The data element can be any C++
Packit 58578d
type. Note that `void` and plain function types are valid C++ types, but
Packit 58578d
objects of such types cannot exist. Hence, if a tuple type contains such types
Packit 58578d
as elements, the tuple type can exist, but not an object of that type. There
Packit 58578d
are natural limitations for element types that cannot be copied, or that are
Packit 58578d
not default constructible (see [link tuple.constructing_tuples 'Constructing tuples']
Packit 58578d
below).
Packit 58578d
Packit 58578d
For example, the following definitions are valid tuple instantiations (`A`,
Packit 58578d
`B` and `C` are some user defined classes):
Packit 58578d
Packit 58578d
    tuple<int>
Packit 58578d
    tuple<double&, const double&, const double, double*, const double*>
Packit 58578d
    tuple<A, int(*)(char, int), B(A::*)(C&), C>
Packit 58578d
    tuple<std::string, std::pair<A, B> >
Packit 58578d
    tuple<A*, tuple<const A*, const B&, C>, bool, void*>
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:constructing_tuples Constructing Tuples]
Packit 58578d
Packit 58578d
The tuple constructor takes the tuple elements as arguments. For an /n/-
Packit 58578d
element tuple, the constructor can be invoked with /k/ arguments, where
Packit 58578d
`0` <= /k/ <= /n/. For example:
Packit 58578d
Packit 58578d
    tuple<int, double>()
Packit 58578d
    tuple<int, double>(1)
Packit 58578d
    tuple<int, double>(1, 3.14)
Packit 58578d
Packit 58578d
If no initial value for an element is provided, it is default initialized
Packit 58578d
(and hence must be default initializable). For example:
Packit 58578d
Packit 58578d
    class X {
Packit 58578d
      X();
Packit 58578d
    public:
Packit 58578d
      X(std::string);
Packit 58578d
    };
Packit 58578d
Packit 58578d
    tuple<X,X,X>()                                              // error: no default constructor for X
Packit 58578d
    tuple<X,X,X>(string("Jaba"), string("Daba"), string("Duu")) // ok
Packit 58578d
Packit 58578d
In particular, reference types do not have a default initialization:
Packit 58578d
Packit 58578d
    tuple<double&>()                // error: reference must be
Packit 58578d
                                    // initialized explicitly
Packit 58578d
Packit 58578d
    double d = 5;
Packit 58578d
    tuple<double&>(d)               // ok
Packit 58578d
Packit 58578d
    tuple<double&>(d+3.14)          // error: cannot initialize
Packit 58578d
                                    // non-const reference with a temporary
Packit 58578d
Packit 58578d
    tuple<const double&>(d+3.14)    // ok, but dangerous:
Packit 58578d
                                    // the element becomes a dangling reference
Packit 58578d
Packit 58578d
Using an initial value for an element that cannot be copied, is a compile time
Packit 58578d
error:
Packit 58578d
Packit 58578d
    class Y {
Packit 58578d
      Y(const Y&);
Packit 58578d
    public:
Packit 58578d
      Y();
Packit 58578d
    };
Packit 58578d
Packit 58578d
    char a[10];
Packit 58578d
Packit 58578d
    tuple<char[10], Y>(a, Y()); // error, neither arrays nor Y can be copied
Packit 58578d
    tuple<char[10], Y>();       // ok
Packit 58578d
Packit 58578d
Note particularly that the following is perfectly ok:
Packit 58578d
Packit 58578d
    Y y;
Packit 58578d
    tuple<char(&)[10], Y&>(a, y);
Packit 58578d
Packit 58578d
It is possible to come up with a tuple type that cannot be constructed. This
Packit 58578d
occurs if an element that cannot be initialized has a lower index than an
Packit 58578d
element that requires initialization. For example: `tuple<char[10], int&>`.
Packit 58578d
Packit 58578d
In sum, the tuple construction is semantically just a group of individual
Packit 58578d
elementary constructions.
Packit 58578d
Packit 58578d
[section:make_tuple The `make_tuple` function]
Packit 58578d
Packit 58578d
Tuples can also be constructed using the `make_tuple` (cf. `std::make_pair`)
Packit 58578d
helper functions. This makes the construction more convenient, saving the
Packit 58578d
programmer from explicitly specifying the element types:
Packit 58578d
Packit 58578d
    tuple<int, int, double> add_multiply_divide(int a, int b) {
Packit 58578d
      return make_tuple(a+b, a*b, double(a)/double(b));
Packit 58578d
    }
Packit 58578d
Packit 58578d
By default, the element types are deduced to the plain non-reference types.
Packit 58578d
E.g.:
Packit 58578d
Packit 58578d
    void foo(const A& a, B& b) {
Packit 58578d
      ...
Packit 58578d
      make_tuple(a, b);
Packit 58578d
Packit 58578d
The `make_tuple` invocation results in a tuple of type `tuple<A, B>`.
Packit 58578d
Packit 58578d
Sometimes the plain non-reference type is not desired, e.g. if the element
Packit 58578d
type cannot be copied. Therefore, the programmer can control the type
Packit 58578d
deduction and state that a reference to const or reference to non-const type
Packit 58578d
should be used as the element type instead. This is accomplished with two
Packit 58578d
helper template functions: [@boost:/libs/core/doc/html/core/ref.html `boost::ref`]
Packit 58578d
and [@boost:/libs/core/doc/html/core/ref.html `boost::cref`]. Any argument can
Packit 58578d
be wrapped with these functions to get the desired type. The mechanism does
Packit 58578d
not compromise const correctness since a const object wrapped with ref results
Packit 58578d
in a tuple element with const reference type (see the fifth example below).
Packit 58578d
For example:
Packit 58578d
Packit 58578d
    A a; B b; const A ca = a;
Packit 58578d
    make_tuple(cref(a), b);      // creates tuple<const A&, B>
Packit 58578d
    make_tuple(ref(a), b);       // creates tuple<A&, B>
Packit 58578d
    make_tuple(ref(a), cref(b)); // creates tuple<A&, const B&>
Packit 58578d
    make_tuple(cref(ca));        // creates tuple<const A&>
Packit 58578d
    make_tuple(ref(ca));         // creates tuple<const A&>
Packit 58578d
Packit 58578d
Array arguments to `make_tuple` functions are deduced to reference to const
Packit 58578d
types by default; there is no need to wrap them with `cref`. For example:
Packit 58578d
Packit 58578d
    make_tuple("Donald", "Daisy");
Packit 58578d
Packit 58578d
This creates an object of type `tuple<const char (&)[7], const char (&)[6]>`
Packit 58578d
(note that the type of a string literal is an array of const characters, not
Packit 58578d
`const char*`). However, to get `make_tuple` to create a tuple with an element
Packit 58578d
of a non-const array type one must use the `ref` wrapper.
Packit 58578d
Packit 58578d
Function pointers are deduced to the plain non-reference type, that is, to
Packit 58578d
plain function pointer. A tuple can also hold a reference to a function, but
Packit 58578d
such a tuple cannot be constructed with `make_tuple` (a const qualified
Packit 58578d
function type would result, which is illegal):
Packit 58578d
Packit 58578d
    void f(int i);
Packit 58578d
      ...
Packit 58578d
    make_tuple(&f); // tuple<void (*)(int)>
Packit 58578d
      ...
Packit 58578d
    tuple<tuple<void (&)(int)> > a(f) // ok
Packit 58578d
    make_tuple(f);                    // not ok
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:accessing_elements Accessing Tuple Elements]
Packit 58578d
Packit 58578d
Tuple elements are accessed with the expression:
Packit 58578d
Packit 58578d
    t.get<N>()
Packit 58578d
Packit 58578d
or
Packit 58578d
Packit 58578d
    get<N>(t)
Packit 58578d
Packit 58578d
where `t`  is a tuple object and `N` is a constant integral expression
Packit 58578d
specifying the index of the element to be accessed. Depending on whether `t`
Packit 58578d
is const or not, `get` returns the `N`-th element as a reference to const or
Packit 58578d
non-const type. The index of the first element is `0` and thus `N` must be
Packit 58578d
between `0` and /k/`-1`, where /k/ is the number of elements in the tuple.
Packit 58578d
Violations of these constraints are detected at compile time. Examples:
Packit 58578d
Packit 58578d
    double d = 2.7; A a;
Packit 58578d
    tuple<int, double&, const A&> t(1, d, a);
Packit 58578d
    const tuple<int, double&, const A&> ct = t;
Packit 58578d
      ...
Packit 58578d
    int i = get<0>(t); i = t.get<0>();        // ok
Packit 58578d
    int j = get<0>(ct);                       // ok
Packit 58578d
    get<0>(t) = 5;                            // ok
Packit 58578d
    get<0>(ct) = 5;                           // error, can't assign to const
Packit 58578d
      ...
Packit 58578d
    double e = get<1>(t); // ok
Packit 58578d
    get<1>(t) = 3.14;     // ok
Packit 58578d
    get<2>(t) = A();      // error, can't assign to const
Packit 58578d
    A aa = get<3>(t);     // error: index out of bounds
Packit 58578d
      ...
Packit 58578d
    ++get<0>(t);  // ok, can be used as any variable
Packit 58578d
Packit 58578d
/[Note:/ The member `get` functions are not supported with MS Visual C++
Packit 58578d
compiler. Further, the compiler has trouble with finding the non-member `get`
Packit 58578d
functions without an explicit namespace qualifier. Hence, all `get` calls
Packit 58578d
should be qualified as `tuples::get<N>(a_tuple)` when writing code that should
Packit 58578d
compile with MSVC++ 6.0./]/
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:construction_and_assignment Copy Construction and Tuple Assignment]
Packit 58578d
Packit 58578d
A tuple can be copy constructed from another tuple, provided that the element
Packit 58578d
types are element-wise copy constructible. Analogously, a tuple can be
Packit 58578d
assigned to another tuple, provided that the element types are element-wise
Packit 58578d
assignable. For example:
Packit 58578d
Packit 58578d
    class A {};
Packit 58578d
    class B : public A {};
Packit 58578d
    struct C { C(); C(const B&); };
Packit 58578d
    struct D { operator C() const; };
Packit 58578d
    tuple<char, B*, B, D> t;
Packit 58578d
      ...
Packit 58578d
    tuple<int, A*, C, C> a(t); // ok
Packit 58578d
    a = t;                     // ok
Packit 58578d
Packit 58578d
In both cases, the conversions performed are:
Packit 58578d
Packit 58578d
* `char -> int`,
Packit 58578d
* `B* -> A*` (derived class pointer to base class pointer),
Packit 58578d
* `B -> C` (a user defined conversion), and
Packit 58578d
* `D -> C` (a user defined conversion).
Packit 58578d
Packit 58578d
Note that assignment is also defined from `std::pair` types:
Packit 58578d
Packit 58578d
    tuple<float, int> a = std::make_pair(1, 'a');
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:relational_operators Relational Operators]
Packit 58578d
Packit 58578d
Tuples reduce the operators `==`, `!=`, `<`, `>`, `<=` and `>=` to the
Packit 58578d
corresponding elementary operators. This means, that if any of these operators
Packit 58578d
is defined between all elements of two tuples, then the same operator is
Packit 58578d
defined between the tuples as well. The equality operators for two tuples `a`
Packit 58578d
and `b` are defined as:
Packit 58578d
Packit 58578d
* `a == b` iff for each `i`: `a`'''<subscript>i</subscript>'''` == b`'''<subscript>i</subscript>'''
Packit 58578d
* `a != b` iff exists `i`: `a`'''<subscript>i</subscript>'''` != b`'''<subscript>i</subscript>'''
Packit 58578d
Packit 58578d
The operators `<`, `>`, `<=` and `>=` implement a lexicographical ordering.
Packit 58578d
Packit 58578d
Note that an attempt to compare two tuples of different lengths results in a
Packit 58578d
compile time error. Also, the comparison operators are /"short-circuited"/:
Packit 58578d
elementary comparisons start from the first elements and are performed only
Packit 58578d
until the result is clear.
Packit 58578d
Packit 58578d
Examples:
Packit 58578d
Packit 58578d
    tuple<std::string, int, A> t1(std::string("same?"), 2, A());
Packit 58578d
    tuple<std::string, long, A> t2(std::string("same?"), 2, A());
Packit 58578d
    tuple<std::string, long, A> t3(std::string("different"), 3, A());
Packit 58578d
Packit 58578d
    bool operator==(A, A) { std::cout << "All the same to me..."; return true; }
Packit 58578d
Packit 58578d
    t1 == t2;               // true
Packit 58578d
    t1 == t3;               // false, does not print "All the..."
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:tiers Tiers]
Packit 58578d
Packit 58578d
/Tiers/ are tuples, where all elements are of non-const reference types. They
Packit 58578d
are constructed with a call to the `tie` function template (cf. `make_tuple`):
Packit 58578d
Packit 58578d
    int i; char c; double d;
Packit 58578d
      ...
Packit 58578d
    tie(i, c, a);
Packit 58578d
Packit 58578d
The above `tie` function creates a tuple of type `tuple<int&, char&, double&>`.
Packit 58578d
The same result could be achieved with the call `make_tuple(ref(i), ref(c), ref(a))`.
Packit 58578d
Packit 58578d
A tuple that contains non-const references as elements can be used to 'unpack'
Packit 58578d
another tuple into variables. E.g.:
Packit 58578d
Packit 58578d
    int i; char c; double d;
Packit 58578d
    tie(i, c, d) = make_tuple(1,'a', 5.5);
Packit 58578d
    std::cout << i << " " <<  c << " " << d;
Packit 58578d
Packit 58578d
This code prints `1 a 5.5` to the standard output stream. A tuple unpacking
Packit 58578d
operation like this is found for example in ML and Python. It is convenient
Packit 58578d
when calling functions which return tuples.
Packit 58578d
Packit 58578d
The tying mechanism works with `std::pair` templates as well:
Packit 58578d
Packit 58578d
    int i; char c;
Packit 58578d
    tie(i, c) = std::make_pair(1, 'a');
Packit 58578d
Packit 58578d
[section Ignore]
Packit 58578d
Packit 58578d
There is also an object called `ignore` which allows you to ignore an element
Packit 58578d
assigned by a tuple. The idea is that a function may return a tuple, only part
Packit 58578d
of which you are interested in. For example (note, that ignore is under the
Packit 58578d
`tuples` subnamespace):
Packit 58578d
Packit 58578d
    char c;
Packit 58578d
    tie(tuples::ignore, c) = std::make_pair(1, 'a');
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:streaming Streaming]
Packit 58578d
Packit 58578d
The global `operator<<` has been overloaded for `std::ostream` such that
Packit 58578d
tuples are output by recursively calling `operator<<` for each element.
Packit 58578d
Packit 58578d
Analogously, the global `operator>>` has been overloaded to extract tuples
Packit 58578d
from `std::istream` by recursively calling `operator>>` for each element.
Packit 58578d
Packit 58578d
The default delimiter between the elements is space, and the tuple is enclosed
Packit 58578d
in parenthesis. For Example:
Packit 58578d
Packit 58578d
    tuple<float, int, std::string> a(1.0f,  2, std::string("Howdy folks!");
Packit 58578d
Packit 58578d
    cout << a;
Packit 58578d
Packit 58578d
outputs the tuple as: `(1.0 2 Howdy folks!)`
Packit 58578d
Packit 58578d
The library defines three manipulators for changing the default behavior:
Packit 58578d
Packit 58578d
* `set_open(char)` defines the character that is output before the first element.
Packit 58578d
* `set_close(char)` defines the character that is output after the last element.
Packit 58578d
* `set_delimiter(char)` defines the delimiter character between elements.
Packit 58578d
Packit 58578d
Note, that these manipulators are defined in the tuples subnamespace. For
Packit 58578d
example:
Packit 58578d
Packit 58578d
    cout << tuples::set_open('[') << tuples::set_close(']') << tuples::set_delimiter(',') << a;
Packit 58578d
Packit 58578d
outputs the same tuple `a` as: `[1.0,2,Howdy folks!]`
Packit 58578d
Packit 58578d
The same manipulators work with `operator>>` and `istream` as well. Suppose
Packit 58578d
the `cin` stream contains the following data:
Packit 58578d
Packit 58578d
    (1 2 3) [4:5]
Packit 58578d
Packit 58578d
The code:
Packit 58578d
Packit 58578d
    tuple<int, int, int> i;
Packit 58578d
    tuple<int, int> j;
Packit 58578d
Packit 58578d
    cin >> i;
Packit 58578d
    cin >> tuples::set_open('[') >> tuples::set_close(']') >> tuples::set_delimiter(':');
Packit 58578d
    cin >> j;
Packit 58578d
Packit 58578d
reads the data into the tuples `i` and `j`.
Packit 58578d
Packit 58578d
Note that extracting tuples with `std::string` or C-style string elements does
Packit 58578d
not generally work, since the streamed tuple representation may not be
Packit 58578d
unambiguously parseable.
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:performance Performance]
Packit 58578d
Packit 58578d
All tuple access and construction functions are small inlined one-liners.
Packit 58578d
Therefore, a decent compiler can eliminate any extra cost of using tuples
Packit 58578d
compared to using hand-written tuple like classes. Particularly, with a decent
Packit 58578d
compiler there is no performance difference between this code:
Packit 58578d
Packit 58578d
    class hand_made_tuple {
Packit 58578d
      A a; B b; C c;
Packit 58578d
    public:
Packit 58578d
      hand_made_tuple(const A& aa, const B& bb, const C& cc)
Packit 58578d
        : a(aa), b(bb), c(cc) {};
Packit 58578d
      A& getA() { return a; };
Packit 58578d
      B& getB() { return b; };
Packit 58578d
      C& getC() { return c; };
Packit 58578d
    };
Packit 58578d
Packit 58578d
    hand_made_tuple hmt(A(), B(), C());
Packit 58578d
    hmt.getA(); hmt.getB(); hmt.getC();
Packit 58578d
Packit 58578d
and this code:
Packit 58578d
Packit 58578d
    tuple<A, B, C> t(A(), B(), C());
Packit 58578d
    t.get<0>(); t.get<1>(); t.get<2>();
Packit 58578d
Packit 58578d
Note, that there are widely used compilers (e.g. bcc 5.5.1) which fail to
Packit 58578d
optimize this kind of tuple usage.
Packit 58578d
Packit 58578d
Depending on the optimizing ability of the compiler, the tier mechanism may
Packit 58578d
have a small performance penalty compared to using non-const reference
Packit 58578d
parameters as a mechanism for returning multiple values from a function. For
Packit 58578d
example, suppose that the following functions `f1` and `f2` have equivalent
Packit 58578d
functionalities:
Packit 58578d
Packit 58578d
    void f1(int&, double&);
Packit 58578d
    tuple<int, double> f2();
Packit 58578d
Packit 58578d
Then, the call #1 may be slightly faster than #2 in the code below:
Packit 58578d
Packit 58578d
    int i; double d;
Packit 58578d
      ...
Packit 58578d
    f1(i,d);         // #1
Packit 58578d
    tie(i,d) = f2(); // #2
Packit 58578d
Packit 58578d
See [[link publ_1 1], [link publ_2 2]] for more in-depth discussions about 
Packit 58578d
efficiency.
Packit 58578d
Packit 58578d
[section Effect on Compile Time]
Packit 58578d
Packit 58578d
Compiling tuples can be slow due to the excessive amount of template
Packit 58578d
instantiations. Depending on the compiler and the tuple length, it may be more
Packit 58578d
than 10 times slower to compile a tuple construct, compared to compiling an
Packit 58578d
equivalent explicitly written class, such as the `hand_made_tuple` class above.
Packit 58578d
However, as a realistic program is likely to contain a lot of code in addition
Packit 58578d
to tuple definitions, the difference is probably unnoticeable. Compile time
Packit 58578d
increases between 5 and 10 percent were measured for programs which used tuples
Packit 58578d
very frequently. With the same test programs, memory consumption of compiling
Packit 58578d
increased between 22% to 27%. See [[link publ_1 1], [link publ_2 2]] for
Packit 58578d
details.
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:portability Portability]
Packit 58578d
Packit 58578d
The library code is(?) standard C++ and thus the library works with a standard
Packit 58578d
conforming compiler. Below is a list of compilers and known problems with each
Packit 58578d
compiler:
Packit 58578d
Packit 58578d
[table
Packit 58578d
    [[Compiler]        [Problems]]
Packit 58578d
    [[gcc 2.95]        [-]]
Packit 58578d
    [[edg 2.44]        [-]]
Packit 58578d
    [[Borland 5.5]     [Can't use function pointers or member pointers as
Packit 58578d
                       tuple elements]]
Packit 58578d
    [[Metrowerks 6.2]  [Can't use `ref` and `cref` wrappers]]
Packit 58578d
    [[MS Visual C++]   [No reference elements (`tie` still works). Can't use
Packit 58578d
                       `ref` and `cref` wrappers]]
Packit 58578d
]
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:more_details More Details]
Packit 58578d
Packit 58578d
[link tuple_advanced_interface Advanced features] (describes some metafunctions etc.).
Packit 58578d
Packit 58578d
[link design_decisions_rationale Rationale behind some design/implementation decisions].
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:thanks Acknowledgements]
Packit 58578d
Packit 58578d
Gary Powell has been an indispensable helping hand. In particular, stream
Packit 58578d
manipulators for tuples were his idea. Doug Gregor came up with a working
Packit 58578d
version for MSVC, David Abrahams found a way to get rid of most of the
Packit 58578d
restrictions for compilers not supporting partial specialization. Thanks to
Packit 58578d
Jeremy Siek, William Kempf and Jens Maurer for their help and suggestions. The
Packit 58578d
comments by Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes, David
Packit 58578d
Abrahams and Hartmut Kaiser helped to improve the library. The idea for the
Packit 58578d
`tie` mechanism came from an old usenet article by Ian McCulloch, where he
Packit 58578d
proposed something similar for `std::pair`s.
Packit 58578d
Packit 58578d
[endsect]
Packit 58578d
Packit 58578d
[section:references References]
Packit 58578d
Packit 58578d
[#publ_1]
Packit 58578d
[1] J\u00E4rvi J.: /Tuples and multiple return values in C++/, TUCS Technical Report No 249, 1999.
Packit 58578d
Packit 58578d
[#publ_2]
Packit 58578d
[2] J\u00E4rvi J.: /ML-Style Tuple Assignment in Standard C++ - Extending the Multiple Return Value Formalism/, TUCS Technical Report No 267, 1999.
Packit 58578d
Packit 58578d
[#publ_3]
Packit 58578d
[3] J\u00E4rvi J.: /Tuple Types and Multiple Return Values/, C/C++ Users Journal, August 2001.
Packit 58578d
Packit 58578d
[endsect]