From cc8d3636e891d22d033b3a6af767c2fe94fea293 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 13 Oct 2007 18:34:25 +0000 Subject: [PATCH] Add support for complex numbers to Boost.Hash [SVN r39983] --- doc/ref.xml | 14 ++++ include/boost/functional/hash/hash.hpp | 4 + test/Jamfile.v2 | 1 + test/hash_complex_test.cpp | 108 +++++++++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 test/hash_complex_test.cpp diff --git a/doc/ref.xml b/doc/ref.xml index fbbafae..0ce8318 100644 --- a/doc/ref.xml +++ b/doc/ref.xml @@ -708,6 +708,14 @@ for(; first != last; ++first) std::multimap<K, T, C, A> const& + + + std::size_t + std::complex<T> const& + + Generally shouldn't be called directly by users, instead they should use boost::hash, boost::hash_range @@ -784,6 +792,12 @@ for(; first != last; ++first) hash_combine(seed, val.second); return seed; + + + std::complex<T> + + When T is a built in type and val.imag() == 0, the result is equal to hash_value(val.real()). Otherwise an unspecified value, except that equal arguments shall yield the same result. + diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index e9a9a1c..4244989 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -88,6 +88,9 @@ namespace boost template std::size_t hash_value(std::multimap const& v); + template + std::size_t hash_value(std::complex const&); + // Implementation namespace hash_detail @@ -138,6 +141,7 @@ namespace boost { return static_cast(v); } + inline std::size_t hash_value(char v) { return static_cast(v); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 55789a8..1f6b14f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -33,6 +33,7 @@ test-suite functional/hash [ run hash_deque_test.cpp ] [ run hash_set_test.cpp ] [ run hash_map_test.cpp ] + [ run hash_complex_test.cpp ] [ run link_test.cpp link_test_2.cpp ] [ run link_ext_test.cpp link_no_ext_test.cpp ] [ run container_fwd_test.cpp ] diff --git a/test/hash_complex_test.cpp b/test/hash_complex_test.cpp new file mode 100644 index 0000000..a0707b5 --- /dev/null +++ b/test/hash_complex_test.cpp @@ -0,0 +1,108 @@ + +// Copyright 2005-2007 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include "./config.hpp" + +#ifdef TEST_EXTENSIONS +# ifdef TEST_STD_INCLUDES +# include +# else +# include +# endif +#endif + +#include + +#ifdef TEST_EXTENSIONS + +#include +#include +#include + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4244) // conversion from 'unsigned long' to 'unsigned short', possible loss of data +#pragma warning(disable:4512) // assignment operator could not be generated +#endif + +#include +#include +#include +#include + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +template +void generic_complex_tests(std::complex v) +{ + HASH_NAMESPACE::hash > complex_hasher; + + BOOST_TEST(complex_hasher(v) == complex_hasher(v)); + + HASH_NAMESPACE::hash real_hasher; + T real = v.real(); + T imag = v.imag(); + + BOOST_TEST(real_hasher(real) == complex_hasher(std::complex(real))); + + if(imag != 0 && real_hasher(real) == complex_hasher(v)) { + std::ostringstream os; + os<<"real_hasher("< +void complex_float_tests(Float*) +{ + boost::mt19937 rng; + boost::uniform_real uniform; + boost::variate_generator > + uniform_generator(rng, uniform); + + for(int i = 0; i < 100; ++i) + { + std::complex v(uniform_generator(), uniform_generator()); + generic_complex_tests(v); + } +} + +template +void complex_integral_tests(Integer*) +{ + boost::mt19937 rng; + boost::uniform_int uniform( + (std::numeric_limits::min)(), + (std::numeric_limits::max)()); + boost::variate_generator > + uniform_generator(rng, uniform); + + for(int i = 0; i < 100; ++i) + { + std::complexv(uniform_generator(), uniform_generator()); + generic_complex_tests(v); + } +} + +int main() +{ + 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 boost::report_errors(); +} + +#endif