diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dd5a72c..da47e04 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -10,6 +10,8 @@ alias framework : /boost/test//boost_unit_test_framework ; test-suite functional/hash : + [ run hash_fwd_test_1.cpp framework ] + [ run hash_fwd_test_2.cpp framework ] [ run hash_number_test.cpp framework ] [ run hash_pointer_test.cpp framework ] [ run hash_function_pointer_test.cpp framework ] diff --git a/test/hash_fwd_test.hpp b/test/hash_fwd_test.hpp new file mode 100644 index 0000000..475725d --- /dev/null +++ b/test/hash_fwd_test.hpp @@ -0,0 +1,94 @@ +// (C) Copyright Daniel James 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include "./config.hpp" + +#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES) +#include + +#include + +template +struct test_type1 +{ + T value; + test_type1(T const& x) : value(x) {} + +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + friend std::size_t hash_value(test_type1 const& x) + { + HASH_NAMESPACE::hash hasher; + return hasher(x.value); + } +#endif +}; + +template +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) + friend std::size_t hash_value(test_type2 const& x) + { + std::size_t seed = 0; + boost::hash_combine(seed, x.value1); + boost::hash_combine(seed, x.value2); + return seed; + } +#endif +}; + +template +struct test_type3 +{ + std::vector values; + test_type3(typename std::vector::iterator x, + typename std::vector::iterator y) : values(x, y) {} + +#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + friend std::size_t hash_value(test_type3 const& x) + { + std::size_t seed = boost::hash_range(x.values.begin(), x.values.end()); + boost::hash_range(seed, x.values.begin(), x.values.end()); + return seed; + } +#endif +}; + + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOPUP) + +namespace boost +{ + template + std::size_t hash_value(test_type1 const& x) + { + HASH_NAMESPACE::hash hasher; + return hasher(x.value); + } + + template + std::size_t hash_value(test_type2 const& x) + { + std::size_t seed = 0; + boost::hash_combine(seed, x.value1); + boost::hash_combine(seed, x.value2); + return seed; + } + + template + std::size_t hash_value(test_type3 const& x) + { + std::size_t seed = boost::hash_range(x.values.begin(), x.values.end()); + boost::hash_range(seed, x.values.begin(), x.values.end()); + return seed; + } +} + +#endif + +#endif diff --git a/test/hash_fwd_test_1.cpp b/test/hash_fwd_test_1.cpp new file mode 100644 index 0000000..8a66156 --- /dev/null +++ b/test/hash_fwd_test_1.cpp @@ -0,0 +1,78 @@ +// (C) Copyright Daniel James 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// This checks that template code implemented using hash_fwd will work. + +#include "./hash_fwd_test.hpp" + +#define BOOST_TEST_MAIN +#include + +#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES) + +#include +#include + +BOOST_AUTO_TEST_CASE(fwd_test1) +{ + test_type1 x(5); + test_type1 y("Test"); + + BOOST_CHECK_EQUAL( + boost::hash()(5), + boost::hash >()(x)); + + BOOST_CHECK_EQUAL( + boost::hash()("Test"), + boost::hash >()(y)); +} + +BOOST_AUTO_TEST_CASE(fwd_test2) +{ + test_type2 x(5, 10); + test_type2 y("Test1", "Test2"); + + std::size_t seed1 = 0; + boost::hash_combine(seed1, 5); + boost::hash_combine(seed1, 10); + + std::size_t seed2 = 0; + boost::hash_combine(seed2, std::string("Test1")); + boost::hash_combine(seed2, std::string("Test2")); + + BOOST_CHECK_EQUAL(seed1, + boost::hash >()(x)); + BOOST_CHECK_EQUAL(seed2, + boost::hash >()(y)); +} + +BOOST_AUTO_TEST_CASE(fwd_test3) +{ + std::vector values1; + values1.push_back(10); + values1.push_back(15); + values1.push_back(20); + values1.push_back(3); + + std::vector values2; + values2.push_back("Groucho"); + values2.push_back("Harpo"); + + test_type3 x(values1.begin(), values1.end()); + test_type3 y(values2.begin(), values2.end()); + + std::size_t seed1 = boost::hash_range(values1.begin(), values1.end()); + boost::hash_range(seed1, values1.begin(), values1.end()); + + std::size_t seed2 = boost::hash_range(values2.begin(), values2.end()); + boost::hash_range(seed2, values2.begin(), values2.end()); + + BOOST_CHECK_EQUAL(seed1, + boost::hash >()(x)); + BOOST_CHECK_EQUAL(seed2, + boost::hash >()(y)); +} + +#endif diff --git a/test/hash_fwd_test_2.cpp b/test/hash_fwd_test_2.cpp new file mode 100644 index 0000000..8eaf75f --- /dev/null +++ b/test/hash_fwd_test_2.cpp @@ -0,0 +1,32 @@ +// (C) Copyright Daniel James 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// This test just makes sure a header which uses hash_fwd can compile without +// the main hash headers. + +#include "./hash_fwd_test.hpp" + +#define BOOST_TEST_MAIN +#include + +template void unused(T const&) {} + +BOOST_AUTO_TEST_CASE(fwd_test) +{ + test_type1 x1(3); + test_type1 y1("Black"); + test_type2 x2(25, 16); + test_type2 y2("White", "Green"); + + std::vector empty; + std::vector empty2; + + test_type3 x3(empty.begin(), empty.end()); + test_type3 y3(empty2.begin(), empty2.end()); + + // Prevent gcc warnings: + unused(x1); unused(x2); unused(x3); + unused(y1); unused(y2); unused(y3); +}