In common.h, define func_lib for function objects. In configure.ac, define HAVE_STD_FUNCTION and HAVE_BOOST_FUNCTION. Include function headers in ndnboost.
diff --git a/libs/functional/hash/doc/Jamfile.v2 b/libs/functional/hash/doc/Jamfile.v2
new file mode 100644
index 0000000..62e2798
--- /dev/null
+++ b/libs/functional/hash/doc/Jamfile.v2
@@ -0,0 +1,19 @@
+
+# Copyright 2005-2008 Daniel James.
+# 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)
+
+using boostbook ;
+using quickbook ;
+
+xml hash : hash.qbk ;
+boostbook standalone : hash :
+ <xsl:param>boost.root=../../../../..
+
+ <xsl:param>chunk.first.sections=1
+ <xsl:param>chunk.section.depth=2
+ <xsl:param>generate.section.toc.level=2
+ <xsl:param>toc.section.depth=1
+ <xsl:param>toc.max.depth=1
+ <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/functional/hash/doc/html
+ ;
diff --git a/libs/functional/hash/doc/changes.qbk b/libs/functional/hash/doc/changes.qbk
new file mode 100644
index 0000000..4ca0814
--- /dev/null
+++ b/libs/functional/hash/doc/changes.qbk
@@ -0,0 +1,163 @@
+
+[/ Copyright 2005-2008 Daniel James.
+ / 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) ]
+
+[section:changes Change Log]
+
+[h2 Boost 1.33.0]
+
+* Initial Release
+
+[h2 Boost 1.33.1]
+
+* Fixed the points example, as pointed out by 沈慧峰.
+
+[h2 Boost 1.34.0]
+
+* Use declarations for standard classes, so that the library
+ doesn't need to include all of their headers
+* Deprecated the `<boost/functional/hash/*.hpp>` headers. Now a single header,
+ <[headerref boost/functional/hash.hpp]> is used.
+* Add support for the `BOOST_HASH_NO_EXTENSIONS` macro, which
+ disables the extensions to TR1.
+
+* Minor improvements to the hash functions for floating point numbers.
+* Update the portable example to hopefully be more generally portable.
+
+[h2 Boost 1.34.1]
+
+* [@http://svn.boost.org/trac/boost/ticket/952 Ticket 952]:
+ Suppress incorrect 64-bit warning on Visual C++.
+
+[h2 Boost 1.35.0]
+
+* Support for `long long`, `std::complex`.
+* Improved algorithm for hashing floating point numbers:
+ * Improved portablity, as described by Daniel Krügler in
+ [@http://lists.boost.org/boost-users/2005/08/13418.php
+ a post to the boost users list].
+ * Fits more information into each combine loop, which can reduce the
+ the number of times combine is called and hopefully give a better
+ quality hash function.
+ * Improved the algorithm for hashing floating point numbers.
+ * On Cygwin use a binary hash function for floating point numbers, as
+ Cygwin doesn't have decent floating point functions for `long double`.
+ * Never uses `fpclass` which doesn't support `long double`.
+ * [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]:
+ Removed unnecessary use of `errno`.
+* Explicitly overload for more built in types.
+* Minor improvements to the documentation.
+* A few bug and warning fixes:
+ * [@http://svn.boost.org/trac/boost/ticket/1509 Ticket 1509]:
+ Suppress another Visual C++ warning.
+ * Some workarounds for the Sun compilers.
+
+[h2 Boost 1.36.0]
+
+* Stop using OpenBSD's dodgy `std::numeric_limits`.
+* Using the boost typedefs for `long long` and `unsigned long long`.
+* Move the extensions into their own header.
+
+[h2 Boost 1.37.0]
+
+* [@http://svn.boost.org/trac/boost/ticket/2264 Ticket 2264]:
+ In Visual C++, always use C99 float functions for `long double` and `float` as
+ the C++ overloads aren't always availables.
+
+[h2 Boost 1.38.0]
+
+* Changed the warnings in the deprecated headers from 1.34.0 to errors. These
+ will be removed in a future version of Boost.
+* Moved detail headers out of `boost/functional/detail`, since they are part of
+ functional/hash, not functional. `boost/functional/detail/container_fwd.hpp`
+ has been moved to `boost/detail/container_fwd.hpp` as it's used outside of
+ this library, the others have been moved to `boost/functional/hash/detail`.
+
+[h2 Boost 1.39.0]
+
+* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a
+ forwarding header in the old location. You should still use the old location,
+ the new location is mainly for implementation and possible modularization.
+* [@https://svn.boost.org/trac/boost/ticket/2412 Ticket 2412]: Removed deprecated
+ headers.
+* [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration
+ for vxworks.
+
+[h2 Boost 1.40.0]
+
+* Automatically configure the float functions using template metaprogramming
+ instead of trying to configure every possibility manually.
+* Workaround for when STLport doesn't support long double.
+
+[h2 Boost 1.42.0]
+
+* Reduce the number of warnings for Visual C++ warning level 4.
+* Some code formatting changes to fit lines into 80 characters.
+* Rename an internal namespace.
+
+[h2 Boost 1.43.0]
+
+* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]:
+ Don't foward declare containers when using gcc's parallel library,
+ allow user to stop forward declaration by defining the
+ `BOOST_DETAIL_NO_CONTAINER_FWD` macro.
+* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]:
+ Avoid hashing 0.5 and 0 to the same number.
+* Stop using deprecated `BOOST_HAS_*` macros.
+
+[h2 Boost 1.44.0]
+
+* Add option to prevent implicit conversions when calling `hash_value` by
+ defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash`
+ for a type that does not have `hash_value` declared but does have
+ an implicit conversion to a type that does, it would use that
+ implicit conversion to hash it. Which can sometimes go very wrong,
+ e.g. using a conversion to bool and only hashing to 2 possible
+ values. Since fixing this is a breaking change and was only
+ approached quite late in the release cycle with little discussion
+ it's opt-in for now. This, or something like it, will become the
+ default in a future version.
+
+[h2 Boost 1.46.0]
+
+* Avoid warning due with gcc's `-Wconversion` flag.
+
+[h2 Boost 1.50.0]
+
+* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
+ Avoid gcc's `-Wfloat-equal` warning.
+* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
+ Support `std::array` and `std::tuple` when available.
+* Add deprecation warning to the long deprecated
+ `boost/functional/detail/container_fwd.hpp`.
+
+[h2 Boost 1.51.0]
+
+* Support the standard smart pointers.
+* `hash_value` now implemented using SFINAE to avoid implicit casts to built
+ in types when calling it.
+* Updated to use the new config macros.
+
+[h2 Boost 1.52.0]
+
+* Restore `enum` support, which was accidentally removed in the last version.
+* New floating point hasher - will hash the binary representation on more
+ platforms, which should be faster.
+
+[h2 Boost 1.53.0]
+
+* Add support for `boost::int128_type` and `boost::uint128_type` where
+ available - currently only `__int128` and `unsigned __int128` on some
+ versions of gcc.
+* On platforms that are known to have the standard floating point functions,
+ don't use automatic detection - which can break if there are ambiguous
+ overloads.
+* Fix undefined behaviour when using the binary float hash (Thomas Heller).
+
+[h2 Boost 1.54.0]
+
+* [@https://svn.boost.org/trac/boost/ticket/7957 Ticket 7957]:
+ Fixed a typo.
+
+[endsect]
diff --git a/libs/functional/hash/doc/disable.qbk b/libs/functional/hash/doc/disable.qbk
new file mode 100644
index 0000000..27dec6b
--- /dev/null
+++ b/libs/functional/hash/doc/disable.qbk
@@ -0,0 +1,29 @@
+
+[/ Copyright 2005-2008 Daniel James.
+ / 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) ]
+
+[section:disable Disabling The Extensions]
+
+While [classref boost::hash]'s extensions are generally useful, you might want
+to turn them of in order to check that your code will work with other
+implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
+When this macro is defined, only the specialisations detailed
+in TR1 will be declared. But, if you later undefine the macro and include
+<[headerref boost/functional/hash.hpp]> then the non-specialised form will be defined
+- activating the extensions.
+
+It is strongly recommended that you never undefine the macro - and only define
+it so that it applies to the complete translation unit, either by defining it
+at the beginning of the main source file or, preferably, by using a compiler
+switch or preference. And you really should never define it in header files.
+
+If you are writing a library which has code in the header which requires the
+extensions, then the best action is to tell users not to define the macro.
+Their code won't ['require] the macro.
+
+Translation units that are compiled with the macro defined will link with units
+that were compiled without it. This feature has been designed to avoid ODR
+violations.
+
+[endsect]
diff --git a/libs/functional/hash/doc/hash.qbk b/libs/functional/hash/doc/hash.qbk
new file mode 100644
index 0000000..cdb72d4
--- /dev/null
+++ b/libs/functional/hash/doc/hash.qbk
@@ -0,0 +1,29 @@
+[library Boost.Functional/Hash
+ [quickbook 1.5]
+ [authors [James, Daniel]]
+ [copyright 2005 2006 2007 2008 Daniel James]
+ [purpose A TR1 hash function object that can be extended to hash user
+ defined types]
+ [category higher-order]
+ [id hash]
+ [dirname functional/hash]
+ [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])
+ ]
+]
+
+[def __issues__
+ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
+ Library Extension Technical Report Issues List]]
+
+[include:hash intro.qbk]
+[include:hash tutorial.qbk]
+[include:hash portability.qbk]
+[include:hash disable.qbk]
+[include:hash changes.qbk]
+[include:hash rationale.qbk]
+[xinclude ref.xml]
+[include:hash links.qbk]
+[include:hash thanks.qbk]
diff --git a/libs/functional/hash/doc/intro.qbk b/libs/functional/hash/doc/intro.qbk
new file mode 100644
index 0000000..076e997
--- /dev/null
+++ b/libs/functional/hash/doc/intro.qbk
@@ -0,0 +1,52 @@
+
+[/ Copyright 2005-2008 Daniel James.
+ / 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) ]
+
+[section:intro Introduction]
+
+[def __tr1-full__
+ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
+ Draft Technical Report on C++ Library Extensions]]
+[def __tr1__
+ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
+ TR1]]
+[def __unordered__ [link unordered Boost.Unordered]]
+[def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]]
+[def __multi-index__ [@boost:/libs/multi_index/doc/index.html
+ Boost Multi-Index Containers Library]]
+[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
+ Boost.MultiIndex]]
+[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
+[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-full__ (TR1). It is the default hash function for
+__unordered__, __intrusive__'s unordered associative containers, and
+__multi-index-short__'s hash indicies and __bimap__'s `unordered_set_of`.
+
+As it is compliant with __tr1__, it will work with:
+
+* integers
+* floats
+* pointers
+* strings
+
+It also implements the extension proposed by Peter Dimov in issue 6.18 of the
+__issues__ (page 63), this adds support for:
+
+* arrays
+* `std::pair`
+* the standard containers.
+* extending [classref boost::hash] for custom types.
+
+[note
+This hash function is designed to be used in containers based on
+the STL and is not suitable as a general purpose hash function.
+For more details see the [link hash.rationale rationale].
+]
+
+
+[endsect]
+
diff --git a/libs/functional/hash/doc/links.qbk b/libs/functional/hash/doc/links.qbk
new file mode 100644
index 0000000..405536e
--- /dev/null
+++ b/libs/functional/hash/doc/links.qbk
@@ -0,0 +1,27 @@
+
+[/ Copyright 2005-2008 Daniel James.
+ / 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) ]
+
+[section:links Links]
+
+[*A Proposal to Add Hash Tables to the Standard Library]
+[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html]
+The hash table proposal explains much of the design. The hash function object
+is discussed in Section D.
+
+[*The C++ Standard Library Technical Report.]
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf]
+Contains the hash function specification in section 6.3.2.
+
+[*Library Extension Technical Report Issues List.]
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf]
+The library implements the extension described in Issue 6.18, pages 63-67.
+
+[*Methods for Identifying Versioned and Plagiarised Documents]
+Timothy C. Hoad, Justin Zobel
+[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf]
+Contains the hash function that [funcref boost::hash_combine] is based on.
+
+[endsect]
+
diff --git a/libs/functional/hash/doc/portability.qbk b/libs/functional/hash/doc/portability.qbk
new file mode 100644
index 0000000..a65bc19
--- /dev/null
+++ b/libs/functional/hash/doc/portability.qbk
@@ -0,0 +1,93 @@
+
+[/ Copyright 2005-2008 Daniel James.
+ / 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) ]
+
+[section:portability Portability]
+
+[def __boost_hash__ [classref boost::hash]]
+
+__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 customisation. On those compilers custom overloads for `hash_value`
+needs 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 __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
+ {
+ template <class T>
+ class custom_type
+ {
+ T value;
+ public:
+ custom_type(T x) : value(x) {}
+
+ friend std::size_t hash_value(custom_type x)
+ {
+ __boost_hash__<int> 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.
+To make things worse, some compilers which do support ADL won't find
+a friend class defined inside the class.
+
+So first move the member function out of the class:
+
+ namespace foo
+ {
+ template <class T>
+ class custom_type
+ {
+ T value;
+ public:
+ custom_type(T x) : value(x) {}
+
+ std::size_t hash(custom_type x)
+ {
+ __boost_hash__<T> hasher;
+ return hasher(value);
+ }
+ };
+
+ template <class T>
+ inline std::size_t hash_value(custom_type<T> x)
+ {
+ return x.hash();
+ }
+ }
+
+Unfortunately, I couldn't declare hash_value as a friend, as some compilers
+don't support template friends, so instead I declared a member function to
+calculate the hash, and called it from hash_value.
+
+For compilers which don't support ADL, hash_value needs to be defined in the
+boost namespace:
+
+ #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+ namespace boost
+ #else
+ namespace foo
+ #endif
+ {
+ template <class T>
+ std::size_t hash_value(foo::custom_type<T> x)
+ {
+ return x.hash();
+ }
+ }
+
+Full code for this example is at
+[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
+
+[endsect]
diff --git a/libs/functional/hash/doc/rationale.qbk b/libs/functional/hash/doc/rationale.qbk
new file mode 100644
index 0000000..8621081
--- /dev/null
+++ b/libs/functional/hash/doc/rationale.qbk
@@ -0,0 +1,50 @@
+
+[/ Copyright 2011 Daniel James.
+ / 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) ]
+
+[section:rationale Rationale]
+
+The rationale can be found in the original design
+[footnote issue 6.18 of the __issues__ (page 63)].
+
+[heading Quality of the hash function]
+
+Many hash functions strive to have little correlation between the input
+and output values. They attempt to uniformally distribute the output
+values for very similar inputs. This hash function makes no such
+attempt. In fact, for integers, the result of the hash function is often
+just the input value. So similar but different input values will often
+result in similar but different output values.
+This means that it is not appropriate as a general hash function. For
+example, a hash table may discard bits from the hash function resulting
+in likely collisions, or might have poor collision resolution when hash
+values are clustered together. In such cases this hash function will
+preform poorly.
+
+But the standard has no such requirement for the hash function,
+it just requires that the hashes of two different values are unlikely
+to collide. Containers or algorithms
+designed to work with the standard hash function will have to be
+implemented to work well when the hash function's output is correlated
+to its input. Since they are paying that cost a higher quality hash function
+would be wasteful.
+
+For other use cases, if you do need a higher quality hash function,
+then neither the standard hash function or `boost::hash` are appropriate.
+There are several options
+available. One is to use a second hash on the output of this hash
+function, such as [@http://www.concentric.net/~ttwang/tech/inthash.htm
+Thomas Wang's hash function]. This this may not work as
+well as a hash algorithm tailored for the input.
+
+For strings there are several fast, high quality hash functions
+available (for example [@http://code.google.com/p/smhasher/ MurmurHash3]
+and [@http://code.google.com/p/cityhash/ Google's CityHash]),
+although they tend to be more machine specific.
+These may also be appropriate for hashing a binary representation of
+your data - providing that all equal values have an equal
+representation, which is not always the case (e.g. for floating point
+values).
+
+[endsect]
diff --git a/libs/functional/hash/doc/ref.xml b/libs/functional/hash/doc/ref.xml
new file mode 100644
index 0000000..d7c427c
--- /dev/null
+++ b/libs/functional/hash/doc/ref.xml
@@ -0,0 +1,883 @@
+
+<!--
+Copyright Daniel James 2005-2009
+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-reference>
+ <section id="hash.reference.specification">
+ <para>For the full specification, see section 6.3 of the
+ <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C++ Standard Library Technical Report</ulink>
+ and issue 6.18 of the
+ <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63).
+ </para>
+ </section>
+ <header name="boost/functional/hash.hpp">
+ <para>
+ Defines <code><classname>boost::hash</classname></code>,
+ and helper functions.
+ </para>
+
+ <namespace name="boost">
+
+ <!--
+ boost::hash
+ -->
+
+ <struct name="hash">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+
+ <inherit access="public">
+ <classname>std::unary_function<T, std::size_t></classname>
+ </inherit>
+
+ <purpose><simpara>A <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</ulink> compliant hash function object.</simpara></purpose>
+
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>T const&</paramtype>
+ </parameter>
+ <returns><para>
+ <programlisting><functionname>hash_value</functionname>(val)</programlisting>
+ </para></returns>
+ <notes>
+ <para>
+ The call to <code><functionname>hash_value</functionname></code>
+ is unqualified, so that custom overloads can be
+ found via argument dependent lookup.
+ </para>
+ <para>
+ This is not defined when the macro <code>BOOST_HASH_NO_EXTENSIONS</code>
+ is defined. The specializations are still defined, so only the specializations
+ required by TR1 are defined.
+ </para>
+ <para>
+ Forward declared in
+ <code><boost/functional/hash_fwd.hpp></code>
+ </para>
+ </notes>
+ <throws><para>
+ Only throws if
+ <code><functionname>hash_value</functionname>(T)</code> throws.
+ </para></throws>
+ </method>
+ </struct>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>bool</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>bool</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>char</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>char</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>signed char</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>signed char</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>unsigned char</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>unsigned char</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>wchar_t</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>wchar_t</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>short</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>short</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>unsigned short</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>unsigned short</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>int</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>int</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>unsigned int</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>unsigned int</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>long</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>long</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>unsigned long</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>unsigned long</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>long long</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>long long</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>unsigned long long</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>unsigned long long</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>float</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>float</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>double</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>double</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>long double</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>long double</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>std::string</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>std::string const&</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>std::wstring</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>std::wstring const&</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ <para><functionname>hash_value</functionname>(val) in Boost.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <specialization>
+ <template-arg>T*</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>T*</paramtype>
+ </parameter>
+ <returns>
+ <para>Unspecified in TR1, except that equal arguments yield the same result.</para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ </struct-specialization>
+
+ <struct-specialization name="hash">
+ <template></template>
+ <specialization>
+ <template-arg>std::type_index</template-arg>
+ </specialization>
+ <method name="operator()" cv="const">
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>std::type_index</paramtype>
+ </parameter>
+ <returns>
+ <para><code>val.hash_code()</code></para>
+ </returns>
+ <throws><para>Doesn't throw</para></throws>
+ </method>
+ <notes>
+ <para>
+ Only available if it's in your standard library and Boost.Config
+ is aware of it.
+ </para>
+ </notes>
+ </struct-specialization>
+
+ <free-function-group name="Support functions (Boost extension).">
+
+ <!--
+ boost::hash_combine
+ -->
+
+ <function name="hash_combine">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type>void</type>
+ <parameter name="seed"><paramtype>size_t &</paramtype></parameter>
+ <parameter name="v"><paramtype>T const&</paramtype></parameter>
+ <purpose><simpara>
+ Called repeatedly to incrementally create a hash value from
+ several variables.
+ </simpara></purpose>
+ <effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);</programlisting></effects>
+ <notes>
+ <para><functionname>hash_value</functionname> is called without
+ qualification, so that overloads can be found via ADL.</para>
+ <para>This is an extension to TR1</para>
+ <para>
+ Forward declared in
+ <code><boost/functional/hash_fwd.hpp></code>
+ </para>
+ </notes>
+ <throws>
+ Only throws if <functionname>hash_value</functionname>(T) throws.
+ Strong exception safety, as long as <functionname>hash_value</functionname>(T)
+ also has strong exception safety.
+ </throws>
+ </function>
+
+ <!--
+ boost::hash_range
+ -->
+
+ <overloaded-function name="hash_range">
+ <signature>
+ <template>
+ <template-type-parameter name="It"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="first"><paramtype>It</paramtype></parameter>
+ <parameter name="last"><paramtype>It</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="It"/>
+ </template>
+ <type>void</type>
+ <parameter name="seed"><paramtype>std::size_t&</paramtype></parameter>
+ <parameter name="first"><paramtype>It</paramtype></parameter>
+ <parameter name="last"><paramtype>It</paramtype></parameter>
+ </signature>
+
+ <purpose><simpara>
+ Calculate the combined hash value of the elements of an iterator
+ range.
+ </simpara></purpose>
+ <effects>
+ <para>For the two argument overload:
+<programlisting>
+size_t seed = 0;
+
+for(; first != last; ++first)
+{
+ <functionname>hash_combine</functionname>(seed, *first);
+}
+
+return seed;
+</programlisting>
+ </para>
+ <para>For the three arguments overload:</para>
+<programlisting>
+for(; first != last; ++first)
+{
+ <functionname>hash_combine</functionname>(seed, *first);
+}
+</programlisting>
+ </effects>
+ <notes>
+ <para>
+ <code>hash_range</code> is sensitive to the order of the elements
+ so it wouldn't be appropriate to use this with an unordered
+ container.
+ </para>
+ <para>This is an extension to TR1</para>
+ <para>
+ Forward declared in
+ <code><boost/functional/hash_fwd.hpp></code>
+ </para>
+ </notes>
+ <throws><para>
+ Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits<It>::value_type)</code>
+ throws. <code>hash_range(std::size_t&, It, It)</code> has basic exception safety as long as
+ <code><functionname>hash_value</functionname>(std::iterator_traits<It>::value_type)</code>
+ has basic exception safety.
+ </para></throws>
+ </overloaded-function>
+
+ </free-function-group>
+
+ <free-function-group name="Overloadable hash implementation (Boost extension).">
+
+ <!--
+ boost::hash_value - integers
+ -->
+
+ <overloaded-function name="hash_value">
+ <purpose><simpara>
+ Implementation of the hash function.
+ </simpara></purpose>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>bool</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>char</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>signed char</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>unsigned char</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>wchar_t</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>short</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>unsigned short</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>int</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>unsigned int</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>long</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>unsigned long</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>long long</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>unsigned long long</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>float</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>double</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>long double</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template><template-type-parameter name="T"/></template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>T* const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ <template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
+ </template>
+ <type>std::size_t</type>
+ <parameter><paramtype>T (&val)[N]</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ <template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
+ </template>
+ <type>std::size_t</type>
+ <parameter><paramtype>const T (&val)[N]</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="Ch"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val">
+ <paramtype>std::basic_string<Ch, std::char_traits<Ch>, A> const&</paramtype>
+ </parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="A"/>
+ <template-type-parameter name="B"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::pair<A, B> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::vector<T, A> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::list<T, A> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::deque<T, A> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="K"/>
+ <template-type-parameter name="C"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::set<K, C, A> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="K"/>
+ <template-type-parameter name="C"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::multiset<K, C, A> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="K"/>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="C"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::map<K, T, C, A> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="K"/>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="C"/>
+ <template-type-parameter name="A"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::multimap<K, T, C, A> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::complex<T> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::type_index</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ <template-nontype-parameter name="N">
+ <type>std::size_t</type>
+ </template-nontype-parameter>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::array<T, N> const&</paramtype></parameter>
+ </signature>
+
+ <signature>
+ <template>
+ <template-type-parameter name="T" pack="1"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::tuple<T...></paramtype></parameter>
+ </signature>
+
+ <description><para>
+ Generally shouldn't be called directly by users, instead they should use
+ <classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
+ or <functionname>boost::hash_combine</functionname> which
+ call <code>hash_value</code> without namespace qualification so that overloads
+ for custom types are found via ADL.
+ </para></description>
+
+ <notes>
+ <para>This is an extension to TR1</para>
+ </notes>
+
+ <throws>
+ Only throws if a user supplied version of
+ <code><functionname>hash_value</functionname></code>
+ throws for an element of a container, or
+ one of the types stored in a pair.
+ </throws>
+
+ <returns>
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Types</entry>
+ <entry>Returns</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><code>bool</code>,
+ <code>char</code>, <code>signed char</code>, <code>unsigned char</code>, <code>wchar_t</code>,
+ <code>short</code>, <code>unsigned short</code>,
+ <code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
+ </entry>
+ <entry><code>val</code></entry>
+ </row>
+ <row>
+ <entry><code>long long</code>, <code>unsigned long long</code></entry>
+ <entry><code>val</code> when <code>abs(val) <= std::numeric_limits<std::size_t>::max()</code>.</entry>
+ </row>
+ <row>
+ <entry><code>float</code>, <code>double</code>, <code>long double</code></entry>
+ <entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
+ </row>
+ <row>
+ <entry><code>T*</code></entry>
+ <entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
+ </row>
+ <row>
+ <entry>
+ <code>T val[N]</code>,
+ <code>const T val[N]</code>
+ </entry>
+ <entry><code>hash_range(val, val+N)</code></entry>
+ </row>
+ <row>
+ <entry>
+ <code>std:basic_string<Ch, std::char_traits<Ch>, A></code>,
+ <code>std::vector<T, A></code>,
+ <code>std::list<T, A></code>,
+ <code>std::deque<T, A></code>,
+ <code>std::set<K, C, A></code>,
+ <code>std::multiset<K, C, A></code>,
+ <code>std::map<K, T, C, A></code>,
+ <code>std::multimap<K, T, C, A></code>,
+ <code>std::array<T, N></code>
+ </entry>
+ <entry><code>hash_range(val.begin(), val.end())</code></entry>
+ </row>
+ <row>
+ <entry><code>std::pair<A, B></code></entry>
+ <entry><programlisting>size_t seed = 0;
+<functionname>hash_combine</functionname>(seed, val.first);
+<functionname>hash_combine</functionname>(seed, val.second);
+return seed;</programlisting></entry>
+ </row>
+ <row>
+ <entry><code>std::tuple<T...></code></entry>
+ <entry><programlisting>size_t seed = 0;
+<functionname>hash_combine</functionname>(seed, get<0>(val));
+<functionname>hash_combine</functionname>(seed, get<1>(val));
+// ....
+return seed;</programlisting></entry>
+ </row>
+ <row>
+ <entry>
+ <code>std::complex<T></code>
+ </entry>
+ <entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
+ </row>
+ <row>
+ <entry>
+ <code>std::type_index</code>
+ </entry>
+ <entry><code>val.hash_code()</code></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </returns>
+ </overloaded-function>
+ </free-function-group>
+ </namespace>
+ </header>
+</library-reference>
+
diff --git a/libs/functional/hash/doc/thanks.qbk b/libs/functional/hash/doc/thanks.qbk
new file mode 100644
index 0000000..fcc5108
--- /dev/null
+++ b/libs/functional/hash/doc/thanks.qbk
@@ -0,0 +1,28 @@
+
+[/ Copyright 2005-2008 Daniel James.
+ / 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) ]
+
+[section:acknowledgements Acknowledgements]
+
+This library is based on the design by Peter Dimov. During the initial
+development
+Joaquín M López Muñoz made many useful suggestions and contributed fixes.
+
+The formal review was managed by Thorsten Ottosen, and the library reviewed by:
+David Abrahams, Alberto Barbati, Topher Cooper, Caleb Epstein, Dave Harris,
+Chris Jefferson, Bronek Kozicki, John Maddock, Tobias Swinger, Jaap Suter,
+Rob Stewart and Pavel Vozenilek. Since then, further constructive criticism has
+been made by Daniel Krügler, Alexander Nasonov and 沈慧峰.
+
+The implementation of the hash function for pointers is based on suggestions
+made by Alberto Barbati and Dave Harris. Dave Harris also suggested an
+important improvement to [funcref boost::hash_combine] that was taken up.
+
+Some useful improvements to the floating point hash algorithm were suggested
+by Daniel Krügler.
+
+The original implementation came from Jeremy B. Maitin-Shepard's hash table
+library, although this is a complete rewrite.
+
+[endsect]
diff --git a/libs/functional/hash/doc/tutorial.qbk b/libs/functional/hash/doc/tutorial.qbk
new file mode 100644
index 0000000..59067a7
--- /dev/null
+++ b/libs/functional/hash/doc/tutorial.qbk
@@ -0,0 +1,212 @@
+
+[/ Copyright 2005-2008 Daniel James.
+ / 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) ]
+
+[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
+ Boost.MultiIndex]]
+
+[section:tutorial Tutorial]
+
+When using a hash index with __multi-index-short__, you don't need to do
+anything to use [classref boost::hash] as it uses it by default.
+To find out how to use a user-defined type, read the
+[link hash.custom section on extending boost::hash for a custom data type].
+
+If your standard library supplies its own implementation of the unordered
+associative containers and you wish to use
+[classref boost::hash], just use an extra template parameter:
+
+ std::unordered_multiset<int, ``[classref boost::hash]``<int> >
+ set_of_ints;
+
+ std::unordered_set<std::pair<int, int>, ``[classref boost::hash]``<std::pair<int, int> >
+ set_of_pairs;
+
+ std::unordered_map<int, std::string, ``[classref boost::hash]``<int> > map_int_to_string;
+
+To use [classref boost::hash] directly, create an instance and call it as a function:
+
+ #include <``[headerref boost/functional/hash.hpp]``>
+
+ int main()
+ {
+ ``[classref boost::hash]``<std::string> string_hash;
+
+ std::size_t h = string_hash("Hash me");
+ }
+
+For an example of generic use, here is a function to generate a vector
+containing the hashes of the elements of a container:
+
+ template <class Container>
+ std::vector<std::size_t> get_hashes(Container const& x)
+ {
+ std::vector<std::size_t> hashes;
+ std::transform(x.begin(), x.end(), std::insert_iterator(hashes),
+ ``[classref boost::hash]``<typename Container::value_type>());
+
+ return hashes;
+ }
+
+[endsect]
+
+[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)
+ {
+ ``[classref boost::hash]``<int> hasher;
+ return hasher(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");
+
+ ``[classref boost::hash]``<library::book> book_hasher;
+ std::size_t knife_hash_value = book_hasher(knife);
+
+ // If std::unordered_set is available:
+ std::unordered_set<library::book, ``[classref boost::hash]``<library::book> > 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());
+
+The full example can be found in:
+[@boost:/libs/functional/hash/examples/books.hpp /libs/functional/hash/examples/books.hpp]
+and
+[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
+
+[tip
+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 they should generate different hash values.
+In this object equality was based just on the id so the hash function
+only hashes the id. If it was based on the object's name and author
+then 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`. The function
+[funcref boost::hash_combine] is supplied for this purpose:
+
+ class point
+ {
+ ...
+
+ friend std::size_t hash_value(point const& p)
+ {
+ std::size_t seed = 0;
+ ``[funcref boost::hash_combine]``(seed, p.x);
+ ``[funcref 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
+[@boost:/libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
+
+[note
+When using [funcref boost::hash_combine] the order of the
+calls matters.
+'''
+<programlisting>
+ std::size_t seed = 0;
+ boost::hash_combine(seed, 1);
+ boost::hash_combine(seed, 2);
+</programlisting>
+results in a different seed to:
+<programlisting>
+ std::size_t seed = 0;
+ boost::hash_combine(seed, 2);
+ boost::hash_combine(seed, 1);
+</programlisting>
+'''
+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<std::string> some_strings;
+ std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
+
+Note that when writing template classes, you might not want to include the main
+hash header as it's quite an expensive include that brings in a lot of other
+headers, so instead you can include the `<boost/functional/hash_fwd.hpp>`
+header which forward declares [classref boost::hash],
+[funcref boost::hash_range] and [funcref boost::hash_combine]. You'll need to
+include the main header before instantiating [classref boost::hash]. When using
+a container that uses [classref boost::hash] it should do that for you, so your
+type will work fine with the boost hash containers. There's an example of this
+in [@boost:/libs/functional/hash/examples/template.hpp template.hpp] and
+[@boost:/libs/functional/hash/examples/template.cpp template.cpp].
+
+[endsect]
diff --git a/libs/functional/hash/examples/Jamfile.v2 b/libs/functional/hash/examples/Jamfile.v2
new file mode 100644
index 0000000..6291621
--- /dev/null
+++ b/libs/functional/hash/examples/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)
+
+run books.cpp ;
+run point.cpp ;
+run portable.cpp ;
+run template.cpp ;
diff --git a/libs/functional/hash/examples/books.cpp b/libs/functional/hash/examples/books.cpp
new file mode 100644
index 0000000..8802e0e
--- /dev/null
+++ b/libs/functional/hash/examples/books.cpp
@@ -0,0 +1,51 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./books.hpp"
+#include <boost/functional/hash.hpp>
+#include <cassert>
+
+// If std::unordered_set was available:
+//#include <unordered_set>
+
+// This example illustrates how to use ndnboost::hash with a custom hash function.
+// For full details, see the tutorial.
+
+int main()
+{
+ library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
+ library::book dandelion(1354, "Paul J. Shanley", "Hash & Dandelion Greens");
+
+ ndnboost::hash<library::book> book_hasher;
+ std::size_t knife_hash_value = book_hasher(knife);
+ (void)knife_hash_value; // suppress unused variable warning
+
+ // If std::unordered_set was available:
+ //
+ //std::unordered_set<library::book, ndnboost::hash<library::book> > 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());
+
+ return 0;
+}
+
+namespace library
+{
+ bool operator==(book const& a, book const& b)
+ {
+ return a.id == b.id;
+ }
+
+ std::size_t hash_value(book const& b)
+ {
+ ndnboost::hash<int> hasher;
+ return hasher(b.id);
+ }
+}
diff --git a/libs/functional/hash/examples/books.hpp b/libs/functional/hash/examples/books.hpp
new file mode 100644
index 0000000..195a798
--- /dev/null
+++ b/libs/functional/hash/examples/books.hpp
@@ -0,0 +1,26 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+// This example illustrates how to use ndnboost::hash with a custom hash function.
+// The implementation is contained in books.cpp
+
+#include <cstddef>
+#include <string>
+
+namespace library
+{
+ struct book
+ {
+ int id;
+ std::string author;
+ std::string title;
+
+ book(int i, std::string const& a, std::string const& t)
+ : id(i), author(a), title(t) {}
+ };
+
+ bool operator==(book const&, book const&);
+ std::size_t hash_value(book const&);
+}
diff --git a/libs/functional/hash/examples/point.cpp b/libs/functional/hash/examples/point.cpp
new file mode 100644
index 0000000..b36e3e2
--- /dev/null
+++ b/libs/functional/hash/examples/point.cpp
@@ -0,0 +1,54 @@
+
+// Copyright 2005 Daniel James.
+// 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)
+
+#include <boost/functional/hash.hpp>
+#include <cassert>
+
+// This example illustrates how to use ndnboost::hash_combine to generate a hash
+// value from the different members of a class. For full details see the hash
+// tutorial.
+
+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;
+ }
+
+ friend std::size_t hash_value(point const& p)
+ {
+ std::size_t seed = 0;
+ ndnboost::hash_combine(seed, p.x);
+ ndnboost::hash_combine(seed, p.y);
+
+ return seed;
+ }
+};
+
+int main()
+{
+ ndnboost::hash<point> point_hasher;
+
+ point p1(0, 0);
+ point p2(1, 2);
+ point p3(4, 1);
+ point p4 = p1;
+
+ assert(point_hasher(p1) == point_hasher(p4));
+
+ // These tests could legally fail, but if they did it'd be a pretty bad
+ // hash function.
+ assert(point_hasher(p1) != point_hasher(p2));
+ assert(point_hasher(p1) != point_hasher(p3));
+
+ return 0;
+}
+
diff --git a/libs/functional/hash/examples/portable.cpp b/libs/functional/hash/examples/portable.cpp
new file mode 100644
index 0000000..94b2e0e
--- /dev/null
+++ b/libs/functional/hash/examples/portable.cpp
@@ -0,0 +1,54 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include <boost/functional/hash.hpp>
+#include <cassert>
+
+// This example illustrates how to customise ndnboost::hash portably, so that
+// it'll work on both compilers that don't implement argument dependent lookup
+// and compilers that implement strict two-phase template instantiation.
+
+namespace foo
+{
+ template <class T>
+ class custom_type
+ {
+ T value;
+ public:
+ custom_type(T x) : value(x) {}
+
+ std::size_t hash() const
+ {
+ ndnboost::hash<T> hasher;
+ return hasher(value);
+ }
+ };
+}
+
+#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+namespace ndnboost
+#else
+namespace foo
+#endif
+{
+ template <class T>
+ std::size_t hash_value(foo::custom_type<T> x)
+ {
+ return x.hash();
+ }
+}
+
+int main()
+{
+ foo::custom_type<int> x(1), y(2), z(1);
+
+ ndnboost::hash<foo::custom_type<int> > hasher;
+
+ assert(hasher(x) == hasher(x));
+ assert(hasher(x) != hasher(y));
+ assert(hasher(x) == hasher(z));
+
+ return 0;
+}
diff --git a/libs/functional/hash/examples/template.cpp b/libs/functional/hash/examples/template.cpp
new file mode 100644
index 0000000..d58ef5c
--- /dev/null
+++ b/libs/functional/hash/examples/template.cpp
@@ -0,0 +1,18 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+#include "template.hpp"
+#include <cassert>
+#include <boost/unordered_set.hpp>
+
+int main()
+{
+ typedef my_pair<int, float> pair;
+ ndnboost::unordered_set<pair> pair_set;
+ pair_set.emplace(10, 0.5f);
+
+ assert(pair_set.find(pair(10, 0.5f)) != pair_set.end());
+ assert(pair_set.find(pair(10, 0.6f)) == pair_set.end());
+}
diff --git a/libs/functional/hash/examples/template.hpp b/libs/functional/hash/examples/template.hpp
new file mode 100644
index 0000000..1817a9d
--- /dev/null
+++ b/libs/functional/hash/examples/template.hpp
@@ -0,0 +1,36 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+// This is an example of how to write a hash function for a template
+// class.
+
+#include <boost/functional/hash_fwd.hpp>
+
+template <typename A, typename B>
+class my_pair
+{
+ A value1;
+ B value2;
+public:
+ my_pair(A const& v1, B const& v2)
+ : value1(v1), value2(v2)
+ {}
+
+ bool operator==(my_pair const& other) const
+ {
+ return value1 == other.value1 &&
+ value2 == other.value2;
+ }
+
+ friend std::size_t hash_value(my_pair const& p)
+ {
+ std::size_t seed = 0;
+ ndnboost::hash_combine(seed, p.value1);
+ ndnboost::hash_combine(seed, p.value2);
+
+ return seed;
+ }
+};
+
diff --git a/libs/functional/hash/index.html b/libs/functional/hash/index.html
new file mode 100644
index 0000000..12b5757
--- /dev/null
+++ b/libs/functional/hash/index.html
@@ -0,0 +1,16 @@
+
+<!--
+Copyright 2005-2007 Daniel James.
+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)
+-->
+
+<html>
+<head>
+ <meta http-equiv="refresh" content="0; URL=../../../doc/html/hash.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../../../doc/html/hash.html">../../../doc/html/hash.html</a>
+</body>
+</html>
diff --git a/libs/functional/hash/test/Jamfile.v2 b/libs/functional/hash/test/Jamfile.v2
new file mode 100755
index 0000000..2767bf3
--- /dev/null
+++ b/libs/functional/hash/test/Jamfile.v2
@@ -0,0 +1,81 @@
+
+# Copyright 2005-2012 Daniel James.
+# 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)
+
+import testing ;
+
+project hash-tests
+ : requirements
+ <warnings>all
+ <toolset>intel:<warnings>on
+ #<toolset>intel:<cxxflags>-strict-ansi
+ <toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
+ <toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
+ #<toolset>msvc:<warnings-as-errors>on
+ #<toolset>gcc:<warnings-as-errors>on
+ #<toolset>darwin:<warnings-as-errors>on
+ ;
+
+test-suite functional/hash
+ :
+ [ run hash_fwd_test_1.cpp ]
+ [ run hash_fwd_test_2.cpp ]
+ [ run hash_number_test.cpp ]
+ [ run hash_enum_test.cpp ]
+ [ run hash_pointer_test.cpp ]
+ [ run hash_function_pointer_test.cpp ]
+ [ run hash_float_test.cpp ]
+ [ run hash_long_double_test.cpp ]
+ [ run hash_string_test.cpp ]
+ [ run hash_range_test.cpp ]
+ [ run hash_custom_test.cpp ]
+ [ run hash_global_namespace_test.cpp ]
+ [ run hash_friend_test.cpp ]
+ [ run hash_built_in_array_test.cpp ]
+ [ run hash_value_array_test.cpp ]
+ [ run hash_vector_test.cpp ]
+ [ run hash_list_test.cpp ]
+ [ run hash_deque_test.cpp ]
+ [ run hash_set_test.cpp ]
+ [ run hash_map_test.cpp ]
+ [ run hash_complex_test.cpp ]
+ [ run hash_type_index_test.cpp ]
+ [ run hash_std_array_test.cpp ]
+ [ run hash_std_tuple_test.cpp ]
+ [ run hash_std_smart_ptr_test.cpp ]
+ [ run link_test.cpp link_test_2.cpp ]
+ [ run link_ext_test.cpp link_no_ext_test.cpp ]
+ [ run extensions_hpp_test.cpp ]
+ [ compile-fail hash_no_ext_fail_test.cpp ]
+ [ compile-fail namespace_fail_test.cpp ]
+ [ run implicit_test.cpp ]
+ [ run hash_no_ext_macro_1.cpp ]
+ [ run hash_no_ext_macro_2.cpp ]
+ ;
+
+test-suite functional/hash_no_ext
+ :
+ [ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
+ [ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
+ [ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ]
+ [ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ]
+ [ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ]
+ [ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ]
+ [ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
+ ;
+
+# Tests to see if the floating point hash is using the binary hash.
+# Not run normally because on some platforms these should fail.
+test-suite functional/hash_no_generic_float
+ :
+ [ run hash_float_test.cpp
+ : : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
+ : hash_float_test_no_generic ]
+ [ run hash_long_double_test.cpp
+ : : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
+ : hash_long_double_test_no_generic ]
+ ;
+explicit functional/hash_no_generic_float ;
+
+build-project ../examples ;
diff --git a/libs/functional/hash/test/compile_time.hpp b/libs/functional/hash/test/compile_time.hpp
new file mode 100644
index 0000000..0e445d5
--- /dev/null
+++ b/libs/functional/hash/test/compile_time.hpp
@@ -0,0 +1,16 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+
+template <class T>
+void compile_time_tests(T*)
+{
+ BOOST_STATIC_ASSERT((ndnboost::is_base_and_derived<
+ std::unary_function<T, std::size_t>, BOOST_HASH_TEST_NAMESPACE::hash<T> >::value));
+}
+
diff --git a/libs/functional/hash/test/config.hpp b/libs/functional/hash/test/config.hpp
new file mode 100644
index 0000000..5a1422f
--- /dev/null
+++ b/libs/functional/hash/test/config.hpp
@@ -0,0 +1,21 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#if defined(BOOST_HASH_TEST_STD)
+# define BOOST_HASH_TEST_STD_INCLUDES
+# define BOOST_HASH_TEST_NAMESPACE std
+#else
+# define BOOST_HASH_TEST_NAMESPACE ndnboost
+# if !defined(BOOST_HASH_NO_EXTENSIONS)
+# define BOOST_HASH_TEST_EXTENSIONS
+# endif
+#endif
+
+#if defined(_WIN32_WCE)
+// The standard windows mobile headers trigger this warning so I disable it
+// before doing anything else.
+#pragma warning(disable:4201) // nonstandard extension used :
+ // nameless struct/union
+#endif
diff --git a/libs/functional/hash/test/extensions_hpp_test.cpp b/libs/functional/hash/test/extensions_hpp_test.cpp
new file mode 100644
index 0000000..45f6f8f
--- /dev/null
+++ b/libs/functional/hash/test/extensions_hpp_test.cpp
@@ -0,0 +1,19 @@
+
+// Copyright 2009 Daniel James.
+// 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)
+
+// Check that boost/functional/hash/extensions.hpp works okay.
+//
+// It probably should be in boost/functional/hash/detail, but since it isn't it
+// should work.
+
+#include "./config.hpp"
+
+#include <boost/functional/hash/extensions.hpp>
+
+int main() {
+ int x[2] = { 2, 3 };
+ ndnboost::hash<int[2]> hf;
+ hf(x);
+}
diff --git a/libs/functional/hash/test/extra/Jamfile.v2 b/libs/functional/hash/test/extra/Jamfile.v2
new file mode 100644
index 0000000..243c1b1
--- /dev/null
+++ b/libs/functional/hash/test/extra/Jamfile.v2
@@ -0,0 +1,13 @@
+
+# Copyright 2012 Daniel James.
+# 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)
+
+import testing ;
+
+build-project .. ;
+
+test-suite functional/hash/config
+ :
+ [ compile check_float_funcs.cpp ]
+ ;
\ No newline at end of file
diff --git a/libs/functional/hash/test/extra/check_float_funcs.cpp b/libs/functional/hash/test/extra/check_float_funcs.cpp
new file mode 100644
index 0000000..41817ba
--- /dev/null
+++ b/libs/functional/hash/test/extra/check_float_funcs.cpp
@@ -0,0 +1,58 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <cmath>
+
+namespace test
+{
+ template <class T1>
+ struct check_return_type
+ {
+ template <class T2>
+ static void equals(T2)
+ {
+ BOOST_STATIC_ASSERT((ndnboost::is_same<T1, T2>::value));
+ }
+
+ template <class T2>
+ static void equals_ref(T2&)
+ {
+ BOOST_STATIC_ASSERT((ndnboost::is_same<T1, T2>::value));
+ }
+
+ template <class T2>
+ static void convertible(T2)
+ {
+ BOOST_STATIC_ASSERT((ndnboost::is_convertible<T2, T1>::value));
+ }
+ };
+}
+
+int main() {
+ float f = 0;
+ double d = 0;
+ long double l = 0;
+
+ test::check_return_type<float>::equals(std::ldexp(f, 0));
+ test::check_return_type<double>::equals(std::ldexp(d, 0));
+ test::check_return_type<long double>::equals(std::ldexp(l, 0));
+
+ int dummy = 0;
+
+ test::check_return_type<float>::equals(std::frexp(f, &dummy));
+ test::check_return_type<double>::equals(std::frexp(d, &dummy));
+ test::check_return_type<long double>::equals(std::frexp(l, &dummy));
+
+#if BOOST_HASH_USE_FPCLASSIFY
+
+ int (*fpc1)(float) = std::fpclassify;
+ int (*fpc2)(double) = std::fpclassify;
+ int (*fpc3)(long double) = std::fpclassify;
+
+#endif
+}
diff --git a/libs/functional/hash/test/hash_built_in_array_test.cpp b/libs/functional/hash/test/hash_built_in_array_test.cpp
new file mode 100644
index 0000000..926f385
--- /dev/null
+++ b/libs/functional/hash/test/hash_built_in_array_test.cpp
@@ -0,0 +1,75 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+void array_int_test()
+{
+ const int length1 = 25;
+ int array1[25] = {
+ 26, -43, 32, 65, 45,
+ 12, 67, 32, 12, 23,
+ 0, 0, 0, 0, 0,
+ 8, -12, 23, 65, 45,
+ -1, 93, -54, 987, 3
+ };
+ BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
+
+ const int length2 = 1;
+ int array2[1] = {3};
+ BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
+
+ const int length3 = 2;
+ int array3[2] = {2, 3};
+ BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
+
+ BOOST_TEST(hasher1(array1)
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(array1, array1 + length1));
+ BOOST_TEST(hasher2(array2)
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(array2, array2 + length2));
+ BOOST_TEST(hasher3(array3)
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(array3, array3 + length3));
+}
+
+void two_dimensional_array_test()
+{
+ int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
+ BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
+
+ std::size_t seed1 = 0;
+ for(int i = 0; i < 3; ++i)
+ {
+ std::size_t seed2 = 0;
+ for(int j = 0; j < 2; ++j)
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, array[i][j]);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, seed2);
+ }
+
+ BOOST_TEST(hasher(array) == seed1);
+ BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_range(array, array + 3));
+}
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ array_int_test();
+ two_dimensional_array_test();
+#endif
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_complex_test.cpp b/libs/functional/hash/test/hash_complex_test.cpp
new file mode 100644
index 0000000..f8641d2
--- /dev/null
+++ b/libs/functional/hash/test/hash_complex_test.cpp
@@ -0,0 +1,110 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#if !defined(BOOST_HASH_TEST_EXTENSIONS)
+
+int main() {}
+
+#else
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(disable:4244) // conversion from 'unsigned long' to
+ // 'unsigned short', possible loss of data
+#pragma warning(disable:4245) // conversion from 'int' to
+ // 'const unsigned short',
+ // signed/unsigned mismatch
+#pragma warning(disable:4305) // truncation from 'double' to
+ // 'const std::complex<float>::_Ty'
+#pragma warning(disable:4309) // truncation of constant value
+#pragma warning(disable:4512) // assignment operator could not be generated
+#if BOOST_MSVC < 1400
+#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
+ // possible loss of data
+#endif
+#endif
+
+#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+#include <complex>
+#include <sstream>
+#include <boost/limits.hpp>
+
+template <class T>
+void generic_complex_tests(std::complex<T> v)
+{
+ BOOST_HASH_TEST_NAMESPACE::hash<std::complex<T> > complex_hasher;
+
+ BOOST_TEST(complex_hasher(v) == complex_hasher(v));
+
+ BOOST_HASH_TEST_NAMESPACE::hash<T> real_hasher;
+ T real = v.real();
+ T imag = v.imag();
+
+ BOOST_TEST(real_hasher(real) == complex_hasher(std::complex<T>(real)));
+
+ if(imag != 0 && real_hasher(real) == complex_hasher(v)) {
+ std::ostringstream os;
+ os<<"real_hasher("<<real<<") == complex_hasher("
+ <<v.real()<<" + "<<v.imag()<<"i) == "
+ <<real_hasher(real)<<" (This might not be a bug).";
+ BOOST_ERROR(os.str().c_str());
+ }
+}
+
+template <class Float>
+void complex_float_tests(Float*)
+{
+ typedef std::complex<Float> complex;
+ generic_complex_tests(complex(0,0));
+ generic_complex_tests(complex(0.5,0));
+ generic_complex_tests(complex(25,0));
+ generic_complex_tests(complex(25,0));
+ generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
+}
+
+template <class Integer>
+void complex_integral_tests(Integer*)
+{
+ typedef std::complex<Integer> complex;
+ generic_complex_tests(complex(0,0));
+ generic_complex_tests(complex(15342,124));
+ generic_complex_tests(complex(25,54356));
+ generic_complex_tests(complex(5325,2346));
+ generic_complex_tests(complex(-243897,-49923874));
+ generic_complex_tests(complex(-543,763));
+}
+
+int main()
+{
+ // I've comments out the short and unsigned short tests
+ // as they cause warnings and don't really test
+ // anything that the other tests already deal with.
+
+ complex_float_tests((float*) 0);
+ complex_float_tests((double*) 0);
+ complex_float_tests((long double*) 0);
+ //complex_integral_tests((short*) 0);
+ complex_integral_tests((int*) 0);
+ complex_integral_tests((long*) 0);
+ //complex_integral_tests((unsigned short*) 0);
+ complex_integral_tests((unsigned int*) 0);
+ complex_integral_tests((unsigned long*) 0);
+
+ return ndnboost::report_errors();
+}
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
diff --git a/libs/functional/hash/test/hash_custom_test.cpp b/libs/functional/hash/test/hash_custom_test.cpp
new file mode 100644
index 0000000..ca2a310
--- /dev/null
+++ b/libs/functional/hash/test/hash_custom_test.cpp
@@ -0,0 +1,100 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+#include <boost/config.hpp>
+#include <cstddef>
+
+namespace test
+{
+ struct custom
+ {
+ int value_;
+
+ std::size_t hash() const
+ {
+ return value_ * 10;
+ }
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ friend std::size_t hash_value(custom const& x )
+ {
+ return x.hash();
+ }
+#endif
+
+ custom(int x) : value_(x) {}
+ };
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace ndnboost
+{
+ std::size_t hash_value(test::custom x)
+ {
+ return x.hash();
+ }
+}
+#endif
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+#include <vector>
+#include <string>
+#include <cctype>
+
+void custom_tests()
+{
+ BOOST_HASH_TEST_NAMESPACE::hash<test::custom> custom_hasher;
+ BOOST_TEST(custom_hasher(10) == 100u);
+ test::custom x(55);
+ BOOST_TEST(custom_hasher(x) == 550u);
+
+ {
+ using namespace BOOST_HASH_TEST_NAMESPACE;
+ BOOST_TEST(custom_hasher(x) == hash_value(x));
+ }
+
+ std::vector<test::custom> custom_vector;
+ custom_vector.push_back(5);
+ custom_vector.push_back(25);
+ custom_vector.push_back(35);
+
+ std::size_t seed = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(5));
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(25));
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(35));
+
+ std::size_t seed2 = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
+
+ BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
+ custom_vector.begin(), custom_vector.end()));
+ BOOST_TEST(seed == seed2);
+}
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ custom_tests();
+#endif
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_deque_test.cpp b/libs/functional/hash/test/hash_deque_test.cpp
new file mode 100644
index 0000000..dda9d40
--- /dev/null
+++ b/libs/functional/hash/test/hash_deque_test.cpp
@@ -0,0 +1,35 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+#include <deque>
+
+using std::deque;
+#define CONTAINER_TYPE deque
+#include "./hash_sequence_test.hpp"
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ deque_tests::deque_hash_integer_tests();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_enum_test.cpp b/libs/functional/hash/test/hash_enum_test.cpp
new file mode 100644
index 0000000..781387a
--- /dev/null
+++ b/libs/functional/hash/test/hash_enum_test.cpp
@@ -0,0 +1,63 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include "./compile_time.hpp"
+
+namespace test {
+ enum enum_override { enum_override1, enum_override2 };
+ std::size_t hash_value(enum_override) { return 896532; }
+
+ enum enum1 { enum1a };
+ enum enum2 { enum2a, enum2b };
+ enum enum3 { enum3a = 574, enum3b };
+ enum enum4 { enum4a = -12574, enum4b };
+}
+
+int main() {
+ compile_time_tests((test::enum1*) 0);
+ compile_time_tests((test::enum2*) 0);
+ compile_time_tests((test::enum3*) 0);
+ compile_time_tests((test::enum4*) 0);
+ compile_time_tests((test::enum_override*) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<test::enum1> hash1;
+ BOOST_HASH_TEST_NAMESPACE::hash<test::enum2> hash2;
+ BOOST_HASH_TEST_NAMESPACE::hash<test::enum3> hash3;
+ BOOST_HASH_TEST_NAMESPACE::hash<test::enum4> hash4;
+
+ BOOST_TEST(hash1(test::enum1a) == hash1(test::enum1a));
+
+ BOOST_TEST(hash2(test::enum2a) == hash2(test::enum2a));
+ BOOST_TEST(hash2(test::enum2a) != hash2(test::enum2b));
+ BOOST_TEST(hash2(test::enum2b) == hash2(test::enum2b));
+
+ BOOST_TEST(hash3(test::enum3a) == hash3(test::enum3a));
+ BOOST_TEST(hash3(test::enum3a) != hash3(test::enum3b));
+ BOOST_TEST(hash3(test::enum3b) == hash3(test::enum3b));
+
+ BOOST_TEST(hash4(test::enum4a) == hash4(test::enum4a));
+ BOOST_TEST(hash4(test::enum4a) != hash4(test::enum4b));
+ BOOST_TEST(hash4(test::enum4b) == hash4(test::enum4b));
+
+ BOOST_HASH_TEST_NAMESPACE::hash<test::enum_override> hash_override;
+
+ BOOST_TEST(hash_override(test::enum_override1) ==
+ hash_override(test::enum_override1));
+ BOOST_TEST(hash_override(test::enum_override1) ==
+ hash_override(test::enum_override2));
+ BOOST_TEST(hash_override(test::enum_override1) ==
+ hash_override(test::enum_override1));
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_float_test.cpp b/libs/functional/hash/test/hash_float_test.cpp
new file mode 100644
index 0000000..69cd508
--- /dev/null
+++ b/libs/functional/hash/test/hash_float_test.cpp
@@ -0,0 +1,18 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "hash_float_test.hpp"
+
+int main()
+{
+ std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
+ std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
+ std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
+
+ float_tests("float", (float*) 0);
+ float_tests("double", (double*) 0);
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_float_test.hpp b/libs/functional/hash/test/hash_float_test.hpp
new file mode 100644
index 0000000..96693a9
--- /dev/null
+++ b/libs/functional/hash/test/hash_float_test.hpp
@@ -0,0 +1,309 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <cmath>
+#include <boost/functional/hash/detail/limits.hpp>
+#include <boost/functional/hash/detail/float_functions.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <iostream>
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable:4127) // conditional expression is constant
+#pragma warning(disable:4723) // conditional expression is constant
+#if BOOST_MSVC < 1400
+#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
+ // possible loss of data
+#endif
+#endif
+
+#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+char const* float_type(float*) { return "float"; }
+char const* float_type(double*) { return "double"; }
+char const* float_type(long double*) { return "long double"; }
+
+template <class T>
+void float_tests(char const* name, T* = 0)
+{
+ std::cerr
+ << "\n"
+ << "Testing " BOOST_STRINGIZE(BOOST_HASH_TEST_NAMESPACE) "::hash<"
+ << name
+ << ">\n"
+ << "\n"
+ << "ndnboost::hash_detail::limits<T>::digits = "
+ << ndnboost::hash_detail::limits<T>::digits<< "\n"
+ << "ndnboost::hash_detail::limits<int>::digits = "
+ << ndnboost::hash_detail::limits<int>::digits<< "\n"
+ << "ndnboost::hash_detail::limits<std::size_t>::digits = "
+ << ndnboost::hash_detail::limits<std::size_t>::digits
+ << "\n"
+ << "\n"
+ << "ndnboost::hash_detail::call_ldexp<T>::float_type = "
+ << float_type(static_cast<BOOST_DEDUCED_TYPENAME
+ ndnboost::hash_detail::call_ldexp<T>::float_type*>(0))
+ << "\n"
+ << "ndnboost::hash_detail::call_frexp<T>::float_type = "
+ << float_type(static_cast<BOOST_DEDUCED_TYPENAME
+ ndnboost::hash_detail::call_frexp<T>::float_type*>(0))
+ << "\n"
+ << "ndnboost::hash_detail::select_hash_type<T>::type = "
+ << float_type(static_cast<BOOST_DEDUCED_TYPENAME
+ ndnboost::hash_detail::select_hash_type<T>::type*>(0))
+ << "\n"
+ << "\n"
+ ;
+
+ BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
+
+ T zero = 0;
+ T minus_zero = (T) -1 * zero;
+
+ BOOST_TEST(zero == minus_zero);
+ BOOST_TEST(x1(zero) == x1(minus_zero));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(zero));
+ BOOST_TEST(x1(minus_zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_zero));
+#endif
+
+ BOOST_TEST(x1(zero) != x1(0.5));
+ BOOST_TEST(x1(minus_zero) != x1(0.5));
+ BOOST_TEST(x1(0.5) != x1(-0.5));
+ BOOST_TEST(x1(1) != x1(-1));
+
+ using namespace std;
+
+// Doing anything with infinity causes borland to crash.
+#if defined(__BORLANDC__)
+ std::cerr
+ << "Not running infinity checks on Borland, as it causes it to crash."
+ "\n";
+#else
+ if(ndnboost::hash_detail::limits<T>::has_infinity) {
+ T infinity = -log(zero);
+ T infinity2 = (T) 1. / zero;
+ T infinity3 = (T) -1. / minus_zero;
+ T infinity4 = ndnboost::hash_detail::limits<T>::infinity();
+
+ T minus_infinity = log(zero);
+ T minus_infinity2 = (T) -1. / zero;
+ T minus_infinity3 = (T) 1. / minus_zero;
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(infinity) == BOOST_HASH_TEST_NAMESPACE::hash_value(infinity));
+ BOOST_TEST(x1(minus_infinity)
+ == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_infinity));
+#endif
+
+ if(infinity == infinity2)
+ BOOST_TEST(x1(infinity) == x1(infinity2));
+ if(infinity == infinity3)
+ BOOST_TEST(x1(infinity) == x1(infinity3));
+ if(infinity == infinity4)
+ BOOST_TEST(x1(infinity) == x1(infinity4));
+
+ if(minus_infinity == minus_infinity2)
+ BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2));
+ if(minus_infinity == minus_infinity3)
+ BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3));
+
+ BOOST_TEST(infinity != minus_infinity);
+
+ if(x1(infinity) == x1(minus_infinity)) {
+ std::cerr<<"x1(infinity) == x1(-infinity) == "<<x1(infinity)<<"\n";
+ }
+
+ // This should really be 'has_denorm == denorm_present' but some
+ // compilers don't have 'denorm_present'. See also a later use.
+ if(ndnboost::hash_detail::limits<T>::has_denorm) {
+ if(x1(ndnboost::hash_detail::limits<T>::denorm_min()) == x1(infinity))
+ {
+ std::cerr
+ << "x1(denorm_min) == x1(infinity) == "
+ << x1(infinity)
+ << "\n";
+ }
+
+ if(x1(ndnboost::hash_detail::limits<T>::denorm_min()) ==
+ x1(minus_infinity))
+ {
+ std::cerr
+ << "x1(denorm_min) == x1(-infinity) == "
+ << x1(minus_infinity)
+ << "\n";
+ }
+ }
+
+ if(ndnboost::hash_detail::limits<T>::has_quiet_NaN) {
+ if(x1(ndnboost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity))
+ {
+ std::cerr
+ << "x1(quiet_NaN) == x1(infinity) == "
+ << x1(infinity)
+ << "\n";
+ }
+
+ if(x1(ndnboost::hash_detail::limits<T>::quiet_NaN()) ==
+ x1(minus_infinity))
+ {
+ std::cerr
+ << "x1(quiet_NaN) == x1(-infinity) == "
+ << x1(minus_infinity)
+ << "\n";
+ }
+ }
+ }
+#endif
+
+ T max = (ndnboost::hash_detail::limits<T>::max)();
+ T half_max = max / 2;
+ T quarter_max = max / 4;
+ T three_quarter_max = max - quarter_max;
+
+ // Check the limits::max is in range.
+ BOOST_TEST(max != half_max);
+ BOOST_TEST(max != quarter_max);
+ BOOST_TEST(max != three_quarter_max);
+ BOOST_TEST(half_max != quarter_max);
+ BOOST_TEST(half_max != three_quarter_max);
+ BOOST_TEST(quarter_max != three_quarter_max);
+
+ BOOST_TEST(max != -max);
+ BOOST_TEST(half_max != -half_max);
+ BOOST_TEST(quarter_max != -quarter_max);
+ BOOST_TEST(three_quarter_max != -three_quarter_max);
+
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(max) == BOOST_HASH_TEST_NAMESPACE::hash_value(max));
+ BOOST_TEST(x1(half_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(half_max));
+ BOOST_TEST(x1(quarter_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(quarter_max));
+ BOOST_TEST(x1(three_quarter_max) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_value(three_quarter_max));
+#endif
+
+ // The '!=' tests could legitimately fail, but with my hash it indicates a
+ // bug.
+ BOOST_TEST(x1(max) == x1(max));
+ BOOST_TEST(x1(max) != x1(quarter_max));
+ BOOST_TEST(x1(max) != x1(half_max));
+ BOOST_TEST(x1(max) != x1(three_quarter_max));
+ BOOST_TEST(x1(quarter_max) == x1(quarter_max));
+ BOOST_TEST(x1(quarter_max) != x1(half_max));
+ BOOST_TEST(x1(quarter_max) != x1(three_quarter_max));
+ BOOST_TEST(x1(half_max) == x1(half_max));
+ BOOST_TEST(x1(half_max) != x1(three_quarter_max));
+ BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
+
+ BOOST_TEST(x1(max) != x1(-max));
+ BOOST_TEST(x1(half_max) != x1(-half_max));
+ BOOST_TEST(x1(quarter_max) != x1(-quarter_max));
+ BOOST_TEST(x1(three_quarter_max) != x1(-three_quarter_max));
+
+
+// Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
+#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
+ defined(__ICC) || defined(__ECC)) && \
+ (defined(__GLIBCPP__) || defined(__GLIBCXX__)))
+ T v1 = asin((T) 1);
+ T v2 = acos((T) 0);
+ if(v1 == v2)
+ BOOST_TEST(x1(v1) == x1(v2));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(v1) == BOOST_HASH_TEST_NAMESPACE::hash_value(v1));
+ BOOST_TEST(x1(v2) == BOOST_HASH_TEST_NAMESPACE::hash_value(v2));
+#endif
+
+#endif
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(ndnboost::hash_detail::limits<T>::epsilon()) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_value(
+ ndnboost::hash_detail::limits<T>::epsilon()));
+#endif
+
+ BOOST_TEST(ndnboost::hash_detail::limits<T>::epsilon() != (T) 0);
+ if(x1(ndnboost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
+ std::cerr<<"x1(epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
+
+ BOOST_TEST(-ndnboost::hash_detail::limits<T>::epsilon() != (T) 0);
+ if(x1(-ndnboost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
+ std::cerr<<"x1(-epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
+
+ BOOST_TEST((T) 1 + ndnboost::hash_detail::limits<T>::epsilon() != (T) 1);
+ if(x1((T) 1 + ndnboost::hash_detail::limits<T>::epsilon()) == x1((T) 1))
+ std::cerr<<"x1(1 + epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
+
+ BOOST_TEST((T) 1 - ndnboost::hash_detail::limits<T>::epsilon() != (T) 1);
+ if(x1((T) 1 - ndnboost::hash_detail::limits<T>::epsilon()) == x1((T) 1))
+ std::cerr<<"x1(1 - epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
+
+ BOOST_TEST((T) -1 + ndnboost::hash_detail::limits<T>::epsilon() != (T) -1);
+ if(x1((T) -1 + ndnboost::hash_detail::limits<T>::epsilon()) == x1((T) -1))
+ std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
+
+ BOOST_TEST((T) -1 - ndnboost::hash_detail::limits<T>::epsilon() != (T) -1);
+ if(x1((T) -1 - ndnboost::hash_detail::limits<T>::epsilon()) == x1((T) -1))
+ std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
+
+ // As before.
+ if(ndnboost::hash_detail::limits<T>::has_denorm) {
+ if(x1(ndnboost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
+ std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
+ }
+#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(BOOST_HASH_TEST_EXTENSIONS)
+ // The Tru64/CXX standard library prior to 7.1 contains a bug in the
+ // specialization of ndnboost::hash_detail::limits::denorm_min() for long
+ // doubles which causes this test to fail.
+ if(x1(ndnboost::hash_detail::limits<T>::denorm_min()) !=
+ BOOST_HASH_TEST_NAMESPACE::hash_value(
+ ndnboost::hash_detail::limits<T>::denorm_min()))
+ {
+ std::cerr
+ << "x1(ndnboost::hash_detail::limits<T>::denorm_min()) = "
+ << x1(ndnboost::hash_detail::limits<T>::denorm_min())
+ << "\nhash_value(ndnboost::hash_detail::limits<T>::denorm_min())"
+ " = "
+ << BOOST_HASH_TEST_NAMESPACE::hash_value(
+ ndnboost::hash_detail::limits<T>::denorm_min())
+ << "\nx1(0) = "
+ << x1(0)
+ << "\n";
+ }
+#endif
+ }
+
+// NaN also causes borland to crash.
+#if !defined(__BORLANDC__) && defined(BOOST_HASH_TEST_EXTENSIONS)
+ if(ndnboost::hash_detail::limits<T>::has_quiet_NaN) {
+ if(x1(ndnboost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
+ std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
+ }
+ BOOST_TEST(x1(ndnboost::hash_detail::limits<T>::quiet_NaN()) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_value(
+ ndnboost::hash_detail::limits<T>::quiet_NaN()));
+ }
+#endif
+}
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
diff --git a/libs/functional/hash/test/hash_friend_test.cpp b/libs/functional/hash/test/hash_friend_test.cpp
new file mode 100644
index 0000000..66b9130
--- /dev/null
+++ b/libs/functional/hash/test/hash_friend_test.cpp
@@ -0,0 +1,103 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#include <boost/config.hpp>
+#include <cstddef>
+
+namespace test
+{
+ template <class T>
+ struct custom
+ {
+ int value_;
+
+ std::size_t hash() const
+ {
+ return value_ * 10;
+ }
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ friend std::size_t hash_value(custom const& x)
+ {
+ return x.hash();
+ }
+#endif
+
+ custom(int x) : value_(x) {}
+ };
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace ndnboost
+{
+ template <class T>
+ std::size_t hash_value(test::custom<T> x)
+ {
+ return x.hash();
+ }
+}
+#endif
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+#include <vector>
+#include <string>
+#include <cctype>
+
+void custom_tests()
+{
+ BOOST_HASH_TEST_NAMESPACE::hash<test::custom<int> > custom_hasher;
+ BOOST_TEST(custom_hasher(10) == 100u);
+ test::custom<int> x(55);
+ BOOST_TEST(custom_hasher(x) == 550u);
+
+ {
+ using namespace BOOST_HASH_TEST_NAMESPACE;
+ BOOST_TEST(custom_hasher(x) == hash_value(x));
+ }
+
+ std::vector<test::custom<int> > custom_vector;
+ custom_vector.push_back(5);
+ custom_vector.push_back(25);
+ custom_vector.push_back(35);
+
+ std::size_t seed = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(5));
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(25));
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(35));
+
+ std::size_t seed2 = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
+
+ BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
+ custom_vector.begin(), custom_vector.end()));
+ BOOST_TEST(seed == seed2);
+}
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ custom_tests();
+#endif
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_function_pointer_test.cpp b/libs/functional/hash/test/hash_function_pointer_test.cpp
new file mode 100644
index 0000000..eb78cc3
--- /dev/null
+++ b/libs/functional/hash/test/hash_function_pointer_test.cpp
@@ -0,0 +1,57 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include "./compile_time.hpp"
+
+void void_func1() { static int x = 1; ++x; }
+void void_func2() { static int x = 2; --x; }
+int int_func1(int) { return 0; }
+int int_func2(int) { return 1; }
+
+void function_pointer_tests()
+{
+ compile_time_tests((void(**)()) 0);
+ compile_time_tests((int(**)(int)) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<void(*)()> hasher_void;
+ BOOST_HASH_TEST_NAMESPACE::hash<int(*)(int)> hasher_int;
+
+ BOOST_TEST(&void_func1 != &void_func2);
+ BOOST_TEST(&int_func1 != &int_func2);
+
+ BOOST_TEST(hasher_void(0) == hasher_void(0));
+ BOOST_TEST(hasher_void(&void_func1) == hasher_void(&void_func1));
+ BOOST_TEST(hasher_void(&void_func1) != hasher_void(&void_func2));
+ BOOST_TEST(hasher_void(&void_func1) != hasher_void(0));
+ BOOST_TEST(hasher_int(0) == hasher_int(0));
+ BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
+ BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
+ BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(hasher_void(&void_func1)
+ == BOOST_HASH_TEST_NAMESPACE::hash_value(&void_func1));
+ BOOST_TEST(hasher_int(&int_func1)
+ == BOOST_HASH_TEST_NAMESPACE::hash_value(&int_func1));
+
+ // This isn't specified in Peter's proposal:
+ BOOST_TEST(hasher_void(0) == 0);
+#endif
+}
+
+int main()
+{
+ function_pointer_tests();
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_fwd_test.hpp b/libs/functional/hash/test/hash_fwd_test.hpp
new file mode 100644
index 0000000..e64017c
--- /dev/null
+++ b/libs/functional/hash/test/hash_fwd_test.hpp
@@ -0,0 +1,104 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
+#include <boost/functional/hash_fwd.hpp>
+
+#include <boost/config.hpp>
+#include <cstddef>
+#include <vector>
+
+namespace test {
+
+ template <class T>
+ struct test_type1
+ {
+ T value;
+ test_type1(T const& x) : value(x) {}
+ };
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ template <class T>
+ std::size_t hash_value(test_type1<T> const& x)
+ {
+ BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
+ return hasher(x.value);
+ }
+#endif
+
+ template <class T>
+ struct test_type2
+ {
+ T value1, value2;
+ test_type2(T const& x, T const& y) : value1(x), value2(y) {}
+ };
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ template <class T>
+ std::size_t hash_value(test_type2<T> const& x)
+ {
+ std::size_t seed = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
+ return seed;
+ }
+#endif
+
+ template <class T>
+ struct test_type3
+ {
+ std::vector<T> values;
+ test_type3(typename std::vector<T>::iterator x,
+ typename std::vector<T>::iterator y) : values(x, y) {}
+ };
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ template <class T>
+ std::size_t hash_value(test_type3<T> const& x)
+ {
+ std::size_t seed =
+ BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
+ BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
+ return seed;
+ }
+#endif
+
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+
+namespace ndnboost
+{
+ template <class T>
+ std::size_t hash_value(test::test_type1<T> const& x)
+ {
+ BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
+ return hasher(x.value);
+ }
+
+ template <class T>
+ std::size_t hash_value(test::test_type2<T> const& x)
+ {
+ std::size_t seed = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
+ return seed;
+ }
+
+ template <class T>
+ std::size_t hash_value(test::test_type3<T> const& x)
+ {
+ std::size_t seed =
+ BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
+ BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
+ return seed;
+ }
+}
+
+#endif
+
+#endif
diff --git a/libs/functional/hash/test/hash_fwd_test_1.cpp b/libs/functional/hash/test/hash_fwd_test_1.cpp
new file mode 100644
index 0000000..a3f1665
--- /dev/null
+++ b/libs/functional/hash/test/hash_fwd_test_1.cpp
@@ -0,0 +1,96 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+// This checks that template code implemented using hash_fwd will work.
+
+#include "./config.hpp"
+
+#include "./hash_fwd_test.hpp"
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
+
+#include <boost/functional/hash.hpp>
+#include <string>
+
+void fwd_test1()
+{
+ test::test_type1<int> x(5);
+ test::test_type1<std::string> y("Test");
+
+ BOOST_HASH_TEST_NAMESPACE::hash<int> hasher_int;
+ BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher_string;
+ BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
+ BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
+
+ BOOST_TEST(hasher_int(5) == hasher_test_int(x));
+ BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
+}
+
+void fwd_test2()
+{
+ test::test_type2<int> x(5, 10);
+ test::test_type2<std::string> y("Test1", "Test2");
+
+ std::size_t seed1 = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 5);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 10);
+
+ std::size_t seed2 = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test1"));
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test2"));
+
+ BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
+ BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
+
+ BOOST_TEST(seed1 == hasher_test_int(x));
+ BOOST_TEST(seed2 == hasher_test_string(y));
+}
+
+void fwd_test3()
+{
+ std::vector<int> values1;
+ values1.push_back(10);
+ values1.push_back(15);
+ values1.push_back(20);
+ values1.push_back(3);
+
+ std::vector<std::string> values2;
+ values2.push_back("Chico");
+ values2.push_back("Groucho");
+ values2.push_back("Harpo");
+ values2.push_back("Gummo");
+ values2.push_back("Zeppo");
+
+ test::test_type3<int> x(values1.begin(), values1.end());
+ test::test_type3<std::string> y(values2.begin(), values2.end());
+
+ std::size_t seed1 =
+ BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end());
+ BOOST_HASH_TEST_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
+
+ std::size_t seed2 =
+ BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end());
+ BOOST_HASH_TEST_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
+
+ BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
+ BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
+
+ BOOST_TEST(seed1 == hasher_test_int(x));
+ BOOST_TEST(seed2 == hasher_test_string(y));
+}
+
+#endif
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ fwd_test1();
+ fwd_test2();
+ fwd_test3();
+#endif
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_fwd_test_2.cpp b/libs/functional/hash/test/hash_fwd_test_2.cpp
new file mode 100644
index 0000000..f4f98f4
--- /dev/null
+++ b/libs/functional/hash/test/hash_fwd_test_2.cpp
@@ -0,0 +1,47 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+// This test just makes sure a header which uses hash_fwd can compile without
+// the main hash headers.
+
+#include "./config.hpp"
+
+#if !defined(BOOST_HASH_TEST_EXTENSIONS) || defined(BOOST_HASH_TEST_STD_INCLUDES)
+
+int main() {}
+
+#else
+
+#include "./hash_fwd_test.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+template <class T> void unused(T const&) {}
+
+void fwd_test()
+{
+ test::test_type1<int> x1(3);
+ test::test_type1<std::string> y1("Black");
+ test::test_type2<int> x2(25, 16);
+ test::test_type2<std::string> y2("White", "Green");
+
+ std::vector<int> empty;
+ std::vector<std::string> empty2;
+
+ test::test_type3<int> x3(empty.begin(), empty.end());
+ test::test_type3<std::string> y3(empty2.begin(), empty2.end());
+
+ // Prevent gcc warnings:
+ unused(x1); unused(x2); unused(x3);
+ unused(y1); unused(y2); unused(y3);
+}
+
+int main()
+{
+ fwd_test();
+
+ return ndnboost::report_errors();
+}
+
+#endif // defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
diff --git a/libs/functional/hash/test/hash_global_namespace_test.cpp b/libs/functional/hash/test/hash_global_namespace_test.cpp
new file mode 100644
index 0000000..9f6c8dd
--- /dev/null
+++ b/libs/functional/hash/test/hash_global_namespace_test.cpp
@@ -0,0 +1,103 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+// This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
+// in the global namespace.
+
+#include "./config.hpp"
+
+#include <boost/config.hpp>
+#include <cstddef>
+
+struct custom
+{
+ int value_;
+
+ std::size_t hash() const
+ {
+ return value_ * 10;
+ }
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ friend std::size_t hash_value(custom const& x )
+ {
+ return x.hash();
+ }
+#endif
+
+ custom(int x) : value_(x) {}
+};
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace ndnboost
+{
+ std::size_t hash_value(custom x)
+ {
+ return x.hash();
+ }
+}
+#endif
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+#include <vector>
+#include <string>
+#include <cctype>
+
+void custom_tests()
+{
+ BOOST_HASH_TEST_NAMESPACE::hash<custom> custom_hasher;
+ BOOST_TEST(custom_hasher(10) == 100u);
+ custom x(55);
+ BOOST_TEST(custom_hasher(x) == 550u);
+
+ {
+ using namespace BOOST_HASH_TEST_NAMESPACE;
+ BOOST_TEST(custom_hasher(x) == hash_value(x));
+ }
+
+ std::vector<custom> custom_vector;
+ custom_vector.push_back(5);
+ custom_vector.push_back(25);
+ custom_vector.push_back(35);
+
+ std::size_t seed = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(5));
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(25));
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(35));
+
+ std::size_t seed2 = 0;
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
+
+ BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
+ custom_vector.begin(), custom_vector.end()));
+ BOOST_TEST(seed == seed2);
+}
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ custom_tests();
+#endif
+ return ndnboost::report_errors();
+}
+
diff --git a/libs/functional/hash/test/hash_list_test.cpp b/libs/functional/hash/test/hash_list_test.cpp
new file mode 100644
index 0000000..4294a80
--- /dev/null
+++ b/libs/functional/hash/test/hash_list_test.cpp
@@ -0,0 +1,35 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+#include <list>
+
+using std::list;
+#define CONTAINER_TYPE list
+#include "./hash_sequence_test.hpp"
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ list_tests::list_hash_integer_tests();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_long_double_test.cpp b/libs/functional/hash/test/hash_long_double_test.cpp
new file mode 100644
index 0000000..c192185
--- /dev/null
+++ b/libs/functional/hash/test/hash_long_double_test.cpp
@@ -0,0 +1,17 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "hash_float_test.hpp"
+
+int main()
+{
+ std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
+ std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
+ std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
+
+ float_tests("long double", (long double*) 0);
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_map_test.cpp b/libs/functional/hash/test/hash_map_test.cpp
new file mode 100644
index 0000000..31835c7
--- /dev/null
+++ b/libs/functional/hash/test/hash_map_test.cpp
@@ -0,0 +1,40 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <map>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+using std::map;
+#define CONTAINER_TYPE map
+#include "./hash_map_test.hpp"
+
+using std::multimap;
+#define CONTAINER_TYPE multimap
+#include "./hash_map_test.hpp"
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ map_tests::map_hash_integer_tests();
+ multimap_tests::multimap_hash_integer_tests();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_map_test.hpp b/libs/functional/hash/test/hash_map_test.hpp
new file mode 100644
index 0000000..41bb2fa
--- /dev/null
+++ b/libs/functional/hash/test/hash_map_test.hpp
@@ -0,0 +1,76 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#if !defined(CONTAINER_TYPE)
+#error "CONTAINER_TYPE not defined"
+#else
+
+#include <boost/preprocessor/cat.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable:4244) // conversion from 'int' to 'float'
+#pragma warning(disable:4245) // signed/unsigned mismatch
+#endif
+
+namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
+{
+ template <class T>
+ void integer_tests(T* = 0)
+ {
+ const int number_of_containers = 10;
+ T containers[number_of_containers];
+ typedef BOOST_DEDUCED_TYPENAME T::value_type pair;
+ typedef BOOST_DEDUCED_TYPENAME T::key_type key;
+ typedef BOOST_DEDUCED_TYPENAME T::mapped_type value;
+
+ for(int i = 0; i < 5; ++i) {
+ for(int j = 0; j < i; ++j)
+ containers[i].insert(pair(key(0), value(0)));
+ }
+
+ containers[6].insert(pair(key(1),value(0)));
+ containers[7].insert(pair(key(1),value(0)));
+ containers[7].insert(pair(key(1),value(0)));
+ containers[8].insert(pair(key(-1),value(1)));
+ containers[9].insert(pair(key(-1),value(3)));
+ containers[9].insert(pair(key(-1),value(3)));
+
+ BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
+
+ for(int i2 = 0; i2 < number_of_containers; ++i2) {
+ BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
+
+ BOOST_TEST(hasher(containers[i2]) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
+
+ BOOST_TEST(hasher(containers[i2])
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(
+ containers[i2].begin(), containers[i2].end()));
+
+ for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
+ BOOST_TEST(
+ (containers[i2] == containers[j2]) ==
+ (hasher(containers[i2]) == hasher(containers[j2]))
+ );
+ }
+ }
+ }
+
+ void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
+ {
+ integer_tests((CONTAINER_TYPE<char, unsigned char>*) 0);
+ integer_tests((CONTAINER_TYPE<int, float>*) 0);
+ integer_tests((CONTAINER_TYPE<unsigned long, unsigned long>*) 0);
+ integer_tests((CONTAINER_TYPE<double, short>*) 0);
+ }
+}
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#undef CONTAINER_TYPE
+#endif
diff --git a/libs/functional/hash/test/hash_no_ext_fail_test.cpp b/libs/functional/hash/test/hash_no_ext_fail_test.cpp
new file mode 100644
index 0000000..6d1636e
--- /dev/null
+++ b/libs/functional/hash/test/hash_no_ext_fail_test.cpp
@@ -0,0 +1,28 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
+// (or at least one of them).
+#if !defined(BOOST_HASH_NO_EXTENSIONS)
+# define BOOST_HASH_NO_EXTENSIONS
+#endif
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+template <class T> void ignore(T const&) {}
+
+int main()
+{
+ BOOST_HASH_TEST_NAMESPACE::hash< int[10] > hasher;
+ ignore(hasher);
+
+ return 0;
+}
diff --git a/libs/functional/hash/test/hash_no_ext_macro_1.cpp b/libs/functional/hash/test/hash_no_ext_macro_1.cpp
new file mode 100644
index 0000000..a9dfa06
--- /dev/null
+++ b/libs/functional/hash/test/hash_no_ext_macro_1.cpp
@@ -0,0 +1,37 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+
+// Include header without BOOST_HASH_NO_EXTENSIONS defined
+# if defined(BOOST_HASH_NO_EXTENSIONS)
+# undef BOOST_HASH_NO_EXTENSIONS
+# endif
+# include <boost/functional/hash.hpp>
+
+// Include header with BOOST_HASH_NO_EXTENSIONS defined
+# define BOOST_HASH_NO_EXTENSIONS
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include <deque>
+
+int main()
+{
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ std::deque<int> x;
+
+ x.push_back(1);
+ x.push_back(2);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<std::deque<int> > hasher;
+ BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_no_ext_macro_2.cpp b/libs/functional/hash/test/hash_no_ext_macro_2.cpp
new file mode 100644
index 0000000..73b422e
--- /dev/null
+++ b/libs/functional/hash/test/hash_no_ext_macro_2.cpp
@@ -0,0 +1,37 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+
+// Include header with BOOST_HASH_NO_EXTENSIONS defined
+# if !defined(BOOST_HASH_NO_EXTENSIONS)
+# define BOOST_HASH_NO_EXTENSIONS
+# endif
+# include <boost/functional/hash.hpp>
+
+// Include header without BOOST_HASH_NO_EXTENSIONS defined
+# undef BOOST_HASH_NO_EXTENSIONS
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include <map>
+
+int main()
+{
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ std::map<int, int> x;
+
+ x.insert(std::map<int, int>::value_type(53, -42));
+ x.insert(std::map<int, int>::value_type(14, -75));
+
+ BOOST_HASH_TEST_NAMESPACE::hash<std::map<int, int> > hasher;
+ BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_number_test.cpp b/libs/functional/hash/test/hash_number_test.cpp
new file mode 100644
index 0000000..28ca6e8
--- /dev/null
+++ b/libs/functional/hash/test/hash_number_test.cpp
@@ -0,0 +1,196 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/functional/hash/detail/limits.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include "./compile_time.hpp"
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable:4127) // conditional expression is constant
+#pragma warning(disable:4309) // truncation of constant value
+#pragma warning(disable:4310) // cast truncates constant value
+#endif
+
+#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+
+template <class T>
+void numeric_extra_tests(typename
+ ndnboost::enable_if_c<ndnboost::hash_detail::limits<T>::is_integer,
+ void*>::type = 0)
+{
+ typedef ndnboost::hash_detail::limits<T> limits;
+
+ if(limits::is_signed ||
+ limits::digits <= ndnboost::hash_detail::limits<std::size_t>::digits)
+ {
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
+ }
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
+}
+
+template <class T>
+void numeric_extra_tests(typename
+ ndnboost::disable_if_c<ndnboost::hash_detail::limits<T>::is_integer,
+ void*>::type = 0)
+{
+}
+
+template <class T>
+void numeric_test(T*)
+{
+ typedef ndnboost::hash_detail::limits<T> limits;
+
+ compile_time_tests((T*) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
+
+ T v1 = (T) -5;
+ BOOST_TEST(x1(v1) == x2(v1));
+ BOOST_TEST(x1(T(-5)) == x2(T(-5)));
+ BOOST_TEST(x1(T(0)) == x2(T(0)));
+ BOOST_TEST(x1(T(10)) == x2(T(10)));
+ BOOST_TEST(x1(T(25)) == x2(T(25)));
+ BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
+ BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
+ BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
+ BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
+ BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
+
+ numeric_extra_tests<T>();
+#endif
+}
+
+template <class T>
+void limits_test(T*)
+{
+ typedef ndnboost::hash_detail::limits<T> limits;
+
+ if(limits::is_specialized)
+ {
+ BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
+
+ T min_value = (limits::min)();
+ T max_value = (limits::max)();
+
+ BOOST_TEST(x1(min_value) == x2((limits::min)()));
+ BOOST_TEST(x1(max_value) == x2((limits::max)()));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
+ BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
+
+ if (limits::is_integer)
+ {
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value)
+ == std::size_t(min_value));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value)
+ == std::size_t(max_value));
+ }
+#endif
+ }
+}
+
+template <class T>
+void poor_quality_tests(T*)
+{
+ typedef ndnboost::hash_detail::limits<T> limits;
+
+ BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
+
+ // A hash function can legally fail these tests, but it'll not be a good
+ // sign.
+ if(T(1) != T(-1))
+ BOOST_TEST(x1(T(1)) != x2(T(-1)));
+ if(T(1) != T(2))
+ BOOST_TEST(x1(T(1)) != x2(T(2)));
+ if((limits::max)() != (limits::max)() - 1)
+ BOOST_TEST(x1(static_cast<T>((limits::max)()))
+ != x2(static_cast<T>((limits::max)() - 1)));
+}
+
+void bool_test()
+{
+ BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
+
+ BOOST_TEST(x1(true) == x2(true));
+ BOOST_TEST(x1(false) == x2(false));
+ BOOST_TEST(x1(true) != x2(false));
+ BOOST_TEST(x1(false) != x2(true));
+}
+
+#define NUMERIC_TEST(type, name) \
+ std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
+ numeric_test((type*) 0); \
+ limits_test((type*) 0); \
+ poor_quality_tests((type*) 0);
+#define NUMERIC_TEST_NO_LIMITS(type, name) \
+ std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
+ numeric_test((type*) 0); \
+ poor_quality_tests((type*) 0);
+
+int main()
+{
+ NUMERIC_TEST(char, char)
+ NUMERIC_TEST(signed char, schar)
+ NUMERIC_TEST(unsigned char, uchar)
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+ NUMERIC_TEST(wchar_t, wchar)
+#endif
+ NUMERIC_TEST(short, short)
+ NUMERIC_TEST(unsigned short, ushort)
+ NUMERIC_TEST(int, int)
+ NUMERIC_TEST(unsigned int, uint)
+ NUMERIC_TEST(long, hash_long)
+ NUMERIC_TEST(unsigned long, ulong)
+
+#if !defined(BOOST_NO_LONG_LONG)
+ NUMERIC_TEST_NO_LIMITS(ndnboost::long_long_type, long_long)
+ NUMERIC_TEST_NO_LIMITS(ndnboost::ulong_long_type, ulong_long)
+#endif
+
+#if defined(BOOST_HAS_INT128)
+ NUMERIC_TEST_NO_LIMITS(ndnboost::int128_type, int128)
+ NUMERIC_TEST_NO_LIMITS(ndnboost::uint128_type, uint128)
+#endif
+
+ NUMERIC_TEST(float, float)
+ NUMERIC_TEST(double, double)
+
+ NUMERIC_TEST(std::size_t, size_t)
+ NUMERIC_TEST(std::ptrdiff_t, ptrdiff_t)
+
+ bool_test();
+
+ return ndnboost::report_errors();
+}
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
diff --git a/libs/functional/hash/test/hash_pointer_test.cpp b/libs/functional/hash/test/hash_pointer_test.cpp
new file mode 100644
index 0000000..2720696
--- /dev/null
+++ b/libs/functional/hash/test/hash_pointer_test.cpp
@@ -0,0 +1,45 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/limits.hpp>
+#include "./compile_time.hpp"
+
+void pointer_tests()
+{
+ compile_time_tests((int**) 0);
+ compile_time_tests((void**) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<int*> x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<int*> x2;
+
+ int int1;
+ int int2;
+
+ BOOST_TEST(x1(0) == x2(0));
+ BOOST_TEST(x1(&int1) == x2(&int1));
+ BOOST_TEST(x1(&int2) == x2(&int2));
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(&int1) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int1));
+ BOOST_TEST(x1(&int2) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int2));
+
+ // This isn't specified in Peter's proposal:
+ BOOST_TEST(x1(0) == 0);
+#endif
+}
+
+int main()
+{
+ pointer_tests();
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_range_test.cpp b/libs/functional/hash/test/hash_range_test.cpp
new file mode 100644
index 0000000..c09239a
--- /dev/null
+++ b/libs/functional/hash/test/hash_range_test.cpp
@@ -0,0 +1,85 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#if !defined(BOOST_HASH_TEST_EXTENSIONS)
+
+int main() {}
+
+#else
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/limits.hpp>
+#include <vector>
+
+void hash_range_tests()
+{
+ std::vector<int> empty, values1, values2, values3, values4, values5;
+ values1.push_back(0);
+ values2.push_back(10);
+ values3.push_back(10);
+ values3.push_back(20);
+ values4.push_back(15);
+ values4.push_back(75);
+ values5.push_back(10);
+ values5.push_back(20);
+ values5.push_back(15);
+ values5.push_back(75);
+ values5.push_back(10);
+ values5.push_back(20);
+
+ std::vector<int> x;
+
+ std::size_t x_seed = 0;
+ BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
+ != BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end()));
+
+ x.push_back(10);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 10);
+ BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
+ != BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+
+ x.push_back(20);
+ BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 20);
+ BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
+ != BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
+ != BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end())
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
+
+ std::size_t seed =
+ BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end());
+ BOOST_HASH_TEST_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
+ BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.begin(), x.end());
+ BOOST_TEST(seed ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(values5.begin(), values5.end()));
+}
+
+int main()
+{
+ hash_range_tests();
+
+ return ndnboost::report_errors();
+}
+
+#endif // TEST_EXTESNIONS
diff --git a/libs/functional/hash/test/hash_sequence_test.hpp b/libs/functional/hash/test/hash_sequence_test.hpp
new file mode 100644
index 0000000..e0846b0
--- /dev/null
+++ b/libs/functional/hash/test/hash_sequence_test.hpp
@@ -0,0 +1,76 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#if !defined(CONTAINER_TYPE)
+#error "CONTAINER_TYPE not defined"
+#else
+
+#include <boost/preprocessor/cat.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable:4245) // signed/unsigned mismatch
+#endif
+
+namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
+{
+ template <class T>
+ void integer_tests(T* = 0)
+ {
+ const int number_of_containers = 11;
+ T containers[number_of_containers];
+
+ for(int i = 0; i < 5; ++i) {
+ for(int j = 0; j < i; ++j)
+ containers[i].push_back(0);
+ }
+
+ containers[5].push_back(1);
+ containers[6].push_back(1);
+ containers[6].push_back(1);
+ containers[7].push_back(-1);
+ containers[8].push_back(-1);
+ containers[8].push_back(-1);
+ containers[9].push_back(1);
+ containers[9].push_back(-1);
+ containers[10].push_back(-1);
+ containers[10].push_back(1);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
+
+ for(int i2 = 0; i2 < number_of_containers; ++i2) {
+ BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
+
+ BOOST_TEST(hasher(containers[i2]) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
+
+ BOOST_TEST(hasher(containers[i2])
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(
+ containers[i2].begin(), containers[i2].end()));
+
+ for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
+ BOOST_TEST(
+ (containers[i2] == containers[j2]) ==
+ (hasher(containers[i2]) == hasher(containers[j2]))
+ );
+ }
+ }
+ }
+
+ void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
+ {
+ integer_tests((CONTAINER_TYPE<char>*) 0);
+ integer_tests((CONTAINER_TYPE<int>*) 0);
+ integer_tests((CONTAINER_TYPE<unsigned long>*) 0);
+ integer_tests((CONTAINER_TYPE<double>*) 0);
+ }
+}
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#undef CONTAINER_TYPE
+#endif
diff --git a/libs/functional/hash/test/hash_set_test.cpp b/libs/functional/hash/test/hash_set_test.cpp
new file mode 100644
index 0000000..be44e92
--- /dev/null
+++ b/libs/functional/hash/test/hash_set_test.cpp
@@ -0,0 +1,40 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+#include <set>
+
+using std::set;
+#define CONTAINER_TYPE set
+#include "./hash_set_test.hpp"
+
+using std::multiset;
+#define CONTAINER_TYPE multiset
+#include "./hash_set_test.hpp"
+
+#endif
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ set_tests::set_hash_integer_tests();
+ multiset_tests::multiset_hash_integer_tests();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_set_test.hpp b/libs/functional/hash/test/hash_set_test.hpp
new file mode 100644
index 0000000..31d4909
--- /dev/null
+++ b/libs/functional/hash/test/hash_set_test.hpp
@@ -0,0 +1,79 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#if !defined(CONTAINER_TYPE)
+#error "CONTAINER_TYPE not defined"
+#else
+
+#include <boost/preprocessor/cat.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable:4245) // signed/unsigned mismatch
+#endif
+
+namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
+{
+ template <class T>
+ void integer_tests(T* = 0)
+ {
+ const int number_of_containers = 12;
+ T containers[number_of_containers];
+
+ for(int i = 0; i < 5; ++i) {
+ for(int j = 0; j < i; ++j)
+ containers[i].insert(0);
+ }
+
+ containers[6].insert(1);
+ containers[7].insert(1);
+ containers[7].insert(1);
+ containers[8].insert(-1);
+ containers[9].insert(-1);
+ containers[9].insert(-1);
+ containers[10].insert(-1);
+ containers[10].insert(1);
+ containers[11].insert(1);
+ containers[11].insert(2);
+ containers[11].insert(3);
+ containers[11].insert(4);
+ containers[11].insert(5);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
+
+ for(int i2 = 0; i2 < number_of_containers; ++i2) {
+ BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
+
+ BOOST_TEST(hasher(containers[i2]) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
+
+ BOOST_TEST(hasher(containers[i2])
+ == BOOST_HASH_TEST_NAMESPACE::hash_range(
+ containers[i2].begin(), containers[i2].end()));
+
+ for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
+ BOOST_TEST(
+ (containers[i2] == containers[j2]) ==
+ (hasher(containers[i2]) == hasher(containers[j2]))
+ );
+ }
+ }
+ }
+
+ void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
+ {
+ integer_tests((CONTAINER_TYPE<char>*) 0);
+ integer_tests((CONTAINER_TYPE<int>*) 0);
+ integer_tests((CONTAINER_TYPE<unsigned long>*) 0);
+ integer_tests((CONTAINER_TYPE<double>*) 0);
+ }
+}
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#undef CONTAINER_TYPE
+#endif
diff --git a/libs/functional/hash/test/hash_std_array_test.cpp b/libs/functional/hash/test/hash_std_array_test.cpp
new file mode 100644
index 0000000..11a28ff
--- /dev/null
+++ b/libs/functional/hash/test/hash_std_array_test.cpp
@@ -0,0 +1,103 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_ARRAY)
+#define TEST_ARRAY
+#include <array>
+#include <vector>
+#endif
+
+#ifdef TEST_ARRAY
+
+template <typename T>
+void array_tests(T const& v) {
+ ndnboost::hash<typename T::value_type> hf;
+ for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
+ for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
+ if (i != j)
+ BOOST_TEST(hf(*i) != hf(*j));
+ else
+ BOOST_TEST(hf(*i) == hf(*j));
+ }
+ }
+}
+
+void empty_array_test() {
+/*
+ ndnboost::hash<std::array<int, 0> > empty_array_hash;
+ std::array<int, 0> empty_array;
+ BOOST_TEST(empty_array_hash(empty_array) == ndnboost::hash_value(empty_array));
+*/
+}
+
+void int_1_array_test()
+{
+ std::vector<std::array<int, 1> > arrays;
+ std::array<int, 1> val;
+ val[0] = 0;
+ arrays.push_back(val);
+ val[0] = 1;
+ arrays.push_back(val);
+ val[0] = 2;
+ arrays.push_back(val);
+ array_tests(arrays);
+}
+
+void string_1_array_test()
+{
+ std::vector<std::array<std::string, 1> > arrays;
+ std::array<std::string, 1> val;
+ arrays.push_back(val);
+ val[0] = "one";
+ arrays.push_back(val);
+ val[0] = "two";
+ arrays.push_back(val);
+ array_tests(arrays);
+}
+
+void string_3_array_test()
+{
+ std::vector<std::array<std::string,3 > > arrays;
+ std::array<std::string, 3> val;
+ arrays.push_back(val);
+ val[0] = "one";
+ arrays.push_back(val);
+ val[0] = ""; val[1] = "one"; val[2] = "";
+ arrays.push_back(val);
+ val[0] = ""; val[1] = ""; val[2] = "one";
+ arrays.push_back(val);
+ val[0] = "one"; val[1] = "one"; val[2] = "one";
+ arrays.push_back(val);
+ val[0] = "one"; val[1] = "two"; val[2] = "three";
+ arrays.push_back(val);
+ array_tests(arrays);
+}
+
+#endif // TEST_ARRAY
+
+int main()
+{
+#ifdef TEST_ARRAY
+ empty_array_test();
+ int_1_array_test();
+ string_1_array_test();
+ string_3_array_test();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_std_smart_ptr_test.cpp b/libs/functional/hash/test/hash_std_smart_ptr_test.cpp
new file mode 100644
index 0000000..639c718
--- /dev/null
+++ b/libs/functional/hash/test/hash_std_smart_ptr_test.cpp
@@ -0,0 +1,80 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include "./compile_time.hpp"
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_SMART_PTR)
+#define TEST_SMART_PTRS
+#include <memory>
+#endif
+
+#ifdef TEST_SMART_PTRS
+
+void shared_ptr_tests()
+{
+ std::shared_ptr<int> x;
+ compile_time_tests(&x);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x2;
+
+ std::shared_ptr<int> ptr1(new int(10));
+ std::shared_ptr<int> ptr2;
+
+ BOOST_TEST(x1(x) == x2(ptr2));
+ BOOST_TEST(x1(x) != x2(ptr1));
+ ptr2.reset(new int(10));
+ BOOST_TEST(x1(ptr1) == x2(ptr1));
+ BOOST_TEST(x1(ptr1) != x2(ptr2));
+ ptr2 = ptr1;
+ BOOST_TEST(x1(ptr1) == x2(ptr2));
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
+ BOOST_TEST(x1(ptr1) == BOOST_HASH_TEST_NAMESPACE::hash_value(ptr2));
+#endif
+}
+
+void unique_ptr_tests()
+{
+ std::unique_ptr<int> x;
+ compile_time_tests(&x);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x2;
+
+ std::unique_ptr<int> ptr1(new int(10));
+ std::unique_ptr<int> ptr2;
+
+ BOOST_TEST(x1(x) == x2(ptr2));
+ BOOST_TEST(x1(x) != x2(ptr1));
+ ptr2.reset(new int(10));
+ BOOST_TEST(x1(ptr1) == x2(ptr1));
+ BOOST_TEST(x1(ptr1) != x2(ptr2));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
+#endif
+}
+
+#endif
+
+int main()
+{
+#ifdef TEST_SMART_PTRS
+ shared_ptr_tests();
+ unique_ptr_tests();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_std_tuple_test.cpp b/libs/functional/hash/test/hash_std_tuple_test.cpp
new file mode 100644
index 0000000..ba5346a
--- /dev/null
+++ b/libs/functional/hash/test/hash_std_tuple_test.cpp
@@ -0,0 +1,77 @@
+
+// Copyright 2012 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
+#define TEST_TUPLE
+#include <tuple>
+#include <vector>
+#endif
+
+#ifdef TEST_TUPLE
+
+template <typename T>
+void tuple_tests(T const& v) {
+ ndnboost::hash<typename T::value_type> hf;
+ for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
+ for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
+ if (i != j)
+ BOOST_TEST(hf(*i) != hf(*j));
+ else
+ BOOST_TEST(hf(*i) == hf(*j));
+ }
+ }
+}
+
+void empty_tuple_test() {
+ ndnboost::hash<std::tuple<> > empty_tuple_hash;
+ std::tuple<> empty_tuple;
+ BOOST_TEST(empty_tuple_hash(empty_tuple) == ndnboost::hash_value(empty_tuple));
+}
+
+void int_tuple_test() {
+ std::vector<std::tuple<int> > int_tuples;
+ int_tuples.push_back(std::make_tuple(0));
+ int_tuples.push_back(std::make_tuple(1));
+ int_tuples.push_back(std::make_tuple(2));
+ tuple_tests(int_tuples);
+}
+
+void int_string_tuple_test() {
+ std::vector<std::tuple<int, std::string> > int_string_tuples;
+ int_string_tuples.push_back(std::make_tuple(0, std::string("zero")));
+ int_string_tuples.push_back(std::make_tuple(1, std::string("one")));
+ int_string_tuples.push_back(std::make_tuple(2, std::string("two")));
+ int_string_tuples.push_back(std::make_tuple(0, std::string("one")));
+ int_string_tuples.push_back(std::make_tuple(1, std::string("zero")));
+ int_string_tuples.push_back(std::make_tuple(0, std::string("")));
+ int_string_tuples.push_back(std::make_tuple(1, std::string("")));
+ tuple_tests(int_string_tuples);
+}
+
+#endif // TEST_TUPLE
+
+int main()
+{
+#ifdef TEST_TUPLE
+ empty_tuple_test();
+ int_tuple_test();
+ int_string_tuple_test();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_string_test.cpp b/libs/functional/hash/test/hash_string_test.cpp
new file mode 100644
index 0000000..73e76af
--- /dev/null
+++ b/libs/functional/hash/test/hash_string_test.cpp
@@ -0,0 +1,73 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+#include <string>
+#include "./compile_time.hpp"
+
+void string_tests()
+{
+ compile_time_tests((std::string*) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<std::string> x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<std::string> x2;
+
+ BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
+ BOOST_TEST(x1("") == x2(std::string()));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ std::string value1;
+ std::string value2("Hello");
+
+ BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
+ BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
+#endif
+}
+
+#if !defined(BOOST_NO_STD_WSTRING)
+void wstring_tests()
+{
+ compile_time_tests((std::wstring*) 0);
+
+ BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x1;
+ BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x2;
+
+ BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
+ BOOST_TEST(x1(L"") == x2(std::wstring()));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+ std::wstring value1;
+ std::wstring value2(L"Hello");
+
+ BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
+ BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
+ BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
+#endif
+}
+#endif
+
+int main()
+{
+ string_tests();
+#if !defined(BOOST_NO_STD_WSTRING)
+ wstring_tests();
+#endif
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_type_index_test.cpp b/libs/functional/hash/test/hash_type_index_test.cpp
new file mode 100644
index 0000000..a5f81ae
--- /dev/null
+++ b/libs/functional/hash/test/hash_type_index_test.cpp
@@ -0,0 +1,53 @@
+
+// Copyright 2011 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+#else
+# include <boost/functional/hash.hpp>
+#endif
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
+
+#include <typeindex>
+
+void test_type_index() {
+ BOOST_HASH_TEST_NAMESPACE::hash<std::type_index> hasher;
+
+#if defined(BOOST_NO_TYPEID)
+ std::cout<<"Unable to test std::type_index, as typeid isn't available"
+ <<std::endl;
+#else
+ std::type_index int_index = typeid(int);
+ std::type_index int2_index = typeid(int);
+ std::type_index char_index = typeid(char);
+
+ BOOST_TEST(hasher(int_index) == int_index.hash_code());
+ BOOST_TEST(hasher(int_index) == int2_index.hash_code());
+ BOOST_TEST(hasher(char_index) == char_index.hash_code());
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int_index.hash_code());
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int2_index.hash_code());
+ BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(char_index) == char_index.hash_code());
+
+ BOOST_TEST(hasher(int_index) == hasher(int2_index));
+ BOOST_TEST(hasher(int_index) != hasher(char_index));
+#endif
+}
+#endif
+
+int main()
+{
+#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
+ test_type_index();
+#else
+ std::cout<<"<type_index> not available."<<std::endl;
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/hash_value_array_test.cpp b/libs/functional/hash/test/hash_value_array_test.cpp
new file mode 100644
index 0000000..dc79ac7
--- /dev/null
+++ b/libs/functional/hash/test/hash_value_array_test.cpp
@@ -0,0 +1,64 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+// On some compilers hash_value isn't available for arrays, so I test it
+// separately from the main array tests.
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+void array_int_test()
+{
+ const int array1[25] = {
+ 26, -43, 32, 65, 45,
+ 12, 67, 32, 12, 23,
+ 0, 0, 0, 0, 0,
+ 8, -12, 23, 65, 45,
+ -1, 93, -54, 987, 3
+ };
+ BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
+
+ int array2[1] = {3};
+ BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
+
+ int array3[2] = {2, 3};
+ BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
+
+ BOOST_TEST(hasher1(array1) == BOOST_HASH_TEST_NAMESPACE::hash_value(array1));
+ BOOST_TEST(hasher2(array2) == BOOST_HASH_TEST_NAMESPACE::hash_value(array2));
+ BOOST_TEST(hasher3(array3) == BOOST_HASH_TEST_NAMESPACE::hash_value(array3));
+}
+
+void two_dimensional_array_test()
+{
+ int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
+ BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
+
+ BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_value(array));
+}
+
+#endif
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ array_int_test();
+ two_dimensional_array_test();
+#endif
+
+ return ndnboost::report_errors();
+}
+
diff --git a/libs/functional/hash/test/hash_vector_test.cpp b/libs/functional/hash/test/hash_vector_test.cpp
new file mode 100644
index 0000000..1eab7ff
--- /dev/null
+++ b/libs/functional/hash/test/hash_vector_test.cpp
@@ -0,0 +1,35 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+# ifdef BOOST_HASH_TEST_STD_INCLUDES
+# include <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+
+#include <vector>
+
+using std::vector;
+#define CONTAINER_TYPE vector
+#include "./hash_sequence_test.hpp"
+
+#endif // BOOST_HASH_TEST_EXTENSIONS
+
+int main()
+{
+#ifdef BOOST_HASH_TEST_EXTENSIONS
+ vector_tests::vector_hash_integer_tests();
+#endif
+
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/implicit_test.cpp b/libs/functional/hash/test/implicit_test.cpp
new file mode 100644
index 0000000..317d8de
--- /dev/null
+++ b/libs/functional/hash/test/implicit_test.cpp
@@ -0,0 +1,21 @@
+
+// Copyright 2010 Daniel James.
+// 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)
+
+#include <boost/functional/hash.hpp>
+
+namespace test
+{
+ struct base {};
+ std::size_t hash_value(base const&) { return 0; }
+
+ struct converts { operator base() const { return base(); } };
+}
+
+int main() {
+ ndnboost::hash<test::converts> hash;
+ test::converts x;
+
+ hash(x);
+}
diff --git a/libs/functional/hash/test/link_ext_test.cpp b/libs/functional/hash/test/link_ext_test.cpp
new file mode 100644
index 0000000..d15af56
--- /dev/null
+++ b/libs/functional/hash/test/link_ext_test.cpp
@@ -0,0 +1,33 @@
+
+// Copyright 2006-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#define BOOST_HASH_TEST_NAMESPACE ndnboost
+#include <boost/functional/hash.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+int f(std::size_t hash1, int* x1) {
+
+ // Check that BOOST_HASH_TEST_NAMESPACE::hash<int*> works in both files.
+ BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
+ BOOST_TEST(hash1 == ptr_hasher(x1));
+
+#if defined(BOOST_HASH_TEST_EXTENSIONS)
+
+ // Check that std::vector<std::size_t> is avaiable in this file.
+ std::vector<std::size_t> x;
+ x.push_back(*x1);
+ BOOST_HASH_TEST_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
+ return vector_hasher(x) != BOOST_HASH_TEST_NAMESPACE::hash_value(x);
+
+#else
+
+ return 0;
+
+#endif
+}
+
diff --git a/libs/functional/hash/test/link_no_ext_test.cpp b/libs/functional/hash/test/link_no_ext_test.cpp
new file mode 100644
index 0000000..64ee6df
--- /dev/null
+++ b/libs/functional/hash/test/link_no_ext_test.cpp
@@ -0,0 +1,20 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#define BOOST_HASH_TEST_NAMESPACE ndnboost
+#define BOOST_HASH_NO_EXTENSIONS
+#include <boost/functional/hash.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+extern int f(std::size_t, int*);
+
+int main() {
+ BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
+ int x = 55;
+ BOOST_TEST(!f(ptr_hasher(&x), &x));
+ return ndnboost::report_errors();
+}
diff --git a/libs/functional/hash/test/link_test.cpp b/libs/functional/hash/test/link_test.cpp
new file mode 100644
index 0000000..bdae262
--- /dev/null
+++ b/libs/functional/hash/test/link_test.cpp
@@ -0,0 +1,11 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#include <boost/functional/hash.hpp>
+
+extern int f();
+int main() { return f(); }
diff --git a/libs/functional/hash/test/link_test_2.cpp b/libs/functional/hash/test/link_test_2.cpp
new file mode 100644
index 0000000..1beffc8
--- /dev/null
+++ b/libs/functional/hash/test/link_test_2.cpp
@@ -0,0 +1,10 @@
+
+// Copyright 2005-2009 Daniel James.
+// 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)
+
+#include "./config.hpp"
+
+#include <boost/functional/hash.hpp>
+
+int f() { return 0; }
diff --git a/libs/functional/hash/test/namespace_fail_test.cpp b/libs/functional/hash/test/namespace_fail_test.cpp
new file mode 100644
index 0000000..1db9fc6
--- /dev/null
+++ b/libs/functional/hash/test/namespace_fail_test.cpp
@@ -0,0 +1,16 @@
+
+// Copyright 2009 Daniel James.
+// 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)
+
+// Check that I haven't inadvertantly pulled namespace std into the global
+// namespace.
+
+#include "./config.hpp"
+
+#include <list>
+#include <boost/functional/hash.hpp>
+
+typedef list<int> foo;
+
+int main() {}