forked from boostorg/container_hash
Compare commits
8 Commits
feature/be
...
feature/si
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f86cdfe502 | ||
|
|
c28d0b813b | ||
|
|
e39bf42dfc | ||
|
|
58502fddca | ||
|
|
5701dd3119 | ||
|
|
53c12550fa | ||
|
|
561cc5d010 | ||
|
|
bdf4bfe910 |
@@ -1,5 +1,6 @@
|
||||
// Copyright 2005-2014 Daniel James.
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Copyright 2022 Glen Joseph Fernandes (glenjofe@gmail.com)
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
@@ -77,11 +78,11 @@ namespace boost
|
||||
{
|
||||
template<class T,
|
||||
bool bigger_than_size_t = (sizeof(T) > sizeof(std::size_t)),
|
||||
std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT,
|
||||
std::size_t type_bits = sizeof(T) * CHAR_BIT>
|
||||
bool is_unsigned = boost::is_unsigned<T>::value,
|
||||
std::size_t blocks = sizeof(T) / sizeof(std::size_t)>
|
||||
struct hash_integral_impl;
|
||||
|
||||
template<class T, std::size_t size_t_bits, std::size_t type_bits> struct hash_integral_impl<T, false, size_t_bits, type_bits>
|
||||
template<class T, bool is_unsigned, std::size_t blocks> struct hash_integral_impl<T, false, is_unsigned, blocks>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
@@ -89,41 +90,53 @@ namespace boost
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct hash_integral_impl<T, true, 32, 64>
|
||||
template<class T, std::size_t blocks> struct hash_integral_impl<T, true, false, blocks>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
typedef typename boost::make_unsigned<T>::type U;
|
||||
|
||||
if( v >= 0 )
|
||||
{
|
||||
return hash_integral_impl<U>::fn( static_cast<U>( v ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ~hash_integral_impl<U>::fn( static_cast<U>( ~static_cast<U>( v ) ) );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct hash_integral_impl<T, true, true, 2>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
enum {
|
||||
M = sizeof(std::size_t) * CHAR_BIT
|
||||
};
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed ^= static_cast<std::size_t>( v >> 32 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v >> M ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct hash_integral_impl<T, true, 32, 128>
|
||||
template<class T> struct hash_integral_impl<T, true, true, 4>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
enum {
|
||||
M1 = sizeof(std::size_t) * CHAR_BIT,
|
||||
M2 = M1 + M1,
|
||||
M3 = M2 + M1
|
||||
};
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed ^= static_cast<std::size_t>( v >> 96 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v >> 64 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v >> 32 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct hash_integral_impl<T, true, 64, 128>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed ^= static_cast<std::size_t>( v >> 64 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v >> M3 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v >> M2 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v >> M1 ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
seed ^= static_cast<std::size_t>( v ) + ( seed << 6 ) + ( seed >> 2 );
|
||||
|
||||
return seed;
|
||||
@@ -133,28 +146,12 @@ namespace boost
|
||||
} // namespace hash_detail
|
||||
|
||||
template <typename T>
|
||||
typename boost::enable_if_<boost::conjunction<boost::is_integral<T>, boost::is_unsigned<T> >::value, std::size_t>::type
|
||||
typename boost::enable_if_<boost::is_integral<T>::value, std::size_t>::type
|
||||
hash_value( T v )
|
||||
{
|
||||
return hash_detail::hash_integral_impl<T>::fn( v );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::enable_if_<boost::conjunction<boost::is_integral<T>, boost::is_signed<T> >::value, std::size_t>::type
|
||||
hash_value( T v )
|
||||
{
|
||||
typedef typename boost::make_unsigned<T>::type U;
|
||||
|
||||
if( v >= 0 )
|
||||
{
|
||||
return hash_value( static_cast<U>( v ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ~hash_value( static_cast<U>( ~static_cast<U>( v ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// enumeration types
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -79,3 +79,5 @@ local fs-path-req = "-<toolset>gcc:<cxxflags>-Wshadow" "-<toolset>gcc:<cxxflags>
|
||||
|
||||
run hash_fs_path_test.cpp /boost//filesystem/<warnings>off : : : $(fs-path-req) <toolset>msvc-14.0,<cxxstd>latest:<build>no ;
|
||||
run detail_is_range_test2.cpp : : : $(fs-path-req) ;
|
||||
|
||||
run hash_container_test.cpp ;
|
||||
|
||||
@@ -29,6 +29,7 @@ int main() {}
|
||||
// 'const std::complex<float>::_Ty'
|
||||
#pragma warning(disable:4309) // truncation of constant value
|
||||
#pragma warning(disable:4512) // assignment operator could not be generated
|
||||
#pragma warning(disable:4996) // std::complex<Integer> is deprecated
|
||||
#if BOOST_MSVC < 1400
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data
|
||||
|
||||
52
test/hash_container_test.cpp
Normal file
52
test/hash_container_test.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
|
||||
# include <forward_list>
|
||||
#endif
|
||||
|
||||
template<class T> std::size_t hv( T const& t )
|
||||
{
|
||||
return boost::hash<T>()( t );
|
||||
}
|
||||
|
||||
template<class T> void test()
|
||||
{
|
||||
for( std::size_t i = 0; i < 8; ++i )
|
||||
{
|
||||
std::vector<T> v( i );
|
||||
std::size_t h0 = hv( v );
|
||||
|
||||
std::deque<T> d( v.begin(), v.end() );
|
||||
BOOST_TEST_EQ( h0, hv( d ) );
|
||||
|
||||
std::list<T> l( v.begin(), v.end() );
|
||||
BOOST_TEST_EQ( h0, hv( l ) );
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
|
||||
|
||||
std::forward_list<T> f( v.begin(), v.end() );
|
||||
BOOST_TEST_EQ( h0, hv( f ) );
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test<char>();
|
||||
test<unsigned char>();
|
||||
test<signed char>();
|
||||
test<int>();
|
||||
test<float>();
|
||||
test<double>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#define _SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING
|
||||
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__) && __cplusplus < 201100L
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
||||
#include <string_view>
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
|
||||
# include <forward_list>
|
||||
#endif
|
||||
|
||||
// Test whether the hash values of a string and a
|
||||
// string_view that refers to it match. This is
|
||||
@@ -24,12 +30,21 @@ template<class T> std::size_t hv( T const& t )
|
||||
int main()
|
||||
{
|
||||
std::string s( "Test." );
|
||||
std::size_t h0 = hv( s );
|
||||
|
||||
BOOST_TEST_EQ( hv( s ), hv( boost::string_view( s ) ) );
|
||||
BOOST_TEST_EQ( hv( s ), hv( boost::core::string_view( s ) ) );
|
||||
BOOST_TEST_EQ( h0, hv( boost::string_view( s ) ) );
|
||||
BOOST_TEST_EQ( h0, hv( boost::core::string_view( s ) ) );
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
||||
BOOST_TEST_EQ( hv( s ), hv( std::string_view( s ) ) );
|
||||
BOOST_TEST_EQ( h0, hv( std::string_view( s ) ) );
|
||||
#endif
|
||||
|
||||
BOOST_TEST_EQ( h0, hv( std::vector<char>( s.begin(), s.end() ) ) );
|
||||
BOOST_TEST_EQ( h0, hv( std::deque<char>( s.begin(), s.end() ) ) );
|
||||
BOOST_TEST_EQ( h0, hv( std::list<char>( s.begin(), s.end() ) ) );
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
|
||||
BOOST_TEST_EQ( h0, hv( std::forward_list<char>( s.begin(), s.end() ) ) );
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
|
||||
Reference in New Issue
Block a user