diff --git a/hash/doc/Jamfile.v2 b/hash/doc/Jamfile.v2
new file mode 100644
index 0000000..7f55cd5
--- /dev/null
+++ b/hash/doc/Jamfile.v2
@@ -0,0 +1,9 @@
+
+# Copyright Daniel James 2005. Use, modification, and distribution are
+# subject to 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)
+
+using quickbook ;
+
+xml hash : hash.qbk ;
+boostbook standalone : hash ;
diff --git a/hash/doc/hash.qbk b/hash/doc/hash.qbk
new file mode 100644
index 0000000..bc5e9a9
--- /dev/null
+++ b/hash/doc/hash.qbk
@@ -0,0 +1,769 @@
+[library Boost.Hash
+ [authors [James, Daniel]]
+ [copyright 2005 Daniel James]
+ [purpose std::tr1 compliant hash function object]
+ [license
+ 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
+ )
+ ]
+]
+
+[/ QuickBook Document version 1.0 ]
+[/ Feb 8, 2005 ]
+
+[def __note__ [$images/note.png]]
+[def __alert__ [$images/alert.png]]
+[def __tip__ [$images/tip.png]]
+
+[section:intro Introduction]
+
+[def __tr1__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf
+ C++ Standard Library Technical Report]]
+[def __tr1-short__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf
+ Technical Report]]
+[def __multi-index__ [@../../libs/multi_index/doc/index.html
+ Boost Multi-Index Containers Library]]
+[def __multi-index-short__ [@../../libs/multi_index/doc/index.html
+ Boost.MultiIndex]]
+[def __issues__ [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+ Library Extension Technical Report Issues List]]
+[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
+[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
+
+[classref boost::hash] is an implementation of the __hash-function__ object
+specified by the __tr1__. It is intended for use as the default hash function
+for unordered associative containers, and the __multi-index__'s hash indexes.
+
+As it is compliant with the __tr1-short__, it will work with:
+
+* integers
+* floats
+* pointers
+* strings
+
+It also implements the extension proposed by Peter Dimov in issue 6.18 of the
+__issues__, this adds support for:
+
+* `std::pair`
+* the standard containers.
+
+The extension also allows the user to customise the hash function for
+user-defined types. Which means that you don't need to use a custom hash
+function object with a container that uses [classref boost::hash] by default.
+
+[endsect]
+
+[section:tutorial Tutorial]
+
+When using __multi-index-short__, you don't need to do anything, as it uses
+[classref boost::hash] by default. To find out how to use a user-defined type,
+read the [link section.tutorial.custom section on Extending Boost.Hash].
+
+If your standard library supplies its own implementation of the unordered
+associative containers and you wish to use
+[classref boost::hash] you just supply the extra template parameter:
+
+ std::unordered_multiset, boost::hash >
+ set_of_ints;
+
+ std::unordered_set, boost::hash >
+ set_of_pairs;
+
+ std::unordered_map > map_int_to_string;
+
+To use [classref boost::hash] directly, create an instance and call it as a function:
+
+ #include
+
+ int main()
+ {
+ boost::hash string_hash;
+
+ std::size_t h = string_hash("Hash me");
+ }
+
+If you wish to make use of the extensions, you will need to include the
+appropriate header (see the
+[link hash.reference.specification reference documentation] for the full list).
+
+ #include
+
+ int main()
+ {
+ boost::hash > pair_hash;
+
+ std::size_t h = pair_hash(std::make_pair(1, 2));
+ }
+
+Or alternatively, include `` for the full library.
+
+For an example of generic use, here is a function to generate a vector
+containing the hashes of the elements of a container:
+
+ template
+ std::vector get_hashes(Container const& x)
+ {
+ std::vector hashes;
+ std::transform(x.begin(), x.end(), std::insert_iterator(hashes),
+ boost::hash());
+
+ return hashes;
+ }
+
+[section:custom Extending Boost.Hash for a custom data type]
+
+[classref boost::hash] is implemented by calling the function
+[funcref boost::hash_value hash_value].
+The namespace isn't specified so that it can detect overloads via argument
+dependant lookup. So if there is a free function `hash_value` in the same
+namespace as a custom type, it will get called.
+
+If you have a structure `library::book`, where each `book` is uniquely
+defined by it's member `id`:
+
+ namespace library
+ {
+ struct book
+ {
+ int id;
+ std::string author;
+ std::string title;
+
+ // ....
+ };
+
+ bool operator==(book const& a, book const& b)
+ {
+ return a.id == b.id;
+ }
+ }
+
+Then all you would need to do is write the function `library::hash_value`:
+
+ namespace library
+ {
+ std::size_t hash_value(book const& b)
+ {
+ return boost::hash_value(b.id);
+ }
+ }
+
+And you can now use [classref boost::hash] with book:
+
+ library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
+ library::book dandelion(1354, "Paul J. Shanley",
+ "Hash & Dandelion Greens");
+
+ boost::hash book_hasher;
+ std::size_t knife_hash_value = book_hasher(knife);
+
+ boost::unordered_set books;
+ books.insert(knife);
+ books.insert(library::book(2443, "Lindgren, Torgny", "Hash"));
+ books.insert(library::book(1953, "Snyder, Bernadette M.",
+ "Heavenly Hash: A Tasty Mix of a Mother's Meditations"));
+
+ assert(books.find(knife) != books.end());
+ assert(books.find(dandelion) == books.end());
+
+Full code for this example is at
+[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
+
+[blurb
+When writing a hash function, first look at how the equality function works.
+Objects that are equal must generate the same hash value.
+When objects are not equal the should generate different hash values.
+In this object equality was based just on the id, if it was based
+on the objects name and author the hash function should take them into account
+(how to do this is discussed in the next section).
+]
+
+
+[endsect]
+
+[section:combine Combining hash values]
+
+Say you have a point class, representing a two dimensional location:
+
+ class point
+ {
+ int x;
+ int y;
+ public:
+ point() : x(0), y(0) {}
+ point(int x, int y) : x(x), y(y) {}
+
+ bool operator==(point const& other) const
+ {
+ return x = other.x && y == other.y;
+ }
+ };
+
+and you wish to use it as the key for an `unordered_map`. You need to
+customise the hash for this structure. To do this we need to combine
+the hash values for `x` and `y`. Boost.Hash supplies the function
+[funcref boost::hash_combine] for this purpose:
+
+ class point
+ {
+ ...
+
+ friend std::size_t hash_value(point const& p)
+ {
+ std::size_t seed = 0;
+ boost::hash_combine(seed, p.x);
+ boost::hash_combine(seed, p.y);
+
+ return seed;
+ }
+
+ ...
+ };
+
+Calls to hash_combine incrementally build the hash from the different members
+of point, it can be repeatedly called for any number of elements. It calls
+[funcref boost::hash_value hash_value] on the supplied element, and combines
+it with the seed.
+
+Full code for this example is at
+[@../../libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
+
+[blurb
+'''
+When using boost::hash_combine the order of the
+calls matters.
+
+ std::size_t seed = 0;
+ boost::hash_combine(seed, 1);
+ boost::hash_combine(seed, 2);
+
+results in a different seed to:
+
+ std::size_t seed = 0;
+ boost::hash_combine(seed, 2);
+ boost::hash_combine(seed, 1);
+
+If you are calculating a hash value for data where the order of the data
+doesn't matter in comparisons (e.g. a set) you will have to ensure that the
+data is always supplied in the same order.
+'''
+]
+
+To calculate the hash of an iterator range you can use
+[funcref boost::hash_range]:
+
+ std::vector some_strings;
+ std::size_t hash = boost::hash_range(some_strings.begin(), some_strings.end());
+
+[endsect]
+
+[endsect]
+
+[section:portability Portability]
+
+Boost.Hash is written to be as portable as possible, but unfortunately, several
+older compilers don't support argument dependent lookup (ADL) - the mechanism
+used for customization. On those compilers custom overloads for hash_value
+need to be declared in the boost namespace.
+
+On a strictly standards compliant compiler, an overload defined in the
+boost namespace won't be found when [classref boost::hash] is instantiated,
+so for these compilers the overload should only be declared in the same
+namespace as the class.
+
+Let's say we have a simple custom type:
+
+ namespace foo
+ {
+ struct custom_type
+ {
+ int value;
+
+ friend inline std::size_t hash_value(custom_type x)
+ {
+ boost::hash hasher;
+ return hasher(x.value);
+ }
+ };
+ }
+
+On a compliant compiler, when `hash_value` is called for this type,
+it will look at the namespace inside the type and find `hash_value`
+but on a compiler which doesn't support ADL `hash_value` won't be found.
+
+So on these compilers define a member function:
+
+ #ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+ friend inline std::size_t hash_value(custom_type x)
+ {
+ boost::hash hasher;
+ return hasher(x.value);
+ }
+ #else
+ std::size_t hash() const
+ {
+ boost::hash hasher;
+ return hasher(value);
+ }
+ #endif
+
+which will be called from the `boost` namespace:
+
+ #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+ namespace boost
+ {
+ std::size_t hash_value(foo::custom_type x)
+ {
+ return x.hash();
+ }
+ }
+ #endif
+
+Full code for this example is at
+[@../../libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
+
+[endsect]
+
+[/ Quickbook insists on putting a paragraph around the escaped code, which
+messes up the library section, so I wrap it in another section. This is no good,
+but there you go. ]
+
+[section:reference_ Reference]
+'''
+
+
+ For the full specification, see section 6.3 of the
+ C++ Standard Library Technical Report
+ and issue 6.18 of the
+ Library Extension Technical Report Issues List.
+
+
+
+ Includes all the following headers.
+
+
+
+ Defines boost::hash
,
+ the implementation for built in types and
+ std::string
and customisation functions.
+
+
+
+
+
+
+
+
+
+
+
+
+ std::unary_function<T, std::size_t>
+
+
+ An STL compliant hash function object.
+
+
+ std::size_t
+
+ T const&
+
+
+ hash_value(val)
+
+
+ The call to hash_value
+ is always unqualified, so that custom overloads can be
+ found via argument dependent lookup.
+
+
+ Only throws if
+ hash_value(T)
throws.
+
+
+
+
+
+
+
+
+
+ Implementation of a hash function for various types.
+
+
+
+ Should never be called directly by users, instead they should use
+ boost::hash, boost::hash_range
+ or boost::hash_combine which
+ call hash_value without namespace qualification so that overloads
+ for custom types are found via ADL.
+
+
+ Overloads for other types supplied in other headers.
+ This is an extension to TR1
+
+
+
+ std::size_t
+ int
+
+
+
+ std::size_t
+ unsigned int
+
+
+
+ std::size_t
+ long
+
+
+
+ std::size_t
+ unsigned long
+
+
+
+ std::size_t
+ float
+
+
+
+ std::size_t
+ double
+
+
+
+ std::size_t
+ long double
+
+
+
+
+ std::size_t
+ T*
+
+
+
+
+
+
+
+ std::size_t
+
+ std::basic_string<Ch, std::char_traits<Ch>, A> const&
+
+
+
+
+
+
+
+
+
+ int, unsigned int, long, unsigned long
+ v
+
+
+ float, double, long double, T*
+
+ An unspecified value, except that equal arguments shall yield the same
+ result
+
+
+
+ std::basic_string<Ch, std::char_traits<Ch>, A> const&
+ hash_range(v.begin(), v.end());
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ void
+ size_t &
+ T const &
+
+ Called repeatedly to incrementally create a hash value from
+ several variables.
+
+ seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+
+ hash_value is called without
+ qualification, so that overloads can be found via ADL.
+ This is an extension to TR1
+
+
+ Only throws if hash_value(T) throws.
+ Strong exception safety, as long as hash_value(T)
+ also has strong exception safety.
+
+
+
+
+
+
+
+
+
+
+ std::size_t
+ It
+ It
+
+
+
+
+
+
+ void
+ std::size_t&
+ It
+ It
+
+
+
+ Calculate the combined hash value of the elements of an iterator
+ range.
+
+
+size_t seed = 0;
+
+for(; first != last; ++first)
+{
+ hash_combine(seed, *first);
+}
+
+return seed;
+
+
+
+ hash_range
is sensitive to the order of the elements
+ so it wouldn't be appropriate to use this with an unordered
+ container.
+
+ This is an extension to TR1
+
+
+ Only throws if hash_value(std::iterator_traits<It>::value_type)
+ throws. hash_range(std::size_t&, It, It)
has basic exception safety as long as
+ hash_value(std::iterator_traits<It>::value_type)
+ has basic exception safety.
+
+
+
+
+
+
+
+ Hash implementation for std::pair
.
+
+
+
+
+
+
+
+
+ std::size_t
+ std::pair<A, B> const &
+
+
+size_t seed = 0;
+hash_combine(seed, val.first);
+hash_combine(seed, val.second);
+return seed;
+
+
+ Only throws if hash_value(A)
+ or hash_value(B)
throws.
+
+ This is an extension to TR1
+
+
+
+
+
+
+ Hash implementation for std::vector
.
+
+
+
+
+
+
+
+
+ std::size_t
+ std::vector<T, A> const &
+
+
+ hash_range(val.begin(), val.end());
+
+
+ Only throws if hash_value(T)
throws.
+
+ This is an extension to TR1
+
+
+
+
+
+
+ Hash implementation for std::list
.
+
+
+
+
+
+
+
+
+ std::size_t
+ std::list<T, A> const &
+
+
+ hash_range(val.begin(), val.end());
+
+
+ Only throws if hash_value(T)
throws.
+
+ This is an extension to TR1
+
+
+
+
+
+
+ Hash implementation for std::deque
.
+
+
+
+
+
+
+
+
+ std::size_t
+ std::deque<T, A> const &
+
+
+ hash_range(val.begin(), val.end());
+
+
+ Only throws if hash_value(T)
throws.
+
+ This is an extension to TR1
+
+
+
+
+
+
+ Hash implementation for std::set
and std::multiset
.
+
+
+
+
+
+
+
+
+
+ std::size_t
+ std::set<K, C, A> const &
+
+
+
+
+
+
+
+
+ std::size_t
+ std::multiset<K, C, A> const &
+
+
+ hash_range(val.begin(), val.end());
+
+
+ Only throws if hash_value(T)
throws.
+
+ This is an extension to TR1
+
+
+
+
+
+
+ Hash implementation for std::map
and std::multimap
.
+
+
+
+
+
+
+
+
+
+
+ std::size_t
+ std::map<K, T, C, A> const &
+
+
+
+
+
+
+
+
+
+ std::size_t
+ std::multimap<K, T, C, A> const &
+
+
+ hash_range(val.begin(), val.end());
+
+
+ Only throws if
+ hash_value(std::pair<K const, T>)
+ throws.
+
+ This is an extension to TR1
+
+
+
+
+'''
+[/ Remove this comment and everything goes wrong! ;) ]
+[endsect]
+
+[section:acknowledgements Acknowledgements]
+
+This library is based on the design by Peter Dimov. During the inital development
+Joaquín M López Muñoz made many useful suggestions and contributed fixes.
+
+The original implementation came from Jeremy B. Maitin-Shepard's hash table
+library, although this is a complete rewrite.
+
+[endsect]