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/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() {}