mirror of
https://github.com/boostorg/functional.git
synced 2025-08-02 05:54:29 +02:00
Merge latest hash developments:
* Avoid float to int warning. * Work around 'using namespace' bug in Visual C++. * Make `<boost/functional/hash/extensions.hpp> self contained. * Move some of the extension implementation from the main hash header into the exensions header. * Remove BOOST_HASH_CHAR_TRAITS from `container_fwd.hpp`. * Other minor changes. Merged revisions 53828,53924,54024-54025,54033-54034,54139-54145,54399 via svnmerge from https://svn.boost.org/svn/boost/trunk ........ r53828 | danieljames | 2009-06-12 19:24:47 +0100 (Fri, 12 Jun 2009) | 1 line Try to avoid float to int warning when a float function doesn't exist. ........ r53924 | danieljames | 2009-06-15 08:37:42 +0100 (Mon, 15 Jun 2009) | 4 lines Remove hash_complex_test's dependency on Boost.Random. Only test for a few values, but that should be okay as there isn't much to test. ........ r54024 | danieljames | 2009-06-17 22:22:49 +0100 (Wed, 17 Jun 2009) | 1 line Put the minimum amount of implementation in the same namespace as the 'using namespace' directives in order to avoid Visual C++ 8 bug. ........ r54025 | danieljames | 2009-06-17 22:23:42 +0100 (Wed, 17 Jun 2009) | 1 line Try to avoid using special macro handling code. ........ r54033 | danieljames | 2009-06-18 00:24:28 +0100 (Thu, 18 Jun 2009) | 1 line Add copyright to namespace_fail_test.cpp ........ r54034 | danieljames | 2009-06-18 00:25:12 +0100 (Thu, 18 Jun 2009) | 1 line A couple of missing newlines. ........ r54139 | danieljames | 2009-06-21 10:41:11 +0100 (Sun, 21 Jun 2009) | 1 line A few more comments in boost::hash. ........ r54140 | danieljames | 2009-06-21 10:41:30 +0100 (Sun, 21 Jun 2009) | 1 line Move includes to the header which they're used in. ........ r54141 | danieljames | 2009-06-21 10:41:46 +0100 (Sun, 21 Jun 2009) | 1 line Revert [54025] "Try to avoid using special macro handling code." ........ r54142 | danieljames | 2009-06-21 10:42:05 +0100 (Sun, 21 Jun 2009) | 1 line Get <boost/functional/hash/extensions.hpp> to work. ........ r54143 | danieljames | 2009-06-21 10:42:20 +0100 (Sun, 21 Jun 2009) | 1 line Move BOOST_HASH_CHAR_TRAITS from container_fwd into the hash headers, and undefine it. ........ r54144 | danieljames | 2009-06-21 10:42:40 +0100 (Sun, 21 Jun 2009) | 1 line Move the support for hashing containers into the extension header, and improve the standard tests. ........ r54145 | danieljames | 2009-06-21 10:51:59 +0100 (Sun, 21 Jun 2009) | 1 line I didn't mean to comment this out. ........ r54399 | danieljames | 2009-06-27 08:39:12 +0100 (Sat, 27 Jun 2009) | 1 line Add am implementation note about the Visual C++ problems. ........ [SVN r54402]
This commit is contained in:
@@ -36,10 +36,23 @@ test-suite functional/hash
|
||||
[ run hash_complex_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 ]
|
||||
[ run container_fwd_test.cpp ]
|
||||
[ compile-fail hash_no_ext_fail_test.cpp ]
|
||||
[ compile-fail namespace_fail_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 ]
|
||||
;
|
||||
|
||||
build-project ../examples ;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
#if defined(TEST_STD)
|
||||
# define TEST_STD_INCLUDES
|
||||
# define HASH_NAMESPACE std::tr1
|
||||
# define HASH_NAMESPACE std
|
||||
#else
|
||||
# define HASH_NAMESPACE boost
|
||||
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||
|
17
hash/test/extensions_hpp_test.cpp
Normal file
17
hash/test/extensions_hpp_test.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
// 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 <boost/functional/hash/extensions.hpp>
|
||||
|
||||
int main() {
|
||||
int x[2] = { 2, 3 };
|
||||
boost::hash<int[2]> hf;
|
||||
hf(x);
|
||||
}
|
@@ -5,18 +5,20 @@
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# endif
|
||||
#if !defined(TEST_EXTENSIONS)
|
||||
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
|
||||
#include <complex>
|
||||
#include <sstream>
|
||||
#include <boost/limits.hpp>
|
||||
@@ -27,11 +29,6 @@
|
||||
#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
|
||||
@@ -61,33 +58,24 @@ void generic_complex_tests(std::complex<T> v)
|
||||
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);
|
||||
}
|
||||
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(-67.5324535,56.23578678));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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()
|
||||
@@ -105,4 +93,4 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // TEST_EXTENSIONS
|
||||
|
@@ -15,6 +15,8 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/functional/hash/detail/limits.hpp>
|
||||
#include <boost/functional/hash/detail/float_functions.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -42,8 +44,6 @@ void float_tests(char const* name, T* = 0)
|
||||
<<"\n"
|
||||
<<"boost::hash_detail::call_ldexp<T>::float_type = "
|
||||
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_ldexp<T>::float_type*)0)<<"\n"
|
||||
<<"boost::call_frexp<T>::float_type = "
|
||||
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_frexp<T>::float_type*)0)<<"\n"
|
||||
<<"boost::hash_detail::call_frexp<T>::float_type = "
|
||||
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_frexp<T>::float_type*)0)<<"\n"
|
||||
<<"boost::hash_detail::select_hash_type<T>::type = "
|
||||
@@ -59,8 +59,10 @@ void float_tests(char const* name, T* = 0)
|
||||
BOOST_TEST(zero == minus_zero);
|
||||
BOOST_TEST(x1(zero) == x1(minus_zero));
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
|
||||
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -78,9 +80,11 @@ void float_tests(char const* name, T* = 0)
|
||||
T minus_infinity2 = (T) -1. / zero;
|
||||
T minus_infinity3 = (T) 1. / minus_zero;
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
|
||||
BOOST_TEST(x1(minus_infinity)
|
||||
== HASH_NAMESPACE::hash_value(minus_infinity));
|
||||
#endif
|
||||
|
||||
if(infinity == infinity2)
|
||||
BOOST_TEST(x1(infinity) == x1(infinity2));
|
||||
@@ -134,10 +138,12 @@ void float_tests(char const* name, T* = 0)
|
||||
BOOST_TEST(half_max != three_quarter_max);
|
||||
BOOST_TEST(quarter_max != three_quarter_max);
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
|
||||
BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
|
||||
BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
|
||||
BOOST_TEST(x1(three_quarter_max) == HASH_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));
|
||||
@@ -159,12 +165,18 @@ void float_tests(char const* name, T* = 0)
|
||||
T v2 = acos((T) 0);
|
||||
if(v1 == v2)
|
||||
BOOST_TEST(x1(v1) == x1(v2));
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
|
||||
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
|
||||
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::epsilon()));
|
||||
#endif
|
||||
|
||||
BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0);
|
||||
if(x1(boost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
|
||||
@@ -195,7 +207,7 @@ void float_tests(char const* name, T* = 0)
|
||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
|
||||
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
|
||||
}
|
||||
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006)
|
||||
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(TEST_EXTENSIONS)
|
||||
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
|
||||
// specialization of boost::hash_detail::limits::denorm_min() for long
|
||||
// doubles which causes this test to fail.
|
||||
@@ -213,7 +225,7 @@ void float_tests(char const* name, T* = 0)
|
||||
}
|
||||
|
||||
// NaN also causes borland to crash.
|
||||
#if !defined(__BORLANDC__)
|
||||
#if !defined(__BORLANDC__) && defined(TEST_EXTENSIONS)
|
||||
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
|
||||
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
|
||||
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
|
||||
|
@@ -6,8 +6,13 @@
|
||||
// This test just makes sure a header which uses hash_fwd can compile without
|
||||
// the main hash headers.
|
||||
|
||||
#include "./hash_fwd_test.hpp"
|
||||
#if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES)
|
||||
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include "./hash_fwd_test.hpp"
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
template <class T> void unused(T const&) {}
|
||||
@@ -30,10 +35,11 @@ void fwd_test()
|
||||
unused(y1); unused(y2); unused(y3);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
fwd_test();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
||||
|
@@ -4,9 +4,17 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define HASH_NAMESPACE boost
|
||||
|
||||
// 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>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <deque>
|
||||
#include <cassert>
|
||||
|
@@ -4,10 +4,17 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define HASH_NAMESPACE boost
|
||||
|
||||
// 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>
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <map>
|
||||
|
||||
|
@@ -5,18 +5,20 @@
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# endif
|
||||
#if !defined(TEST_EXTENSIONS)
|
||||
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
@@ -74,8 +76,6 @@ void hash_range_tests()
|
||||
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
hash_range_tests();
|
||||
@@ -83,3 +83,4 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // TEST_EXTESNIONS
|
||||
|
@@ -9,14 +9,23 @@
|
||||
#include <vector>
|
||||
|
||||
int f(std::size_t hash1, int* x1) {
|
||||
|
||||
// Check that HASH_NAMESPACE::hash<int*> works in both files.
|
||||
HASH_NAMESPACE::hash<int*> ptr_hasher;
|
||||
BOOST_TEST(hash1 == ptr_hasher(x1));
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
|
||||
// Check that std::vector<std::size_t> is avaiable in this file.
|
||||
std::vector<std::size_t> x;
|
||||
x.push_back(*x1);
|
||||
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
|
||||
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x);
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
14
hash/test/namespace_fail_test.cpp
Normal file
14
hash/test/namespace_fail_test.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
// 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 <list>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
typedef list<int> foo;
|
||||
|
||||
int main() {}
|
@@ -96,10 +96,16 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS {
|
||||
// Then the call_* functions select an appropriate implementation.
|
||||
//
|
||||
// I used c99_func in a few places just to get a unique name.
|
||||
//
|
||||
// Important: when using 'using namespace' at namespace level, include as
|
||||
// little as possible in that namespace, as Visual C++ has an odd bug which
|
||||
// can cause the namespace to be imported at the global level. This seems to
|
||||
// happen mainly when there's a template in the same namesapce.
|
||||
|
||||
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
|
||||
namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \
|
||||
boost::hash_detail::not_found c99_func(int, type2); \
|
||||
template <class Float> \
|
||||
boost::hash_detail::not_found c99_func(Float, type2); \
|
||||
} \
|
||||
\
|
||||
namespace boost { \
|
||||
@@ -117,44 +123,46 @@ namespace boost { \
|
||||
BOOST_STATIC_CONSTANT(bool, c99 = \
|
||||
sizeof(float_type(c99_func(x,y))) \
|
||||
== sizeof(is<type1>)); \
|
||||
}; \
|
||||
\
|
||||
template <bool x> \
|
||||
struct call_c99 : \
|
||||
boost::hash_detail::call_##cpp_func<double> {}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_c99<true> { \
|
||||
typedef type1 float_type; \
|
||||
\
|
||||
template <typename T> \
|
||||
inline type1 operator()(type1 a, T b) const \
|
||||
{ \
|
||||
return c99_func(a, b); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <bool x> \
|
||||
struct call_cpp : \
|
||||
call_c99< \
|
||||
::boost::hash_detail::c99_func##_detect::check::c99 \
|
||||
> {}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_cpp<true> { \
|
||||
typedef type1 float_type; \
|
||||
\
|
||||
template <typename T> \
|
||||
inline type1 operator()(type1 a, T b) const \
|
||||
{ \
|
||||
return cpp_func(a, b); \
|
||||
} \
|
||||
}; \
|
||||
} \
|
||||
\
|
||||
template <bool x> \
|
||||
struct call_c99_##c99_func : \
|
||||
boost::hash_detail::call_##cpp_func<double> {}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_c99_##c99_func<true> { \
|
||||
typedef type1 float_type; \
|
||||
\
|
||||
template <typename T> \
|
||||
inline type1 operator()(type1 a, T b) const \
|
||||
{ \
|
||||
using namespace std; \
|
||||
return c99_func(a, b); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <bool x> \
|
||||
struct call_cpp_##c99_func : \
|
||||
call_c99_##c99_func< \
|
||||
::boost::hash_detail::c99_func##_detect::check::c99 \
|
||||
> {}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_cpp_##c99_func<true> { \
|
||||
typedef type1 float_type; \
|
||||
\
|
||||
template <typename T> \
|
||||
inline type1 operator()(type1 a, T b) const \
|
||||
{ \
|
||||
using namespace std; \
|
||||
return cpp_func(a, b); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_##cpp_func<type1> : \
|
||||
c99_func##_detect::call_cpp< \
|
||||
call_cpp_##c99_func< \
|
||||
::boost::hash_detail::c99_func##_detect::check::cpp \
|
||||
> {}; \
|
||||
} \
|
||||
|
@@ -7,15 +7,114 @@
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
// This implements the extensions to the standard.
|
||||
// It's undocumented, so you shouldn't use it....
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
|
||||
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include <boost/detail/container_fwd.hpp>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v);
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v);
|
||||
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&);
|
||||
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const& v)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, v.first);
|
||||
hash_combine(seed, v.second);
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::size_t hash_value(std::complex<T> const& v)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
std::size_t seed = hasher(v.imag());
|
||||
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
|
||||
return seed;
|
||||
}
|
||||
|
||||
//
|
||||
// call_hash_impl
|
||||
//
|
||||
|
||||
// On compilers without function template ordering, this deals with arrays.
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
namespace hash_detail
|
||||
@@ -61,6 +160,11 @@ namespace boost
|
||||
}
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
//
|
||||
// boost::hash
|
||||
//
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <class T> struct hash
|
||||
@@ -94,7 +198,7 @@ namespace boost
|
||||
|
||||
// On compilers without partial specialization, boost::hash<T>
|
||||
// has already been declared to deal with pointers, so just
|
||||
// need to supply the non-pointer version.
|
||||
// need to supply the non-pointer version of hash_impl.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
@@ -126,8 +230,8 @@ namespace boost
|
||||
|
||||
#else // Visual C++ 6.5
|
||||
|
||||
// There's probably a more elegant way to Visual C++ 6.5 to work
|
||||
// but I don't know what it is.
|
||||
// Visual C++ 6.5 has problems with nested member functions and
|
||||
// applying const to const types in templates. So we get this:
|
||||
|
||||
template <bool IsConst>
|
||||
struct hash_impl_msvc
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <boost/functional/hash/hash_fwd.hpp>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash/detail/hash_float.hpp>
|
||||
#include <boost/detail/container_fwd.hpp>
|
||||
#include <string>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
@@ -21,12 +20,10 @@
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
#define BOOST_HASH_CHAR_TRAITS string_char_traits
|
||||
#else
|
||||
#define BOOST_HASH_CHAR_TRAITS char_traits
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
@@ -72,26 +69,6 @@ namespace boost
|
||||
template <class Ch, class A>
|
||||
std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
|
||||
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v);
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v);
|
||||
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
|
||||
@@ -315,69 +292,21 @@ namespace boost
|
||||
return boost::hash_detail::float_hash_value(v);
|
||||
}
|
||||
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const& v)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, v.first);
|
||||
hash_combine(seed, v.second);
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::size_t hash_value(std::complex<T> const& v)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
std::size_t seed = hasher(v.imag());
|
||||
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
|
||||
return seed;
|
||||
}
|
||||
|
||||
//
|
||||
// boost::hash
|
||||
//
|
||||
|
||||
// Define the specializations required by the standard. The general purpose
|
||||
// boost::hash is defined later in extensions.hpp if BOOST_HASH_NO_EXTENSIONS
|
||||
// is not defined.
|
||||
|
||||
// BOOST_HASH_SPECIALIZE - define a specialization for a type which is
|
||||
// passed by copy.
|
||||
//
|
||||
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
|
||||
// passed by copy.
|
||||
//
|
||||
// These are undefined later.
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
#define BOOST_HASH_SPECIALIZE(type) \
|
||||
@@ -462,10 +391,18 @@ namespace boost
|
||||
BOOST_HASH_SPECIALIZE_REF(std::wstring)
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
BOOST_HASH_SPECIALIZE(boost::long_long_type);
|
||||
BOOST_HASH_SPECIALIZE(boost::ulong_long_type);
|
||||
#endif
|
||||
|
||||
#undef BOOST_HASH_SPECIALIZE
|
||||
#undef BOOST_HASH_SPECIALIZE_REF
|
||||
|
||||
// Specializing boost::hash for pointers.
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <class T>
|
||||
struct hash<T*>
|
||||
: public std::unary_function<T*, std::size_t>
|
||||
@@ -482,7 +419,15 @@ namespace boost
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// For compilers without partial specialization, we define a
|
||||
// boost::hash for all remaining types. But hash_impl is only defined
|
||||
// for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
|
||||
// is defined there will still be a compile error for types not supported
|
||||
// in the standard.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsPointer>
|
||||
@@ -515,9 +460,12 @@ namespace boost
|
||||
::BOOST_NESTED_TEMPLATE inner<T>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef BOOST_HASH_CHAR_TRAITS
|
||||
|
||||
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||
|
||||
// Include this outside of the include guards in case the file is included
|
||||
|
Reference in New Issue
Block a user