Squashed 'third_party/boostorg/tuple/' content from commit fb55aa6

Change-Id: I7b2b942d5d0a30df2c80bcb90e9bd79a86a0acdc
git-subtree-dir: third_party/boostorg/tuple
git-subtree-split: fb55aa6d4d5e6917f55dbd7aee58afde97879b85
diff --git a/doc/tuple_users_guide.qbk b/doc/tuple_users_guide.qbk
new file mode 100644
index 0000000..43d03e6
--- /dev/null
+++ b/doc/tuple_users_guide.qbk
@@ -0,0 +1,525 @@
+[/
+ /  Copyright (c) 2001 Jaakko Järvi
+ /
+ / 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)
+ /]
+
+[library Boost.Tuple
+  [quickbook 1.6]
+  [id tuple]
+  [copyright 2001 Jaakko J\u00E4rvi]
+  [dirname tuple]
+  [license Distributed under the
+    [@http://boost.org/LICENSE_1_0.txt Boost Software License,
+      Version 1.0].
+  ]
+]
+
+[include tuple_advanced_interface.qbk]
+[include design_decisions_rationale.qbk]
+
+[template simplesect[title]
+[block '''<simplesect><title>'''[title]'''</title>''']]
+
+[template endsimplesect[]
+[block '''</simplesect>''']]
+
+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.
+
+[section:using_library 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.
+
+[endsect]
+
+[section:tuple_types 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 copied, or that are
+not default constructible (see [link tuple.constructing_tuples '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*>
+
+[endsect]
+
+[section:constructing_tuples 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.
+
+[section:make_tuple 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: [@boost:/libs/core/doc/html/core/ref.html `boost::ref`]
+and [@boost:/libs/core/doc/html/core/ref.html `boost::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 example 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
+
+[endsect]
+
+[endsect]
+
+[section:accessing_elements 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 `N`-th 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 constraints 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 should
+compile with MSVC++ 6.0./]/
+
+[endsect]
+
+[section:construction_and_assignment 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');
+
+[endsect]
+
+[section:relational_operators 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:
+
+* `a == b` iff for each `i`: `a`'''<subscript>i</subscript>'''` == b`'''<subscript>i</subscript>'''
+* `a != b` iff exists `i`: `a`'''<subscript>i</subscript>'''` != b`'''<subscript>i</subscript>'''
+
+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..."
+
+[endsect]
+
+[section:tiers 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');
+
+[section 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');
+
+[endsect]
+
+[endsect]
+
+[section:streaming 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:
+
+* `set_open(char)` defines the character that is output before the first element.
+* `set_close(char)` defines the character that is output after the last element.
+* `set_delimiter(char)` defines the delimiter character between elements.
+
+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(']') >> tuples::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.
+
+[endsect]
+
+[section:performance 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 [[link publ_1 1], [link publ_2 2]] for more in-depth discussions about 
+efficiency.
+
+[section 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 and 10 percent were measured for programs which used tuples
+very frequently. With the same test programs, memory consumption of compiling
+increased between 22% to 27%. See [[link publ_1 1], [link publ_2 2]] for
+details.
+
+[endsect]
+
+[endsect]
+
+[section:portability 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:
+
+[table
+    [[Compiler]        [Problems]]
+    [[gcc 2.95]        [-]]
+    [[edg 2.44]        [-]]
+    [[Borland 5.5]     [Can't use function pointers or member pointers as
+                       tuple elements]]
+    [[Metrowerks 6.2]  [Can't use `ref` and `cref` wrappers]]
+    [[MS Visual C++]   [No reference elements (`tie` still works). Can't use
+                       `ref` and `cref` wrappers]]
+]
+
+[endsect]
+
+[section:more_details More Details]
+
+[link tuple_advanced_interface Advanced features] (describes some metafunctions etc.).
+
+[link design_decisions_rationale Rationale behind some design/implementation decisions].
+
+[endsect]
+
+[section:thanks 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::pair`s.
+
+[endsect]
+
+[section:references References]
+
+[#publ_1]
+[1] J\u00E4rvi J.: /Tuples and multiple return values in C++/, TUCS Technical Report No 249, 1999.
+
+[#publ_2]
+[2] J\u00E4rvi J.: /ML-Style Tuple Assignment in Standard C++ - Extending the Multiple Return Value Formalism/, TUCS Technical Report No 267, 1999.
+
+[#publ_3]
+[3] J\u00E4rvi J.: /Tuple Types and Multiple Return Values/, C/C++ Users Journal, August 2001.
+
+[endsect]