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/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..3e84d7c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,96 @@
+* text=auto !eol svneol=native#text/plain
+*.gitattributes text svneol=native#text/plain
+
+# Scriptish formats
+*.bat        text svneol=native#text/plain
+*.bsh        text svneol=native#text/x-beanshell
+*.cgi        text svneol=native#text/plain
+*.cmd        text svneol=native#text/plain
+*.js         text svneol=native#text/javascript
+*.php        text svneol=native#text/x-php
+*.pl         text svneol=native#text/x-perl
+*.pm         text svneol=native#text/x-perl
+*.py         text svneol=native#text/x-python
+*.sh         eol=lf svneol=LF#text/x-sh
+configure    eol=lf svneol=LF#text/x-sh
+
+# Image formats
+*.bmp        binary svneol=unset#image/bmp
+*.gif        binary svneol=unset#image/gif
+*.ico        binary svneol=unset#image/ico
+*.jpeg       binary svneol=unset#image/jpeg
+*.jpg        binary svneol=unset#image/jpeg
+*.png        binary svneol=unset#image/png
+*.tif        binary svneol=unset#image/tiff
+*.tiff       binary svneol=unset#image/tiff
+*.svg        text svneol=native#image/svg%2Bxml
+
+# Data formats
+*.pdf        binary svneol=unset#application/pdf
+*.avi        binary svneol=unset#video/avi
+*.doc        binary svneol=unset#application/msword
+*.dsp        text svneol=crlf#text/plain
+*.dsw        text svneol=crlf#text/plain
+*.eps        binary svneol=unset#application/postscript
+*.gz         binary svneol=unset#application/gzip
+*.mov        binary svneol=unset#video/quicktime
+*.mp3        binary svneol=unset#audio/mpeg
+*.ppt        binary svneol=unset#application/vnd.ms-powerpoint
+*.ps         binary svneol=unset#application/postscript
+*.psd        binary svneol=unset#application/photoshop
+*.rdf        binary svneol=unset#text/rdf
+*.rss        text svneol=unset#text/xml
+*.rtf        binary svneol=unset#text/rtf
+*.sln        text svneol=native#text/plain
+*.swf        binary svneol=unset#application/x-shockwave-flash
+*.tgz        binary svneol=unset#application/gzip
+*.vcproj     text svneol=native#text/xml
+*.vcxproj    text svneol=native#text/xml
+*.vsprops    text svneol=native#text/xml
+*.wav        binary svneol=unset#audio/wav
+*.xls        binary svneol=unset#application/vnd.ms-excel
+*.zip        binary svneol=unset#application/zip
+
+# Text formats
+.htaccess    text svneol=native#text/plain
+*.bbk        text svneol=native#text/xml
+*.cmake      text svneol=native#text/plain
+*.css        text svneol=native#text/css
+*.dtd        text svneol=native#text/xml
+*.htm        text svneol=native#text/html
+*.html       text svneol=native#text/html
+*.ini        text svneol=native#text/plain
+*.log        text svneol=native#text/plain
+*.mak        text svneol=native#text/plain
+*.qbk        text svneol=native#text/plain
+*.rst        text svneol=native#text/plain
+*.sql        text svneol=native#text/x-sql
+*.txt        text svneol=native#text/plain
+*.xhtml      text svneol=native#text/xhtml%2Bxml
+*.xml        text svneol=native#text/xml
+*.xsd        text svneol=native#text/xml
+*.xsl        text svneol=native#text/xml
+*.xslt       text svneol=native#text/xml
+*.xul        text svneol=native#text/xul
+*.yml        text svneol=native#text/plain
+boost-no-inspect text svneol=native#text/plain
+CHANGES      text svneol=native#text/plain
+COPYING      text svneol=native#text/plain
+INSTALL      text svneol=native#text/plain
+Jamfile      text svneol=native#text/plain
+Jamroot      text svneol=native#text/plain
+Jamfile.v2   text svneol=native#text/plain
+Jamrules     text svneol=native#text/plain
+Makefile*    text svneol=native#text/plain
+README       text svneol=native#text/plain
+TODO         text svneol=native#text/plain
+
+# Code formats
+*.c          text svneol=native#text/plain
+*.cpp        text svneol=native#text/plain
+*.h          text svneol=native#text/plain
+*.hpp        text svneol=native#text/plain
+*.ipp        text svneol=native#text/plain
+*.tpp        text svneol=native#text/plain
+*.jam        text svneol=native#text/plain
+*.java       text svneol=native#text/plain
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..fd5e2f8
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,111 @@
+# Copyright 2016, 2017 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
+
+language: cpp
+
+sudo: false
+
+python: "2.7"
+
+branches:
+  only:
+    - master
+    - develop
+    - /feature\/.*/
+
+env:
+  matrix:
+    - BOGUS_JOB=true
+
+matrix:
+
+  exclude:
+    - env: BOGUS_JOB=true
+
+  include:
+    - os: linux
+      compiler: g++
+      env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
+
+    - os: linux
+      compiler: g++-5
+      env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
+      addons:
+        apt:
+          packages:
+            - g++-5
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: g++-6
+      env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
+      addons:
+        apt:
+          packages:
+            - g++-6
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: g++-7
+      env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      compiler: clang++
+      env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
+
+    - os: linux
+      compiler: clang++-4.0
+      env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
+      addons:
+        apt:
+          packages:
+            - clang-4.0
+          sources:
+            - ubuntu-toolchain-r-test
+            - llvm-toolchain-trusty-4.0
+
+    - os: linux
+      compiler: clang++-5.0
+      env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
+      addons:
+        apt:
+          packages:
+            - clang-5.0
+          sources:
+            - ubuntu-toolchain-r-test
+            - llvm-toolchain-trusty-5.0
+
+    - os: osx
+      compiler: clang++
+      env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
+
+install:
+  - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
+  - cd ..
+  - git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root
+  - cd boost-root
+  - git submodule update --init tools/build
+  - git submodule update --init libs/config
+  - git submodule update --init tools/boostdep
+  - cp -r $TRAVIS_BUILD_DIR/* libs/tuple
+  - python tools/boostdep/depinst/depinst.py tuple
+  - ./bootstrap.sh
+  - ./b2 headers
+
+script:
+  - |-
+    echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
+  - ./b2 -j 3 libs/tuple/test toolset=$TOOLSET cxxstd=$CXXSTD
+
+notifications:
+  email:
+    on_success: always
diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
new file mode 100644
index 0000000..04b49ac
--- /dev/null
+++ b/doc/Jamfile.v2
@@ -0,0 +1,37 @@
+#   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)
+
+project doc/tuple ;
+
+import boostbook ;
+import quickbook ;
+
+xml tuple : tuple_users_guide.qbk ;
+
+boostbook standalone_tuple
+    :
+        tuple
+    :
+        <xsl:param>boost.root=../../../..
+        # File name of HTML output:
+        <xsl:param>root.filename=tuple_users_guide
+        # How far down we chunk nested sections, basically all of them:
+        <xsl:param>chunk.section.depth=0
+        # Don't put the first section on the same page as the TOC:
+        <xsl:param>chunk.first.sections=0
+        # How far down sections get TOC's
+        <xsl:param>toc.section.depth=1
+        # Max depth in each TOC:
+        <xsl:param>toc.max.depth=1
+        # How far down we go with TOC's
+        <xsl:param>generate.section.toc.level=0
+     ;
+
+###############################################################################
+alias boostdoc ;
+explicit boostdoc ;
+alias boostrelease : standalone_tuple ;
+explicit boostrelease ;
diff --git a/doc/design_decisions_rationale.qbk b/doc/design_decisions_rationale.qbk
new file mode 100644
index 0000000..a8f4e6d
--- /dev/null
+++ b/doc/design_decisions_rationale.qbk
@@ -0,0 +1,190 @@
+[/
+ /  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)
+ /]
+
+[article Design decisions rationale
+  [quickbook 1.6]
+  [id design_decisions_rationale]
+  [copyright 2001 Jaakko J\u00E4rvi]
+  [license Distributed under the
+    [@http://boost.org/LICENSE_1_0.txt Boost Software License,
+      Version 1.0].
+  ]
+]
+
+[template simplesect[title]
+[block '''<simplesect><title>'''[title]'''</title>''']]
+
+[template endsimplesect[]
+[block '''</simplesect>''']]
+
+[section 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.
+
+[section 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;
+
+[endsect]
+
+[endsect]
+
+[section 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`.
+
+[endsect]
+
+[section Element indexing]
+
+Whether to use `0`- or `1`-based indexing was discussed more than thoroughly,
+and the following observations were made:
+
+* `0`-based indexing is 'the C++ way' and used with arrays etc.
+
+* `1`-based 'name like' indexing exists as well, eg. `bind1st`, `bind2nd`,
+  `pair::first`, etc.
+
+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:
+
+* `0`-based indexing might not please everyone, but once its fixed, it is less
+  confusing than having two different methods (would anyone want such
+  constants for arrays?).
+
+* Adding the other indexing scheme doesn't really provide anything new (like a
+  new feature) to the user of the library.
+
+* C++ variable and constant naming rules don't give many possibilities for
+  defining short and nice index constants (like `_1st`, ...). Let the binding
+  and lambda libraries use these for a better purpose.
+
+* The access syntax a[_1st] (or a(_1st)) is appealing, and almost made us add
+  the index constants after all. However, `0`-based subscripting is so deep in
+  C++, that we had a fear for confusion.
+
+* Such constants are easy to add.
+
+[endsect]
+
+[section 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.
+
+[endsect]
+
+[section 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:
+
+* Allow only plain `char` types as the tuple delimiters and use `widen` and
+  `narrow` to convert between the real character type of the stream. This
+  would always compile, but some calls to set manipulators might result in a
+  different character than expected (some default character).
+
+* Allocate enough space to hold the real character type of the stream. This
+  means memory for holding the delimiter characters must be allocated
+  separately, and that pointers to this memory are stored in the space
+  allocated with `ios_base::xalloc`. Any volunteers?
+
+[endsect]
diff --git a/doc/tuple_advanced_interface.qbk b/doc/tuple_advanced_interface.qbk
new file mode 100644
index 0000000..051e0ca
--- /dev/null
+++ b/doc/tuple_advanced_interface.qbk
@@ -0,0 +1,159 @@
+[/
+ /  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)
+ /]
+
+[article Tuple library advanced features
+  [quickbook 1.6]
+  [id tuple_advanced_interface]
+  [copyright 2001 Jaakko J\u00E4rvi]
+  [license Distributed under the
+    [@http://boost.org/LICENSE_1_0.txt Boost Software License,
+      Version 1.0].
+  ]
+]
+
+[template simplesect[title]
+[block '''<simplesect><title>'''[title]'''</title>''']]
+
+[template endsimplesect[]
+[block '''</simplesect>''']]
+
+The advanced features described in this document are all under namespace
+`::boost::tuples`
+
+[section 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 `N`-th 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`.
+
+[endsect]
+
+[section 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>`.
+
+[section Empty tuple]
+
+The internal representation of the empty tuple `tuple<>` is `null_type`.
+
+[endsect]
+
+[section 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()); }
+
+[endsect]
+
+[section 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.
+
+[endsect]
+
+[endsect]
+
+[section Traits classes for tuple element types]
+
+[section access_traits]
+
+The template `access_traits` defines three type functions. Let `T` be a type
+of an element in a tuple:
+
+* `access_traits<T>::non_const_type` maps `T` to the return type of the no
+  n-const access functions (nonmember and member `get` functions, and the
+  `get_head` function).
+
+* `access_traits<T>::const_type` maps `T` to the return type of the const
+  access functions.
+
+* `access_traits<T>::parameter_type` maps `T` to the parameter type of the
+  tuple constructor.
+
+[endsect]
+
+[section 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:
+
+* /any reference type/ -> /compile time error/
+
+* /any array type/ -> /constant reference to the array type/
+
+* `reference_wrapper<T>` -> `T&`
+
+* `T` -> `T`
+
+Objects of type `reference_wrapper` are created with the `ref` and `cref`
+functions (see [link tuple.constructing_tuples.make_tuple 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
+[@boost:/libs/core/doc/html/core/ref.html `ref.hpp`] in the main boost include
+directory; and directly in the `boost` namespace.
+
+[endsect]
+
+[endsect]
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]
diff --git a/include/boost/tuple/detail/tuple_basic.hpp b/include/boost/tuple/detail/tuple_basic.hpp
new file mode 100644
index 0000000..879f0e9
--- /dev/null
+++ b/include/boost/tuple/detail/tuple_basic.hpp
@@ -0,0 +1,987 @@
+//  tuple_basic.hpp -----------------------------------------------------
+
+// Copyright (C) 1999, 2000 Jaakko Jarvi (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
+
+// Outside help:
+// This and that, Gary Powell.
+// Fixed return types for get_head/get_tail
+// ( and other bugs ) per suggestion of Jens Maurer
+// simplified element type accessors + bug fix  (Jeremy Siek)
+// Several changes/additions according to suggestions by Douglas Gregor,
+// William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes,
+// David Abrahams.
+
+// Revision history:
+// 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes
+// 2002 04 18 Jaakko: tuple element types can be void or plain function
+//                    types, as long as no object is created.
+//                    Tuple objects can no hold even noncopyable types
+//                    such as arrays.
+// 2001 10 22 John Maddock
+//      Fixes for Borland C++
+// 2001 08 30 David Abrahams
+//      Added default constructor for cons<>.
+// -----------------------------------------------------------------
+
+#ifndef BOOST_TUPLE_BASIC_HPP
+#define BOOST_TUPLE_BASIC_HPP
+
+
+#include <utility> // needed for the assignment from pair to tuple
+
+#include <boost/type_traits/cv_traits.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/utility/swap.hpp>
+
+#include <boost/detail/workaround.hpp> // needed for BOOST_WORKAROUND
+
+#if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#endif
+
+namespace boost {
+namespace tuples {
+
+// -- null_type --------------------------------------------------------
+struct null_type {};
+
+// a helper function to provide a const null_type type temporary
+namespace detail {
+  inline const null_type cnull() { return null_type(); }
+
+
+// -- if construct ------------------------------------------------
+// Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
+
+template <bool If, class Then, class Else> struct IF { typedef Then RET; };
+
+template <class Then, class Else> struct IF<false, Then, Else> {
+  typedef Else RET;
+};
+
+} // end detail
+
+// - cons forward declaration -----------------------------------------------
+template <class HT, class TT> struct cons;
+
+
+// - tuple forward declaration -----------------------------------------------
+template <
+  class T0 = null_type, class T1 = null_type, class T2 = null_type,
+  class T3 = null_type, class T4 = null_type, class T5 = null_type,
+  class T6 = null_type, class T7 = null_type, class T8 = null_type,
+  class T9 = null_type>
+class tuple;
+
+// tuple_length forward declaration
+template<class T> struct length;
+
+
+
+namespace detail {
+
+// -- generate error template, referencing to non-existing members of this
+// template is used to produce compilation errors intentionally
+template<class T>
+class generate_error;
+
+template<int N>
+struct drop_front {
+    template<class Tuple>
+    struct apply {
+        typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
+            apply<Tuple> next;
+        typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
+        static const type& call(const Tuple& tup) {
+            return next::call(tup).tail;
+        }
+    };
+};
+
+template<>
+struct drop_front<0> {
+    template<class Tuple>
+    struct apply {
+        typedef Tuple type;
+        static const type& call(const Tuple& tup) {
+            return tup;
+        }
+    };
+};
+
+} // end of namespace detail
+
+
+// -cons type accessors ----------------------------------------
+// typename tuples::element<N,T>::type gets the type of the
+// Nth element ot T, first element is at index 0
+// -------------------------------------------------------
+
+#ifndef BOOST_NO_CV_SPECIALIZATIONS
+
+template<int N, class T>
+struct element
+{
+  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
+      apply<T>::type::head_type type;
+};
+
+template<int N, class T>
+struct element<N, const T>
+{
+private:
+  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
+      apply<T>::type::head_type unqualified_type;
+public:
+#if BOOST_WORKAROUND(__BORLANDC__,<0x600)
+  typedef const unqualified_type type;
+#else
+  typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
+#endif
+};
+#else // def BOOST_NO_CV_SPECIALIZATIONS
+
+namespace detail {
+
+template<int N, class T, bool IsConst>
+struct element_impl
+{
+  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
+      apply<T>::type::head_type type;
+};
+
+template<int N, class T>
+struct element_impl<N, T, true /* IsConst */>
+{
+  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
+      apply<T>::type::head_type unqualified_type;
+  typedef const unqualified_type type;
+};
+
+} // end of namespace detail
+
+
+template<int N, class T>
+struct element:
+  public detail::element_impl<N, T, ::boost::is_const<T>::value>
+{
+};
+
+#endif
+
+
+// -get function templates -----------------------------------------------
+// Usage: get<N>(aTuple)
+
+// -- some traits classes for get functions
+
+// access traits lifted from detail namespace to be part of the interface,
+// (Joel de Guzman's suggestion). Rationale: get functions are part of the
+// interface, so should the way to express their return types be.
+
+template <class T> struct access_traits {
+  typedef const T& const_type;
+  typedef T& non_const_type;
+
+  typedef const typename boost::remove_cv<T>::type& parameter_type;
+
+// used as the tuple constructors parameter types
+// Rationale: non-reference tuple element types can be cv-qualified.
+// It should be possible to initialize such types with temporaries,
+// and when binding temporaries to references, the reference must
+// be non-volatile and const. 8.5.3. (5)
+};
+
+template <class T> struct access_traits<T&> {
+
+  typedef T& const_type;
+  typedef T& non_const_type;
+
+  typedef T& parameter_type;
+};
+
+// get function for non-const cons-lists, returns a reference to the element
+
+template<int N, class HT, class TT>
+inline typename access_traits<
+                  typename element<N, cons<HT, TT> >::type
+                >::non_const_type
+get(cons<HT, TT>& c) {
+  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
+      apply<cons<HT, TT> > impl;
+  typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
+  return const_cast<cons_element&>(impl::call(c)).head;
+}
+
+// get function for const cons-lists, returns a const reference to
+// the element. If the element is a reference, returns the reference
+// as such (that is, can return a non-const reference)
+template<int N, class HT, class TT>
+inline typename access_traits<
+                  typename element<N, cons<HT, TT> >::type
+                >::const_type
+get(const cons<HT, TT>& c) {
+  typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
+      apply<cons<HT, TT> > impl;
+  return impl::call(c).head;
+}
+
+// -- the cons template  --------------------------------------------------
+namespace detail {
+
+//  These helper templates wrap void types and plain function types.
+//  The reationale is to allow one to write tuple types with those types
+//  as elements, even though it is not possible to instantiate such object.
+//  E.g: typedef tuple<void> some_type; // ok
+//  but: some_type x; // fails
+
+template <class T> class non_storeable_type {
+  non_storeable_type();
+};
+
+template <class T> struct wrap_non_storeable_type {
+  typedef typename IF<
+    ::boost::is_function<T>::value, non_storeable_type<T>, T
+  >::RET type;
+};
+template <> struct wrap_non_storeable_type<void> {
+  typedef non_storeable_type<void> type;
+};
+
+} // detail
+
+template <class HT, class TT>
+struct cons {
+
+  typedef HT head_type;
+  typedef TT tail_type;
+
+  typedef typename
+    detail::wrap_non_storeable_type<head_type>::type stored_head_type;
+
+  stored_head_type head;
+  tail_type tail;
+
+  typename access_traits<stored_head_type>::non_const_type
+  get_head() { return head; }
+
+  typename access_traits<tail_type>::non_const_type
+  get_tail() { return tail; }
+
+  typename access_traits<stored_head_type>::const_type
+  get_head() const { return head; }
+
+  typename access_traits<tail_type>::const_type
+  get_tail() const { return tail; }
+
+  cons() : head(), tail() {}
+  //  cons() : head(detail::default_arg<HT>::f()), tail() {}
+
+  // the argument for head is not strictly needed, but it prevents
+  // array type elements. This is good, since array type elements
+  // cannot be supported properly in any case (no assignment,
+  // copy works only if the tails are exactly the same type, ...)
+
+  cons(typename access_traits<stored_head_type>::parameter_type h,
+       const tail_type& t)
+    : head (h), tail(t) {}
+
+  template <class T1, class T2, class T3, class T4, class T5,
+            class T6, class T7, class T8, class T9, class T10>
+  cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
+        T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
+    : head (t1),
+      tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
+      {}
+
+  template <class T2, class T3, class T4, class T5,
+            class T6, class T7, class T8, class T9, class T10>
+  cons( const null_type& /*t1*/, T2& t2, T3& t3, T4& t4, T5& t5,
+        T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
+    : head (),
+      tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
+      {}
+
+
+  template <class HT2, class TT2>
+  cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
+
+  template <class HT2, class TT2>
+  cons& operator=( const cons<HT2, TT2>& u ) {
+    head=u.head; tail=u.tail; return *this;
+  }
+
+  // must define assignment operator explicitly, implicit version is
+  // illformed if HT is a reference (12.8. (12))
+  cons& operator=(const cons& u) {
+    head = u.head; tail = u.tail;  return *this;
+  }
+
+  template <class T1, class T2>
+  cons& operator=( const std::pair<T1, T2>& u ) {
+    BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2
+    head = u.first; tail.head = u.second; return *this;
+  }
+
+  // get member functions (non-const and const)
+  template <int N>
+  typename access_traits<
+             typename element<N, cons<HT, TT> >::type
+           >::non_const_type
+  get() {
+    return boost::tuples::get<N>(*this); // delegate to non-member get
+  }
+
+  template <int N>
+  typename access_traits<
+             typename element<N, cons<HT, TT> >::type
+           >::const_type
+  get() const {
+    return boost::tuples::get<N>(*this); // delegate to non-member get
+  }
+};
+
+template <class HT>
+struct cons<HT, null_type> {
+
+  typedef HT head_type;
+  typedef null_type tail_type;
+  typedef cons<HT, null_type> self_type;
+
+  typedef typename
+    detail::wrap_non_storeable_type<head_type>::type stored_head_type;
+  stored_head_type head;
+
+  typename access_traits<stored_head_type>::non_const_type
+  get_head() { return head; }
+
+  null_type get_tail() { return null_type(); }
+
+  typename access_traits<stored_head_type>::const_type
+  get_head() const { return head; }
+
+  const null_type get_tail() const { return null_type(); }
+
+  //  cons() : head(detail::default_arg<HT>::f()) {}
+  cons() : head() {}
+
+  cons(typename access_traits<stored_head_type>::parameter_type h,
+       const null_type& = null_type())
+    : head (h) {}
+
+  template<class T1>
+  cons(T1& t1, const null_type&, const null_type&, const null_type&,
+       const null_type&, const null_type&, const null_type&,
+       const null_type&, const null_type&, const null_type&)
+  : head (t1) {}
+
+  cons(const null_type&,
+       const null_type&, const null_type&, const null_type&,
+       const null_type&, const null_type&, const null_type&,
+       const null_type&, const null_type&, const null_type&)
+  : head () {}
+
+  template <class HT2>
+  cons( const cons<HT2, null_type>& u ) : head(u.head) {}
+
+  template <class HT2>
+  cons& operator=(const cons<HT2, null_type>& u )
+  { head = u.head; return *this; }
+
+  // must define assignment operator explicitely, implicit version
+  // is illformed if HT is a reference
+  cons& operator=(const cons& u) { head = u.head; return *this; }
+
+  template <int N>
+  typename access_traits<
+             typename element<N, self_type>::type
+            >::non_const_type
+  get() {
+    return boost::tuples::get<N>(*this);
+  }
+
+  template <int N>
+  typename access_traits<
+             typename element<N, self_type>::type
+           >::const_type
+  get() const {
+    return boost::tuples::get<N>(*this);
+  }
+
+};
+
+// templates for finding out the length of the tuple -------------------
+
+template<class T>
+struct length  {
+  BOOST_STATIC_CONSTANT(int, value = 1 + length<typename T::tail_type>::value);
+};
+
+template<>
+struct length<tuple<> > {
+  BOOST_STATIC_CONSTANT(int, value = 0);
+};
+
+template<>
+struct length<tuple<> const> {
+  BOOST_STATIC_CONSTANT(int, value = 0);
+};
+
+template<>
+struct length<null_type> {
+  BOOST_STATIC_CONSTANT(int, value = 0);
+};
+
+template<>
+struct length<null_type const> {
+  BOOST_STATIC_CONSTANT(int, value = 0);
+};
+
+namespace detail {
+
+// Tuple to cons mapper --------------------------------------------------
+template <class T0, class T1, class T2, class T3, class T4,
+          class T5, class T6, class T7, class T8, class T9>
+struct map_tuple_to_cons
+{
+  typedef cons<T0,
+               typename map_tuple_to_cons<T1, T2, T3, T4, T5,
+                                          T6, T7, T8, T9, null_type>::type
+              > type;
+};
+
+// The empty tuple is a null_type
+template <>
+struct map_tuple_to_cons<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>
+{
+  typedef null_type type;
+};
+
+} // end detail
+
+// -------------------------------------------------------------------
+// -- tuple ------------------------------------------------------
+template <class T0, class T1, class T2, class T3, class T4,
+          class T5, class T6, class T7, class T8, class T9>
+
+class tuple :
+  public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
+{
+public:
+  typedef typename
+    detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
+  typedef typename inherited::head_type head_type;
+  typedef typename inherited::tail_type tail_type;
+
+
+// access_traits<T>::parameter_type takes non-reference types as const T&
+  tuple() {}
+
+  explicit tuple(typename access_traits<T0>::parameter_type t0)
+    : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull(), detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1)
+    : inherited(t0, t1, detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull(), detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2)
+    : inherited(t0, t1, t2, detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2,
+        typename access_traits<T3>::parameter_type t3)
+    : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull(), detail::cnull(),
+                detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2,
+        typename access_traits<T3>::parameter_type t3,
+        typename access_traits<T4>::parameter_type t4)
+    : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull(), detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2,
+        typename access_traits<T3>::parameter_type t3,
+        typename access_traits<T4>::parameter_type t4,
+        typename access_traits<T5>::parameter_type t5)
+    : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(),
+                detail::cnull(), detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2,
+        typename access_traits<T3>::parameter_type t3,
+        typename access_traits<T4>::parameter_type t4,
+        typename access_traits<T5>::parameter_type t5,
+        typename access_traits<T6>::parameter_type t6)
+    : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(),
+                detail::cnull(), detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2,
+        typename access_traits<T3>::parameter_type t3,
+        typename access_traits<T4>::parameter_type t4,
+        typename access_traits<T5>::parameter_type t5,
+        typename access_traits<T6>::parameter_type t6,
+        typename access_traits<T7>::parameter_type t7)
+    : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(),
+                detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2,
+        typename access_traits<T3>::parameter_type t3,
+        typename access_traits<T4>::parameter_type t4,
+        typename access_traits<T5>::parameter_type t5,
+        typename access_traits<T6>::parameter_type t6,
+        typename access_traits<T7>::parameter_type t7,
+        typename access_traits<T8>::parameter_type t8)
+    : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {}
+
+  tuple(typename access_traits<T0>::parameter_type t0,
+        typename access_traits<T1>::parameter_type t1,
+        typename access_traits<T2>::parameter_type t2,
+        typename access_traits<T3>::parameter_type t3,
+        typename access_traits<T4>::parameter_type t4,
+        typename access_traits<T5>::parameter_type t5,
+        typename access_traits<T6>::parameter_type t6,
+        typename access_traits<T7>::parameter_type t7,
+        typename access_traits<T8>::parameter_type t8,
+        typename access_traits<T9>::parameter_type t9)
+    : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
+
+
+  template<class U1, class U2>
+  tuple(const cons<U1, U2>& p) : inherited(p) {}
+
+  template <class U1, class U2>
+  tuple& operator=(const cons<U1, U2>& k) {
+    inherited::operator=(k);
+    return *this;
+  }
+
+  template <class U1, class U2>
+  tuple& operator=(const std::pair<U1, U2>& k) {
+    BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2
+    this->head = k.first;
+    this->tail.head = k.second;
+    return *this;
+  }
+
+};
+
+// The empty tuple
+template <>
+class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>  :
+  public null_type
+{
+public:
+  typedef null_type inherited;
+};
+
+
+// Swallows any assignment   (by Doug Gregor)
+namespace detail {
+
+struct swallow_assign;
+typedef void (detail::swallow_assign::*ignore_t)();
+struct swallow_assign {
+  swallow_assign(ignore_t(*)(ignore_t)) {}
+  template<typename T>
+  swallow_assign const& operator=(const T&) const {
+    return *this;
+  }
+};
+
+
+} // namespace detail
+
+// "ignore" allows tuple positions to be ignored when using "tie".
+inline detail::ignore_t ignore(detail::ignore_t) { return 0; }
+
+// ---------------------------------------------------------------------------
+// The call_traits for make_tuple
+// Honours the reference_wrapper class.
+
+// Must be instantiated with plain or const plain types (not with references)
+
+// from template<class T> foo(const T& t) : make_tuple_traits<const T>::type
+// from template<class T> foo(T& t) : make_tuple_traits<T>::type
+
+// Conversions:
+// T -> T,
+// references -> compile_time_error
+// reference_wrapper<T> -> T&
+// const reference_wrapper<T> -> T&
+// array -> const ref array
+
+
+template<class T>
+struct make_tuple_traits {
+  typedef T type;
+
+  // commented away, see below  (JJ)
+  //  typedef typename IF<
+  //  boost::is_function<T>::value,
+  //  T&,
+  //  T>::RET type;
+
+};
+
+// The is_function test was there originally for plain function types,
+// which can't be stored as such (we must either store them as references or
+// pointers). Such a type could be formed if make_tuple was called with a
+// reference to a function.
+// But this would mean that a const qualified function type was formed in
+// the make_tuple function and hence make_tuple can't take a function
+// reference as a parameter, and thus T can't be a function type.
+// So is_function test was removed.
+// (14.8.3. says that type deduction fails if a cv-qualified function type
+// is created. (It only applies for the case of explicitly specifying template
+// args, though?)) (JJ)
+
+template<class T>
+struct make_tuple_traits<T&> {
+  typedef typename
+     detail::generate_error<T&>::
+       do_not_use_with_reference_type error;
+};
+
+// Arrays can't be stored as plain types; convert them to references.
+// All arrays are converted to const. This is because make_tuple takes its
+// parameters as const T& and thus the knowledge of the potential
+// non-constness of actual argument is lost.
+template<class T, int n>  struct make_tuple_traits <T[n]> {
+  typedef const T (&type)[n];
+};
+
+template<class T, int n>
+struct make_tuple_traits<const T[n]> {
+  typedef const T (&type)[n];
+};
+
+template<class T, int n>  struct make_tuple_traits<volatile T[n]> {
+  typedef const volatile T (&type)[n];
+};
+
+template<class T, int n>
+struct make_tuple_traits<const volatile T[n]> {
+  typedef const volatile T (&type)[n];
+};
+
+template<class T>
+struct make_tuple_traits<reference_wrapper<T> >{
+  typedef T& type;
+};
+
+template<class T>
+struct make_tuple_traits<const reference_wrapper<T> >{
+  typedef T& type;
+};
+
+template<>
+struct make_tuple_traits<detail::ignore_t(detail::ignore_t)> {
+  typedef detail::swallow_assign type;
+};
+
+
+
+namespace detail {
+
+// a helper traits to make the make_tuple functions shorter (Vesa Karvonen's
+// suggestion)
+template <
+  class T0 = null_type, class T1 = null_type, class T2 = null_type,
+  class T3 = null_type, class T4 = null_type, class T5 = null_type,
+  class T6 = null_type, class T7 = null_type, class T8 = null_type,
+  class T9 = null_type
+>
+struct make_tuple_mapper {
+  typedef
+    tuple<typename make_tuple_traits<T0>::type,
+          typename make_tuple_traits<T1>::type,
+          typename make_tuple_traits<T2>::type,
+          typename make_tuple_traits<T3>::type,
+          typename make_tuple_traits<T4>::type,
+          typename make_tuple_traits<T5>::type,
+          typename make_tuple_traits<T6>::type,
+          typename make_tuple_traits<T7>::type,
+          typename make_tuple_traits<T8>::type,
+          typename make_tuple_traits<T9>::type> type;
+};
+
+} // end detail
+
+// -make_tuple function templates -----------------------------------
+inline tuple<> make_tuple() {
+  return tuple<>();
+}
+
+template<class T0>
+inline typename detail::make_tuple_mapper<T0>::type
+make_tuple(const T0& t0) {
+  typedef typename detail::make_tuple_mapper<T0>::type t;
+  return t(t0);
+}
+
+template<class T0, class T1>
+inline typename detail::make_tuple_mapper<T0, T1>::type
+make_tuple(const T0& t0, const T1& t1) {
+  typedef typename detail::make_tuple_mapper<T0, T1>::type t;
+  return t(t0, t1);
+}
+
+template<class T0, class T1, class T2>
+inline typename detail::make_tuple_mapper<T0, T1, T2>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2) {
+  typedef typename detail::make_tuple_mapper<T0, T1, T2>::type t;
+  return t(t0, t1, t2);
+}
+
+template<class T0, class T1, class T2, class T3>
+inline typename detail::make_tuple_mapper<T0, T1, T2, T3>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
+  typedef typename detail::make_tuple_mapper<T0, T1, T2, T3>::type t;
+  return t(t0, t1, t2, t3);
+}
+
+template<class T0, class T1, class T2, class T3, class T4>
+inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
+                  const T4& t4) {
+  typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type t;
+  return t(t0, t1, t2, t3, t4);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5>
+inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
+                  const T4& t4, const T5& t5) {
+  typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type t;
+  return t(t0, t1, t2, t3, t4, t5);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
+inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
+                  const T4& t4, const T5& t5, const T6& t6) {
+  typedef typename detail::make_tuple_mapper
+           <T0, T1, T2, T3, T4, T5, T6>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
+         class T7>
+inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
+                  const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
+  typedef typename detail::make_tuple_mapper
+           <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6, t7);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
+         class T7, class T8>
+inline typename detail::make_tuple_mapper
+  <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
+                  const T4& t4, const T5& t5, const T6& t6, const T7& t7,
+                  const T8& t8) {
+  typedef typename detail::make_tuple_mapper
+           <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
+         class T7, class T8, class T9>
+inline typename detail::make_tuple_mapper
+  <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
+make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
+                  const T4& t4, const T5& t5, const T6& t6, const T7& t7,
+                  const T8& t8, const T9& t9) {
+  typedef typename detail::make_tuple_mapper
+           <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
+}
+
+namespace detail {
+
+template<class T>
+struct tie_traits {
+  typedef T& type;
+};
+
+template<>
+struct tie_traits<ignore_t(ignore_t)> {
+  typedef swallow_assign type;
+};
+
+template<>
+struct tie_traits<void> {
+  typedef null_type type;
+};
+
+template <
+  class T0 = void, class T1 = void, class T2 = void,
+  class T3 = void, class T4 = void, class T5 = void,
+  class T6 = void, class T7 = void, class T8 = void,
+  class T9 = void
+>
+struct tie_mapper {
+  typedef
+    tuple<typename tie_traits<T0>::type,
+          typename tie_traits<T1>::type,
+          typename tie_traits<T2>::type,
+          typename tie_traits<T3>::type,
+          typename tie_traits<T4>::type,
+          typename tie_traits<T5>::type,
+          typename tie_traits<T6>::type,
+          typename tie_traits<T7>::type,
+          typename tie_traits<T8>::type,
+          typename tie_traits<T9>::type> type;
+};
+
+}
+
+// Tie function templates -------------------------------------------------
+template<class T0>
+inline typename detail::tie_mapper<T0>::type
+tie(T0& t0) {
+  typedef typename detail::tie_mapper<T0>::type t;
+  return t(t0);
+}
+
+template<class T0, class T1>
+inline typename detail::tie_mapper<T0, T1>::type
+tie(T0& t0, T1& t1) {
+  typedef typename detail::tie_mapper<T0, T1>::type t;
+  return t(t0, t1);
+}
+
+template<class T0, class T1, class T2>
+inline typename detail::tie_mapper<T0, T1, T2>::type
+tie(T0& t0, T1& t1, T2& t2) {
+  typedef typename detail::tie_mapper<T0, T1, T2>::type t;
+  return t(t0, t1, t2);
+}
+
+template<class T0, class T1, class T2, class T3>
+inline typename detail::tie_mapper<T0, T1, T2, T3>::type
+tie(T0& t0, T1& t1, T2& t2, T3& t3) {
+  typedef typename detail::tie_mapper<T0, T1, T2, T3>::type t;
+  return t(t0, t1, t2, t3);
+}
+
+template<class T0, class T1, class T2, class T3, class T4>
+inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
+tie(T0& t0, T1& t1, T2& t2, T3& t3,
+                  T4& t4) {
+  typedef typename detail::tie_mapper<T0, T1, T2, T3, T4>::type t;
+  return t(t0, t1, t2, t3, t4);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5>
+inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
+tie(T0& t0, T1& t1, T2& t2, T3& t3,
+                  T4& t4, T5& t5) {
+  typedef typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type t;
+  return t(t0, t1, t2, t3, t4, t5);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
+inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
+tie(T0& t0, T1& t1, T2& t2, T3& t3,
+                  T4& t4, T5& t5, T6& t6) {
+  typedef typename detail::tie_mapper
+           <T0, T1, T2, T3, T4, T5, T6>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
+         class T7>
+inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
+tie(T0& t0, T1& t1, T2& t2, T3& t3,
+                  T4& t4, T5& t5, T6& t6, T7& t7) {
+  typedef typename detail::tie_mapper
+           <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6, t7);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
+         class T7, class T8>
+inline typename detail::tie_mapper
+  <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
+tie(T0& t0, T1& t1, T2& t2, T3& t3,
+                  T4& t4, T5& t5, T6& t6, T7& t7,
+                  T8& t8) {
+  typedef typename detail::tie_mapper
+           <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
+}
+
+template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
+         class T7, class T8, class T9>
+inline typename detail::tie_mapper
+  <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
+tie(T0& t0, T1& t1, T2& t2, T3& t3,
+                  T4& t4, T5& t5, T6& t6, T7& t7,
+                  T8& t8, T9& t9) {
+  typedef typename detail::tie_mapper
+           <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
+  return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
+}
+
+template <class T0, class T1, class T2, class T3, class T4,
+          class T5, class T6, class T7, class T8, class T9>
+void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
+          tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
+inline void swap(null_type&, null_type&) {}
+template<class HH>
+inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
+  ::boost::swap(lhs.head, rhs.head);
+}
+template<class HH, class TT>
+inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
+  ::boost::swap(lhs.head, rhs.head);
+  ::boost::tuples::swap(lhs.tail, rhs.tail);
+}
+template <class T0, class T1, class T2, class T3, class T4,
+          class T5, class T6, class T7, class T8, class T9>
+inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
+          tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
+  typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
+  typedef typename tuple_type::inherited base;
+  ::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
+}
+
+} // end of namespace tuples
+} // end of namespace boost
+
+
+#if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
+#pragma GCC diagnostic pop
+#endif
+
+
+#endif // BOOST_TUPLE_BASIC_HPP
diff --git a/include/boost/tuple/tuple.hpp b/include/boost/tuple/tuple.hpp
new file mode 100644
index 0000000..d71e7df
--- /dev/null
+++ b/include/boost/tuple/tuple.hpp
@@ -0,0 +1,67 @@
+//  tuple.hpp - Boost Tuple Library --------------------------------------
+
+// Copyright (C) 1999, 2000 Jaakko Jarvi (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
+
+// -----------------------------------------------------------------
+
+#ifndef BOOST_TUPLE_HPP
+#define BOOST_TUPLE_HPP
+
+#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730
+// Work around a compiler bug.
+// boost::python::tuple has to be seen by the compiler before the
+// boost::tuple class template.
+namespace boost { namespace python { class tuple; }}
+#endif
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+
+// other compilers
+#include <boost/ref.hpp>
+#include <boost/tuple/detail/tuple_basic.hpp>
+
+
+namespace boost {
+
+using tuples::tuple;
+using tuples::make_tuple;
+using tuples::tie;
+#if !defined(BOOST_NO_USING_TEMPLATE)
+using tuples::get;
+#else
+//
+// The "using tuples::get" statement causes the
+// Borland compiler to ICE, use forwarding
+// functions instead:
+//
+template<int N, class HT, class TT>
+inline typename tuples::access_traits<
+                  typename tuples::element<N, tuples::cons<HT, TT> >::type
+                >::non_const_type
+get(tuples::cons<HT, TT>& c) {
+  return tuples::get<N,HT,TT>(c);
+}
+// get function for const cons-lists, returns a const reference to
+// the element. If the element is a reference, returns the reference
+// as such (that is, can return a non-const reference)
+template<int N, class HT, class TT>
+inline typename tuples::access_traits<
+                  typename tuples::element<N, tuples::cons<HT, TT> >::type
+                >::const_type
+get(const tuples::cons<HT, TT>& c) {
+  return tuples::get<N,HT,TT>(c);
+}
+
+#endif // BOOST_NO_USING_TEMPLATE
+
+} // end namespace boost
+
+
+#endif // BOOST_TUPLE_HPP
diff --git a/include/boost/tuple/tuple_comparison.hpp b/include/boost/tuple/tuple_comparison.hpp
new file mode 100644
index 0000000..0a61952
--- /dev/null
+++ b/include/boost/tuple/tuple_comparison.hpp
@@ -0,0 +1,175 @@
+// tuple_comparison.hpp -----------------------------------------------------
+//
+// Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
+// Copyright (C) 2001 Gary Powell (gary.powell@sierra.com)
+//
+// 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
+//
+// (The idea and first impl. of comparison operators was from Doug Gregor)
+
+// -----------------------------------------------------------------
+
+#ifndef BOOST_TUPLE_COMPARISON_HPP
+#define BOOST_TUPLE_COMPARISON_HPP
+
+#include <boost/tuple/tuple.hpp>
+
+// -------------------------------------------------------------
+// equality and comparison operators
+//
+// == and != compare tuples elementwise
+// <, >, <= and >= use lexicographical ordering
+//
+// Any operator between tuples of different length fails at compile time
+// No dependencies between operators are assumed
+// (i.e. !(a<b)  does not imply a>=b, a!=b does not imply a==b etc.
+// so any weirdnesses of elementary operators are respected).
+//
+// -------------------------------------------------------------
+
+
+namespace boost {
+namespace tuples {
+
+inline bool operator==(const null_type&, const null_type&) { return true; }
+inline bool operator>=(const null_type&, const null_type&) { return true; }
+inline bool operator<=(const null_type&, const null_type&) { return true; }
+inline bool operator!=(const null_type&, const null_type&) { return false; }
+inline bool operator<(const null_type&, const null_type&) { return false; }
+inline bool operator>(const null_type&, const null_type&) { return false; }
+
+
+namespace detail {
+  // comparison operators check statically the length of its operands and
+  // delegate the comparing task to the following functions. Hence
+  // the static check is only made once (should help the compiler).
+  // These functions assume tuples to be of the same length.
+
+
+template<class T1, class T2>
+inline bool eq(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() == rhs.get_head() &&
+         eq(lhs.get_tail(), rhs.get_tail());
+}
+template<>
+inline bool eq<null_type,null_type>(const null_type&, const null_type&) { return true; }
+
+template<class T1, class T2>
+inline bool neq(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() != rhs.get_head()  ||
+         neq(lhs.get_tail(), rhs.get_tail());
+}
+template<>
+inline bool neq<null_type,null_type>(const null_type&, const null_type&) { return false; }
+
+template<class T1, class T2>
+inline bool lt(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() < rhs.get_head()  ||
+          ( !(rhs.get_head() < lhs.get_head()) &&
+            lt(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool lt<null_type,null_type>(const null_type&, const null_type&) { return false; }
+
+template<class T1, class T2>
+inline bool gt(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() > rhs.get_head()  ||
+          ( !(rhs.get_head() > lhs.get_head()) &&
+            gt(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool gt<null_type,null_type>(const null_type&, const null_type&) { return false; }
+
+template<class T1, class T2>
+inline bool lte(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() <= rhs.get_head()  &&
+          ( !(rhs.get_head() <= lhs.get_head()) ||
+            lte(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool lte<null_type,null_type>(const null_type&, const null_type&) { return true; }
+
+template<class T1, class T2>
+inline bool gte(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() >= rhs.get_head()  &&
+          ( !(rhs.get_head() >= lhs.get_head()) ||
+            gte(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool gte<null_type,null_type>(const null_type&, const null_type&) { return true; }
+
+} // end of namespace detail
+
+
+// equal ----
+
+template<class T1, class T2, class S1, class S2>
+inline bool operator==(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return  detail::eq(lhs, rhs);
+}
+
+// not equal -----
+
+template<class T1, class T2, class S1, class S2>
+inline bool operator!=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::neq(lhs, rhs);
+}
+
+// <
+template<class T1, class T2, class S1, class S2>
+inline bool operator<(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::lt(lhs, rhs);
+}
+
+// >
+template<class T1, class T2, class S1, class S2>
+inline bool operator>(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::gt(lhs, rhs);
+}
+
+// <=
+template<class T1, class T2, class S1, class S2>
+inline bool operator<=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::lte(lhs, rhs);
+}
+
+// >=
+template<class T1, class T2, class S1, class S2>
+inline bool operator>=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::gte(lhs, rhs);
+}
+
+} // end of namespace tuples
+} // end of namespace boost
+
+
+#endif // BOOST_TUPLE_COMPARISON_HPP
diff --git a/include/boost/tuple/tuple_io.hpp b/include/boost/tuple/tuple_io.hpp
new file mode 100644
index 0000000..f21c7ed
--- /dev/null
+++ b/include/boost/tuple/tuple_io.hpp
@@ -0,0 +1,339 @@
+// tuple_io.hpp --------------------------------------------------------------
+
+// Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
+//               2001 Gary Powell (gary.powell@sierra.com)
+//
+// 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
+
+// ----------------------------------------------------------------------------
+
+#ifndef BOOST_TUPLE_IO_HPP
+#define BOOST_TUPLE_IO_HPP
+
+#include <istream>
+#include <ostream>
+
+#include <sstream>
+
+#include <boost/tuple/tuple.hpp>
+
+// This is ugly: one should be using twoargument isspace since whitspace can
+// be locale dependent, in theory at least.
+// not all libraries implement have the two-arg version, so we need to
+// use the one-arg one, which one should get with <cctype> but there seem
+// to be exceptions to this.
+
+#if !defined (BOOST_NO_STD_LOCALE)
+
+#include <locale> // for two-arg isspace
+
+#else
+
+#include <cctype> // for one-arg (old) isspace
+#include <ctype.h> // Metrowerks does not find one-arg isspace from cctype
+
+#endif
+
+namespace boost {
+namespace tuples {
+
+namespace detail {
+
+class format_info {
+public:
+
+   enum manipulator_type { open, close, delimiter };
+   BOOST_STATIC_CONSTANT(int, number_of_manipulators = delimiter + 1);
+private:
+
+   static int get_stream_index (int m)
+   {
+     static const int stream_index[number_of_manipulators]
+        = { std::ios::xalloc(), std::ios::xalloc(), std::ios::xalloc() };
+
+     return stream_index[m];
+   }
+
+   format_info(const format_info&);
+   format_info();
+
+
+public:
+
+   template<class CharType, class CharTrait>
+   static CharType get_manipulator(std::basic_ios<CharType, CharTrait>& i,
+                                   manipulator_type m) {
+     // The manipulators are stored as long.
+     // A valid instanitation of basic_stream allows CharType to be any POD,
+     // hence, the static_cast may fail (it fails if long is not convertible
+     // to CharType
+     CharType c = static_cast<CharType>(i.iword(get_stream_index(m)) );
+     // parentheses and space are the default manipulators
+     if (!c) {
+       switch(m) {
+         case detail::format_info::open :  c = i.widen('('); break;
+         case detail::format_info::close : c = i.widen(')'); break;
+         case detail::format_info::delimiter : c = i.widen(' '); break;
+       }
+     }
+     return c;
+   }
+
+
+   template<class CharType, class CharTrait>
+   static void set_manipulator(std::basic_ios<CharType, CharTrait>& i,
+                               manipulator_type m, CharType c) {
+     // The manipulators are stored as long.
+     // A valid instanitation of basic_stream allows CharType to be any POD,
+     // hence, the static_cast may fail (it fails if CharType is not
+     // convertible long.
+      i.iword(get_stream_index(m)) = static_cast<long>(c);
+   }
+};
+
+} // end of namespace detail
+
+template<class CharType>
+class tuple_manipulator {
+  const detail::format_info::manipulator_type mt;
+  CharType f_c;
+public:
+  explicit tuple_manipulator(detail::format_info::manipulator_type m,
+                             const char c = 0)
+     : mt(m), f_c(c) {}
+
+   template<class CharTrait>
+  void set(std::basic_ios<CharType, CharTrait> &io) const {
+     detail::format_info::set_manipulator(io, mt, f_c);
+  }
+};
+
+
+template<class CharType, class CharTrait>
+inline std::basic_ostream<CharType, CharTrait>&
+operator<<(std::basic_ostream<CharType, CharTrait>& o, const tuple_manipulator<CharType>& m) {
+  m.set(o);
+  return o;
+}
+
+template<class CharType, class CharTrait>
+inline std::basic_istream<CharType, CharTrait>&
+operator>>(std::basic_istream<CharType, CharTrait>& i, const tuple_manipulator<CharType>& m) {
+  m.set(i);
+  return i;
+}
+
+
+template<class CharType>
+inline tuple_manipulator<CharType> set_open(const CharType c) {
+   return tuple_manipulator<CharType>(detail::format_info::open, c);
+}
+
+template<class CharType>
+inline tuple_manipulator<CharType> set_close(const CharType c) {
+   return tuple_manipulator<CharType>(detail::format_info::close, c);
+}
+
+template<class CharType>
+inline tuple_manipulator<CharType> set_delimiter(const CharType c) {
+   return tuple_manipulator<CharType>(detail::format_info::delimiter, c);
+}
+
+
+
+
+
+// -------------------------------------------------------------
+// printing tuples to ostream in format (a b c)
+// parentheses and space are defaults, but can be overriden with manipulators
+// set_open, set_close and set_delimiter
+
+namespace detail {
+
+// Note: The order of the print functions is critical
+// to let a conforming compiler  find and select the correct one.
+
+
+template<class CharType, class CharTrait, class T1>
+inline std::basic_ostream<CharType, CharTrait>&
+print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, null_type>& t) {
+  return o << t.head;
+}
+
+
+template<class CharType, class CharTrait>
+inline std::basic_ostream<CharType, CharTrait>&
+print(std::basic_ostream<CharType, CharTrait>& o, const null_type&) {
+  return o;
+}
+
+template<class CharType, class CharTrait, class T1, class T2>
+inline std::basic_ostream<CharType, CharTrait>&
+print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, T2>& t) {
+
+  const CharType d = format_info::get_manipulator(o, format_info::delimiter);
+
+  o << t.head;
+
+  o << d;
+
+  return print(o, t.tail);
+}
+
+template<class CharT, class Traits, class T>
+inline bool handle_width(std::basic_ostream<CharT, Traits>& o, const T& t) {
+    std::streamsize width = o.width();
+    if(width == 0) return false;
+
+    std::basic_ostringstream<CharT, Traits> ss;
+
+    ss.copyfmt(o);
+    ss.tie(0);
+    ss.width(0);
+
+    ss << t;
+    o << ss.str();
+
+    return true;
+}
+
+
+} // namespace detail
+
+
+template<class CharType, class CharTrait>
+inline std::basic_ostream<CharType, CharTrait>&
+operator<<(std::basic_ostream<CharType, CharTrait>& o,
+           const null_type& t) {
+  if (!o.good() ) return o;
+  if (detail::handle_width(o, t)) return o;
+
+  const CharType l =
+    detail::format_info::get_manipulator(o, detail::format_info::open);
+  const CharType r =
+    detail::format_info::get_manipulator(o, detail::format_info::close);
+
+  o << l;
+  o << r;
+
+  return o;
+}
+
+template<class CharType, class CharTrait, class T1, class T2>
+inline std::basic_ostream<CharType, CharTrait>&
+operator<<(std::basic_ostream<CharType, CharTrait>& o,
+           const cons<T1, T2>& t) {
+  if (!o.good() ) return o;
+  if (detail::handle_width(o, t)) return o;
+
+  const CharType l =
+    detail::format_info::get_manipulator(o, detail::format_info::open);
+  const CharType r =
+    detail::format_info::get_manipulator(o, detail::format_info::close);
+
+  o << l;
+
+  detail::print(o, t);
+
+  o << r;
+
+  return o;
+}
+
+
+// -------------------------------------------------------------
+// input stream operators
+
+namespace detail {
+
+
+template<class CharType, class CharTrait>
+inline std::basic_istream<CharType, CharTrait>&
+extract_and_check_delimiter(
+  std::basic_istream<CharType, CharTrait> &is, format_info::manipulator_type del)
+{
+  const CharType d = format_info::get_manipulator(is, del);
+
+#if defined (BOOST_NO_STD_LOCALE)
+  const bool is_delimiter = !isspace(d);
+#elif defined ( __BORLANDC__ )
+  const bool is_delimiter = !std::use_facet< std::ctype< CharType > >
+    (is.getloc() ).is( std::ctype_base::space, d);
+#else
+  const bool is_delimiter = (!std::isspace(d, is.getloc()) );
+#endif
+
+  CharType c;
+  if (is_delimiter) {
+    is >> c;
+    if (is.good() && c!=d) {
+      is.setstate(std::ios::failbit);
+    }
+  } else {
+    is >> std::ws;
+  }
+  return is;
+}
+
+
+template<class CharType, class CharTrait, class T1>
+inline  std::basic_istream<CharType, CharTrait> &
+read (std::basic_istream<CharType, CharTrait> &is, cons<T1, null_type>& t1) {
+
+  if (!is.good()) return is;
+
+  return is >> t1.head;
+}
+
+template<class CharType, class CharTrait, class T1, class T2>
+inline std::basic_istream<CharType, CharTrait>&
+read(std::basic_istream<CharType, CharTrait> &is, cons<T1, T2>& t1) {
+
+  if (!is.good()) return is;
+
+  is >> t1.head;
+
+
+  extract_and_check_delimiter(is, format_info::delimiter);
+
+  return read(is, t1.tail);
+}
+
+} // end namespace detail
+
+
+template<class CharType, class CharTrait>
+inline std::basic_istream<CharType, CharTrait>&
+operator>>(std::basic_istream<CharType, CharTrait> &is, null_type&) {
+
+  if (!is.good() ) return is;
+
+  detail::extract_and_check_delimiter(is, detail::format_info::open);
+  detail::extract_and_check_delimiter(is, detail::format_info::close);
+
+  return is;
+}
+
+template<class CharType, class CharTrait, class T1, class T2>
+inline std::basic_istream<CharType, CharTrait>&
+operator>>(std::basic_istream<CharType, CharTrait>& is, cons<T1, T2>& t1) {
+
+  if (!is.good() ) return is;
+
+  detail::extract_and_check_delimiter(is, detail::format_info::open);
+
+  detail::read(is, t1);
+
+  detail::extract_and_check_delimiter(is, detail::format_info::close);
+
+  return is;
+}
+
+
+} // end of namespace tuples
+} // end of namespace boost
+
+#endif // BOOST_TUPLE_IO_HPP
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..437c1e7
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/html/tuple_users_guide.html">
+</head>
+<body>
+Automatic redirection failed, please go to <a href="doc/html/tuple_users_guide.html">doc/html/tuple_users_guide.html</a> 
+&nbsp;<hr>
+<p>© Copyright Beman Dawes, 2001</p>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying 
+file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy 
+at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/meta/libraries.json b/meta/libraries.json
new file mode 100644
index 0000000..0d49822
--- /dev/null
+++ b/meta/libraries.json
@@ -0,0 +1,17 @@
+{
+    "key": "tuple",
+    "name": "Tuple",
+    "authors": [
+        "Jaakko Järvi"
+    ],
+    "description": "Ease definition of functions returning multiple values, and more.",
+    "std": [
+        "tr1"
+    ],
+    "category": [
+        "Data"
+    ],
+    "maintainers": [
+        "Jaakko Jarvi <jarvi -at- cs.tamu.edu>"
+    ]
+}
diff --git a/test/Jamfile b/test/Jamfile
new file mode 100644
index 0000000..66574f6
--- /dev/null
+++ b/test/Jamfile
@@ -0,0 +1,8 @@
+
+project : requirements <library>/boost/test//boost_test_exec_monitor ;
+
+test-suite tuple : 
+    [ run tuple_test_bench.cpp ]
+    [ run io_test.cpp ]
+    [ run another_tuple_test_bench.cpp ]
+    ;
\ No newline at end of file
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..6047c49
--- /dev/null
+++ b/test/README
@@ -0,0 +1,16 @@
+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
new file mode 100644
index 0000000..15074da
--- /dev/null
+++ b/test/another_tuple_test_bench.cpp
@@ -0,0 +1,163 @@
+// Copyright (C) 1999, 2000 Jaakko Jarvi (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 <boost/test/test_tools.hpp>    // see "Header Implementation Option"
+
+#include "boost/tuple/tuple.hpp"
+
+#include <string>
+#include <utility>
+
+using namespace boost;
+using namespace boost::tuples;
+
+
+template<class T> void dummy(const T&) {}
+
+class A {}; class B {}; class C {};
+
+// A non-copyable class
+class no_copy {
+  no_copy(const no_copy&) {}
+public:
+  no_copy() {};
+};
+
+no_copy y;
+
+#ifdef E1
+tuple<no_copy> v1;  // should faild
+#endif
+
+
+#ifdef E2
+char cs[10];
+tuple<char[10]> v3;  // should fail, arrays must be stored as references
+#endif
+
+// a class without a public default constructor
+class no_def_constructor {
+  no_def_constructor() {}
+public:
+  no_def_constructor(std::string) {} // can be constructed with a string
+};
+
+void foo1() {
+
+#ifdef E3
+  dummy(tuple<no_def_constructor, no_def_constructor, no_def_constructor>()); 
+  // should fail
+
+#endif
+}
+
+void foo2() {
+// testing default values
+#ifdef E4
+  dummy(tuple<double&>()); // should fail, not defaults for references
+  dummy(tuple<const double&>()); // likewise
+#endif
+
+#ifdef E5
+  double dd = 5;
+  dummy(tuple<double&>(dd+3.14)); // should fail, temporary to non-const reference
+#endif
+}
+
+
+
+// make_tuple ------------------------------------------
+
+
+   void foo3() {
+#ifdef E7
+    std::make_pair("Doesn't","Work"); // fails
+#endif
+    //    make_tuple("Does", "Work"); // this should work
+}
+
+
+
+// - testing element access
+
+void foo4() 
+{
+  double d = 2.7; 
+  A a;
+  tuple<int, double&, const A&> t(1, d, a);
+  const tuple<int, double&, const A> ct = t;
+  (void)ct;
+#ifdef E8
+  get<0>(ct) = 5; // can't assign to const
+#endif
+
+#ifdef E9
+  get<4>(t) = A(); // can't assign to const
+#endif
+#ifdef E10
+  dummy(get<5>(ct)); // illegal index
+#endif
+}
+
+// testing copy and assignment with implicit conversions between elements
+// testing tie
+
+  class AA {};
+  class BB : public AA {};
+  struct CC { CC() {} CC(const BB& b) {} };
+  struct DD { operator CC() const { return CC(); }; };
+
+  void foo5() {
+    tuple<char, BB*, BB, DD> t;
+    (void)t;
+    tuple<char, char> aaa;
+    tuple<int, int> bbb(aaa);
+    (void)bbb;
+    //    tuple<int, AA*, CC, CC> a = t;
+    //    a = t;
+  }
+
+
+// testing tie
+// testing assignment from std::pair
+void foo7() {
+
+   tuple<int, int, float> a;
+#ifdef E11
+   a = std::make_pair(1, 2); // should fail, tuple is of length 3, not 2
+#endif
+
+    dummy(a);
+}
+
+
+
+// --------------------------------
+// ----------------------------
+int test_main(int, char *[]) {
+
+  foo1();
+  foo2();
+  foo3();
+  foo4();
+  foo5();
+
+  foo7();
+
+  return 0;
+}
diff --git a/test/io_test.cpp b/test/io_test.cpp
new file mode 100644
index 0000000..382f8cc
--- /dev/null
+++ b/test/io_test.cpp
@@ -0,0 +1,143 @@
+// Copyright (C) 1999, 2000 Jaakko Jarvi (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 <fstream>
+#include <iterator>
+#include <algorithm>
+#include <string>
+#include <iomanip>
+
+#if defined BOOST_NO_STRINGSTREAM
+#include <strstream>
+#else
+#include <sstream>
+#endif
+
+using namespace boost;
+
+#if defined BOOST_NO_STRINGSTREAM
+typedef std::ostrstream useThisOStringStream;
+typedef std::istrstream useThisIStringStream;
+#else
+typedef std::ostringstream useThisOStringStream;
+typedef std::istringstream useThisIStringStream;
+#endif
+
+int test_main(int argc, char * argv[] ) {
+   (void)argc;
+   (void)argv;
+   using boost::tuples::set_close;
+   using boost::tuples::set_open;
+   using boost::tuples::set_delimiter;
+   
+  useThisOStringStream os1;
+
+  // Set format [a, b, c] for os1
+  os1 << set_open('[');
+  os1 << set_close(']');
+  os1 << set_delimiter(',');
+  os1 << make_tuple(1, 2, 3);
+  BOOST_CHECK (os1.str() == std::string("[1,2,3]") );
+
+  {
+  useThisOStringStream os2;
+  // Set format (a:b:c) for os2; 
+  os2 << set_open('(');
+  os2 << set_close(')');
+  os2 << set_delimiter(':');
+#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+  os2 << make_tuple("TUPU", "HUPU", "LUPU", 4.5);
+  BOOST_CHECK (os2.str() == std::string("(TUPU:HUPU:LUPU:4.5)") );
+#endif
+  }
+
+  // The format is still [a, b, c] for os1
+  os1 << make_tuple(1, 2, 3);
+  BOOST_CHECK (os1.str() == std::string("[1,2,3][1,2,3]") );
+
+  // check empty tuple.
+  useThisOStringStream os3;
+  os3 << make_tuple();
+  BOOST_CHECK (os3.str() == std::string("()") );
+  os3 << set_open('[');
+  os3 << set_close(']');
+  os3 << make_tuple();
+  BOOST_CHECK (os3.str() == std::string("()[]") );
+  
+  // check width
+  useThisOStringStream os4;
+  os4 << std::setw(10) << make_tuple(1, 2, 3);
+  BOOST_CHECK (os4.str() == std::string("   (1 2 3)") );
+
+  std::ofstream tmp("temp.tmp");
+
+#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+  tmp << make_tuple("One", "Two", 3);
+#endif   
+  tmp << set_delimiter(':');
+  tmp << make_tuple(1000, 2000, 3000) << std::endl;
+
+  tmp.close();
+  
+  // When teading tuples from a stream, manipulators must be set correctly:
+  std::ifstream tmp3("temp.tmp");
+  tuple<std::string, std::string, int> j;
+
+#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+  tmp3 >> j; 
+  BOOST_CHECK (tmp3.good() ); 
+#endif
+   
+  tmp3 >> set_delimiter(':');
+  tuple<int, int, int> i;
+  tmp3 >> i; 
+  BOOST_CHECK (tmp3.good() ); 
+   
+  tmp3.close(); 
+
+
+  // reading tuple<int, int, int> in format (a b c); 
+  useThisIStringStream is1("(100 200 300)"); 
+   
+  tuple<int, int, int> ti1; 
+  BOOST_CHECK(bool(is1 >> ti1));
+  BOOST_CHECK(ti1 == make_tuple(100, 200, 300));
+
+  useThisIStringStream is2("()");
+  tuple<> ti2;
+  BOOST_CHECK(bool(is2 >> ti2));
+  useThisIStringStream is3("[]");
+  is3 >> set_open('[');
+  is3 >> set_close(']');
+  BOOST_CHECK(bool(is3 >> ti2));
+
+  // Make sure that whitespace between elements
+  // is skipped.
+  useThisIStringStream is4("(100 200 300)"); 
+   
+  BOOST_CHECK(bool(is4 >> std::noskipws >> ti1));
+  BOOST_CHECK(ti1 == make_tuple(100, 200, 300));
+
+  // Note that strings are problematic:
+  // writing a tuple on a stream and reading it back doesn't work in
+  // general. If this is wanted, some kind of a parseable string class
+  // should be used.
+  
+  return 0;
+}
+
diff --git a/test/tuple_test_bench.cpp b/test/tuple_test_bench.cpp
new file mode 100644
index 0000000..8bf756f
--- /dev/null
+++ b/test/tuple_test_bench.cpp
@@ -0,0 +1,497 @@
+// Copyright (C) 1999, 2000 Jaakko Jarvi (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 <boost/test/test_tools.hpp>    // see "Header Implementation Option"
+
+#include "boost/tuple/tuple.hpp"
+
+#include "boost/tuple/tuple_comparison.hpp"
+
+#include "boost/type_traits/is_const.hpp"
+
+#include "boost/ref.hpp"
+#include <string>
+#include <utility>
+
+using namespace boost;
+
+// ----------------------------------------------------------------------------
+// helpers 
+// ----------------------------------------------------------------------------
+
+class A {}; 
+class B {}; 
+class C {};
+
+// classes with different kinds of conversions
+class AA {};
+class BB : public AA {}; 
+struct CC { CC() {} CC(const BB&) {} };
+struct DD { operator CC() const { return CC(); }; };
+
+// something to prevent warnings for unused variables
+template<class T> void dummy(const T&) {}
+
+// no public default constructor
+class foo {
+public:
+  explicit foo(int v) : val(v) {}
+
+  bool operator==(const foo& other) const  {
+    return val == other.val;
+  }
+
+private:
+  foo() {}
+  int val;
+};
+
+// another class without a public default constructor
+class no_def_constructor {
+  no_def_constructor() {}
+public:
+  no_def_constructor(std::string) {}
+};
+
+// A non-copyable class 
+class no_copy {
+  no_copy(const no_copy&) {}
+public:
+  no_copy() {};
+};
+
+
+// ----------------------------------------------------------------------------
+// Testing different element types --------------------------------------------
+// ----------------------------------------------------------------------------
+
+
+typedef tuple<int> t1;
+
+typedef tuple<double&, const double&, const double, double*, const double*> t2;
+typedef tuple<A, int(*)(char, int), C> t3;
+typedef tuple<std::string, std::pair<A, B> > t4;
+typedef tuple<A*, tuple<const A*, const B&, C>, bool, void*> t5;
+typedef tuple<volatile int, const volatile char&, int(&)(float) > t6;
+
+# if !defined(__BORLANDC__) || __BORLAND__ > 0x0551
+typedef tuple<B(A::*)(C&), A&> t7;
+#endif
+
+// -----------------------------------------------------------------------
+// -tuple construction tests ---------------------------------------------
+// -----------------------------------------------------------------------
+
+
+no_copy y;
+tuple<no_copy&> x = tuple<no_copy&>(y); // ok
+
+char cs[10];
+tuple<char(&)[10]> v2(cs);  // ok
+
+void
+construction_test()
+{
+
+  // Note, the get function can be called without the tuples:: qualifier,
+  // as it is lifted to namespace boost with a "using tuples::get" but
+  // MSVC 6.0 just cannot find get without the namespace qualifier
+
+  tuple<int> t1;
+  BOOST_CHECK(get<0>(t1) == int());
+
+  tuple<float> t2(5.5f);
+  BOOST_CHECK(get<0>(t2) > 5.4f && get<0>(t2) < 5.6f);
+
+  tuple<foo> t3(foo(12));
+  BOOST_CHECK(get<0>(t3) == foo(12));
+
+  tuple<double> t4(t2);
+  BOOST_CHECK(get<0>(t4) > 5.4 && get<0>(t4) < 5.6);
+
+  tuple<int, float> t5;
+  BOOST_CHECK(get<0>(t5) == int());
+  BOOST_CHECK(get<1>(t5) == float());
+
+  tuple<int, float> t6(12, 5.5f);
+  BOOST_CHECK(get<0>(t6) == 12);
+  BOOST_CHECK(get<1>(t6) > 5.4f && get<1>(t6) < 5.6f);
+
+  tuple<int, float> t7(t6);
+  BOOST_CHECK(get<0>(t7) == 12);
+  BOOST_CHECK(get<1>(t7) > 5.4f && get<1>(t7) < 5.6f);
+
+  tuple<long, double> t8(t6);
+  BOOST_CHECK(get<0>(t8) == 12);
+  BOOST_CHECK(get<1>(t8) > 5.4f && get<1>(t8) < 5.6f);
+
+  dummy(
+    tuple<no_def_constructor, no_def_constructor, no_def_constructor>(
+       std::string("Jaba"),   // ok, since the default
+       std::string("Daba"),   // constructor is not used
+       std::string("Doo")
+    )
+  );
+
+// testing default values
+  dummy(tuple<int, double>());
+  dummy(tuple<int, double>(1));
+  dummy(tuple<int, double>(1,3.14));
+
+
+  //  dummy(tuple<double&>()); // should fail, not defaults for references
+  //  dummy(tuple<const double&>()); // likewise
+
+  double dd = 5;
+  dummy(tuple<double&>(dd)); // ok
+
+  dummy(tuple<const double&>(dd+3.14)); // ok, but dangerous
+
+  //  dummy(tuple<double&>(dd+3.14)); // should fail,
+  //                                  // temporary to non-const reference
+}
+
+
+// ----------------------------------------------------------------------------
+// - testing element access ---------------------------------------------------
+// ----------------------------------------------------------------------------
+
+void element_access_test()
+{
+  double d = 2.7;
+  A a;
+  tuple<int, double&, const A&, int> t(1, d, a, 2);
+  const tuple<int, double&, const A, int> ct = t;
+
+  int i  = get<0>(t);
+  int i2 = get<3>(t);
+
+  BOOST_CHECK(i == 1 && i2 == 2);
+
+  int j  = get<0>(ct);
+  BOOST_CHECK(j == 1);
+   
+  get<0>(t) = 5;
+  BOOST_CHECK(t.head == 5);
+   
+  //  get<0>(ct) = 5; // can't assign to const
+
+  double e = get<1>(t);
+  BOOST_CHECK(e > 2.69 && e < 2.71);
+     
+  get<1>(t) = 3.14+i;
+  BOOST_CHECK(get<1>(t) > 4.13 && get<1>(t) < 4.15);
+
+  //  get<4>(t) = A(); // can't assign to const
+  //  dummy(get<5>(ct)); // illegal index
+
+  ++get<0>(t);
+  BOOST_CHECK(get<0>(t) == 6);
+
+  BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<0, tuple<int, float> >::type>::value != true));
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+  BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<0, const tuple<int, float> >::type>::value));
+#endif 
+
+  BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<1, tuple<int, float> >::type>::value != true));
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+  BOOST_STATIC_ASSERT((boost::is_const<boost::tuples::element<1, const tuple<int, float> >::type>::value));
+#endif 
+
+
+  dummy(i); dummy(i2); dummy(j); dummy(e); // avoid warns for unused variables
+}
+
+
+// ----------------------------------------------------------------------------
+// - copying tuples -----------------------------------------------------------
+// ----------------------------------------------------------------------------
+
+
+
+void
+copy_test()
+{
+  tuple<int, char> t1(4, 'a');
+  tuple<int, char> t2(5, 'b');
+  t2 = t1;
+  BOOST_CHECK(get<0>(t1) == get<0>(t2));
+  BOOST_CHECK(get<1>(t1) == get<1>(t2));
+
+  tuple<long, std::string> t3(2, "a");
+  t3 = t1;
+  BOOST_CHECK((double)get<0>(t1) == get<0>(t3));
+  BOOST_CHECK(get<1>(t1) == get<1>(t3)[0]);
+
+// testing copy and assignment with implicit conversions between elements
+// testing tie
+
+  tuple<char, BB*, BB, DD> t;
+  tuple<int, AA*, CC, CC> a(t);
+  a = t;
+
+  int i; char c; double d;
+  tie(i, c, d) = make_tuple(1, 'a', 5.5);
+  
+  BOOST_CHECK(i==1);
+  BOOST_CHECK(c=='a');
+  BOOST_CHECK(d>5.4 && d<5.6);
+}
+
+void
+mutate_test()
+{
+  tuple<int, float, bool, foo> t1(5, 12.2f, true, foo(4));
+  get<0>(t1) = 6;
+  get<1>(t1) = 2.2f;
+  get<2>(t1) = false;
+  get<3>(t1) = foo(5);
+
+  BOOST_CHECK(get<0>(t1) == 6);
+  BOOST_CHECK(get<1>(t1) > 2.1f && get<1>(t1) < 2.3f);
+  BOOST_CHECK(get<2>(t1) == false);
+  BOOST_CHECK(get<3>(t1) == foo(5));
+}
+
+// ----------------------------------------------------------------------------
+// make_tuple tests -----------------------------------------------------------
+// ----------------------------------------------------------------------------
+
+void
+make_tuple_test()
+{
+  tuple<int, char> t1 = make_tuple(5, 'a');
+  BOOST_CHECK(get<0>(t1) == 5);
+  BOOST_CHECK(get<1>(t1) == 'a');
+
+  tuple<int, std::string> t2;
+  t2 = boost::make_tuple((short int)2, std::string("Hi"));
+  BOOST_CHECK(get<0>(t2) == 2);
+  BOOST_CHECK(get<1>(t2) == "Hi");
+
+
+    A a = A(); B b;
+    const A ca = a;
+    make_tuple(boost::cref(a), b);
+    make_tuple(boost::ref(a), b);
+    make_tuple(boost::ref(a), boost::cref(b));
+
+    make_tuple(boost::ref(ca));
+     
+// the result of make_tuple is assignable:
+   BOOST_CHECK(make_tuple(2, 4, 6) == 
+             (make_tuple(1, 2, 3) = make_tuple(2, 4, 6)));
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+    make_tuple("Donald", "Daisy"); // should work;
+#endif 
+    //    std::make_pair("Doesn't","Work"); // fails
+
+// You can store a reference to a function in a tuple
+    tuple<void(&)()> adf(make_tuple_test);
+
+    dummy(adf); // avoid warning for unused variable
+ 
+// But make_tuple doesn't work 
+// with function references, since it creates a const qualified function type
+
+//   make_tuple(make_tuple_test);
+  
+// With function pointers, make_tuple works just fine
+
+#if !defined(__BORLANDC__) || __BORLAND__ > 0x0551
+   make_tuple(&make_tuple_test);
+#endif
+      
+// NOTE:
+//
+// wrapping it the function reference with ref helps on gcc 2.95.2.
+// on edg 2.43. it results in a catastrophic error?
+
+// make_tuple(ref(foo3));
+
+// It seems that edg can't use implicitly the ref's conversion operator, e.g.:
+// typedef void (&func_t) (void);
+// func_t fref = static_cast<func_t>(ref(make_tuple_test)); // works fine 
+// func_t fref = ref(make_tuple_test);                        // error
+
+// This is probably not a very common situation, so currently
+// I don't know how which compiler is right (JJ)
+}
+
+void
+tie_test()
+{
+  int a;
+  char b;
+  foo c(5);
+
+  tie(a, b, c) = make_tuple(2, 'a', foo(3));
+  BOOST_CHECK(a == 2);
+  BOOST_CHECK(b == 'a');
+  BOOST_CHECK(c == foo(3));
+
+  tie(a, tuples::ignore, c) = make_tuple((short int)5, false, foo(5));
+  BOOST_CHECK(a == 5);
+  BOOST_CHECK(b == 'a');
+  BOOST_CHECK(c == foo(5));
+
+// testing assignment from std::pair
+   int i, j; 
+   tie (i, j) = std::make_pair(1, 2);
+   BOOST_CHECK(i == 1 && j == 2);
+
+   tuple<int, int, float> ta;
+#ifdef E11
+   ta = std::make_pair(1, 2); // should fail, tuple is of length 3, not 2
+#endif
+
+   dummy(ta);
+}
+
+
+// ----------------------------------------------------------------------------
+// - testing tuple equality   -------------------------------------------------
+// ----------------------------------------------------------------------------
+
+void
+equality_test()
+{
+  tuple<int, char> t1(5, 'a');
+  tuple<int, char> t2(5, 'a');
+  BOOST_CHECK(t1 == t2);
+
+  tuple<int, char> t3(5, 'b');
+  tuple<int, char> t4(2, 'a');
+  BOOST_CHECK(t1 != t3);
+  BOOST_CHECK(t1 != t4);
+  BOOST_CHECK(!(t1 != t2));
+}
+
+
+// ----------------------------------------------------------------------------
+// - testing tuple comparisons  -----------------------------------------------
+// ----------------------------------------------------------------------------
+
+void
+ordering_test()
+{
+  tuple<int, float> t1(4, 3.3f);
+  tuple<short, float> t2(5, 3.3f);
+  tuple<long, double> t3(5, 4.4);
+  BOOST_CHECK(t1 < t2);
+  BOOST_CHECK(t1 <= t2);
+  BOOST_CHECK(t2 > t1);
+  BOOST_CHECK(t2 >= t1);
+  BOOST_CHECK(t2 < t3);
+  BOOST_CHECK(t2 <= t3);
+  BOOST_CHECK(t3 > t2);
+  BOOST_CHECK(t3 >= t2);
+
+}
+
+
+// ----------------------------------------------------------------------------
+// - testing cons lists -------------------------------------------------------
+// ----------------------------------------------------------------------------
+void cons_test()
+{
+  using tuples::cons;
+  using tuples::null_type;
+
+  cons<volatile float, null_type> a(1, null_type());
+  cons<const int, cons<volatile float, null_type> > b(2,a);
+  int i = 3;
+  cons<int&, cons<const int, cons<volatile float, null_type> > > c(i, b);
+  BOOST_CHECK(make_tuple(3,2,1)==c);
+
+  cons<char, cons<int, cons<float, null_type> > > x;
+  dummy(x);
+}
+
+// ----------------------------------------------------------------------------
+// - testing const tuples -----------------------------------------------------
+// ----------------------------------------------------------------------------
+void const_tuple_test()
+{
+  const tuple<int, float> t1(5, 3.3f);
+  BOOST_CHECK(get<0>(t1) == 5);
+  BOOST_CHECK(get<1>(t1) == 3.3f);
+}
+
+// ----------------------------------------------------------------------------
+// - testing length -----------------------------------------------------------
+// ----------------------------------------------------------------------------
+void tuple_length_test()
+{
+  typedef tuple<int, float, double> t1;
+  using tuples::cons;
+  typedef cons<int, cons< float, cons <double, tuples::null_type> > > t1_cons;
+  typedef tuple<> t2;
+  typedef tuples::null_type t3;  
+
+  BOOST_STATIC_ASSERT(tuples::length<t1>::value == 3);
+  BOOST_STATIC_ASSERT(tuples::length<t1_cons>::value == 3);
+  BOOST_STATIC_ASSERT(tuples::length<t2>::value == 0);
+  BOOST_STATIC_ASSERT(tuples::length<t3>::value == 0);
+
+}
+
+// ----------------------------------------------------------------------------
+// - testing swap -----------------------------------------------------------
+// ----------------------------------------------------------------------------
+void tuple_swap_test()
+{
+  tuple<int, float, double> t1(1, 2.0f, 3.0), t2(4, 5.0f, 6.0);
+  swap(t1, t2);
+  BOOST_CHECK(get<0>(t1) == 4);
+  BOOST_CHECK(get<1>(t1) == 5.0f);
+  BOOST_CHECK(get<2>(t1) == 6.0);
+  BOOST_CHECK(get<0>(t2) == 1);
+  BOOST_CHECK(get<1>(t2) == 2.0f);
+  BOOST_CHECK(get<2>(t2) == 3.0);
+
+  int i = 1,j = 2;
+  boost::tuple<int&> t3(i), t4(j);
+  swap(t3, t4);
+  BOOST_CHECK(i == 2);
+  BOOST_CHECK(j == 1);
+}
+
+
+
+// ----------------------------------------------------------------------------
+// - main ---------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+
+int test_main(int, char *[]) {
+
+  construction_test();
+  element_access_test();
+  copy_test();
+  mutate_test();
+  make_tuple_test();
+  tie_test();
+  equality_test();
+  ordering_test();
+  cons_test();
+  const_tuple_test();
+  tuple_length_test();
+  tuple_swap_test();
+  return 0;
+}
+
+
+
+
+
+
+