Boost logo

Boost-Commit :

From: daniel_james_at_[hidden]
Date: 2007-10-13 14:34:25


Author: danieljames
Date: 2007-10-13 14:34:25 EDT (Sat, 13 Oct 2007)
New Revision: 39983
URL: http://svn.boost.org/trac/boost/changeset/39983

Log:
Add support for complex numbers to Boost.Hash

Added:
   trunk/libs/functional/hash/test/hash_complex_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/functional/hash/hash.hpp | 4 ++++
   trunk/libs/functional/hash/doc/ref.xml | 14 ++++++++++++++
   trunk/libs/functional/hash/test/Jamfile.v2 | 1 +
   3 files changed, 19 insertions(+), 0 deletions(-)

Modified: trunk/boost/functional/hash/hash.hpp
==============================================================================
--- trunk/boost/functional/hash/hash.hpp (original)
+++ trunk/boost/functional/hash/hash.hpp 2007-10-13 14:34:25 EDT (Sat, 13 Oct 2007)
@@ -88,6 +88,9 @@
     template <class K, class T, class C, class A>
     std::size_t hash_value(std::multimap<K, T, C, A> const& v);
 
+ template <class T>
+ std::size_t hash_value(std::complex<T> const&);
+
     // Implementation
 
     namespace hash_detail
@@ -138,6 +141,7 @@
     {
         return static_cast<std::size_t>(v);
     }
+
     inline std::size_t hash_value(char v)
     {
         return static_cast<std::size_t>(v);

Modified: trunk/libs/functional/hash/doc/ref.xml
==============================================================================
--- trunk/libs/functional/hash/doc/ref.xml (original)
+++ trunk/libs/functional/hash/doc/ref.xml 2007-10-13 14:34:25 EDT (Sat, 13 Oct 2007)
@@ -708,6 +708,14 @@
           <parameter name="val"><paramtype>std::multimap&lt;K, T, C, A&gt; const&amp;</paramtype></parameter>
         </signature>
 
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type>std::size_t</type>
+ <parameter name="val"><paramtype>std::complex&lt;T&gt; const&amp;</paramtype></parameter>
+ </signature>
+
         <description><para>
           Generally shouldn't be called directly by users, instead they should use
           <classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
@@ -784,6 +792,12 @@
 <functionname>hash_combine</functionname>(seed, val.second);
 return seed;</programlisting></entry>
                 </row>
+ <row>
+ <entry>
+ <code>std::complex&lt;T&gt;</code>
+ </entry>
+ <entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
+ </row>
               </tbody>
             </tgroup>
           </informaltable>

Modified: trunk/libs/functional/hash/test/Jamfile.v2
==============================================================================
--- trunk/libs/functional/hash/test/Jamfile.v2 (original)
+++ trunk/libs/functional/hash/test/Jamfile.v2 2007-10-13 14:34:25 EDT (Sat, 13 Oct 2007)
@@ -33,6 +33,7 @@
         [ 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 ]

Added: trunk/libs/functional/hash/test/hash_complex_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/functional/hash/test/hash_complex_test.cpp 2007-10-13 14:34:25 EDT (Sat, 13 Oct 2007)
@@ -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 <functional>
+# else
+# include <boost/functional/hash.hpp>
+# endif
+#endif
+
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef TEST_EXTENSIONS
+
+#include <complex>
+#include <sstream>
+#include <boost/limits.hpp>
+
+#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 <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/variate_generator.hpp>
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+template <class T>
+void generic_complex_tests(std::complex<T> v)
+{
+ HASH_NAMESPACE::hash<std::complex<T> > complex_hasher;
+
+ BOOST_TEST(complex_hasher(v) == complex_hasher(v));
+
+ HASH_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*)
+{
+ boost::mt19937 rng;
+ boost::uniform_real<Float> uniform;
+ boost::variate_generator<boost::mt19937&, boost::uniform_real<Float> >
+ uniform_generator(rng, uniform);
+
+ for(int i = 0; i < 100; ++i)
+ {
+ std::complex<Float> v(uniform_generator(), uniform_generator());
+ generic_complex_tests(v);
+ }
+}
+
+template <class Integer>
+void complex_integral_tests(Integer*)
+{
+ boost::mt19937 rng;
+ boost::uniform_int<Integer> uniform(
+ (std::numeric_limits<Integer>::min)(),
+ (std::numeric_limits<Integer>::max)());
+ boost::variate_generator<boost::mt19937&, boost::uniform_int<Integer> >
+ uniform_generator(rng, uniform);
+
+ for(int i = 0; i < 100; ++i)
+ {
+ std::complex<Integer>v(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


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk