diff --git a/.appveyor.yml b/.appveyor.yml index 76189c2..61c7e7f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -14,6 +14,7 @@ environment: TOOLSET: msvc-14.0 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 TOOLSET: msvc-14.1 + CXXSTD: 14,17 install: - cd c:\projects @@ -29,5 +30,7 @@ install: build: off test_script: + - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% - cd %APPVEYOR_BUILD_FOLDER%\test - - cmd /c %BOOST_ROOT%\tools\build\b2 -j 3 toolset=%TOOLSET% include=%APPVEYOR_BUILD_FOLDER%\include include=%BOOST_ROOT% + - cmd /c %BOOST_ROOT%\tools\build\b2 -j 3 toolset=%TOOLSET% %CXXSTD% include=%APPVEYOR_BUILD_FOLDER%\include include=%BOOST_ROOT% --verbose-test hash_info + - cmd /c %BOOST_ROOT%\tools\build\b2 -j 3 toolset=%TOOLSET% %CXXSTD% include=%APPVEYOR_BUILD_FOLDER%\include include=%BOOST_ROOT% diff --git a/doc/changes.qbk b/doc/changes.qbk index 60d17c8..459a15d 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -216,5 +216,7 @@ preprocessor to generate them. Should improve usability, due to better error messages, and easier debugging. * Fix tutorial example ([ticket 11017]). +* Quick fix for hashing `vector` when using libc++. Will try to introduce + a more general fix in the next release. [endsect] diff --git a/include/boost/container_hash/extensions.hpp b/include/boost/container_hash/extensions.hpp index 393b702..4eebb4b 100644 --- a/include/boost/container_hash/extensions.hpp +++ b/include/boost/container_hash/extensions.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #if !defined(BOOST_NO_CXX11_HDR_ARRAY) # include @@ -70,6 +71,56 @@ namespace boost return seed; } + inline std::size_t hash_range( + std::vector::iterator first, + std::vector::iterator last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + + return seed; + } + + inline std::size_t hash_range( + std::vector::const_iterator first, + std::vector::const_iterator last) + { + std::size_t seed = 0; + + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + + return seed; + } + + inline void hash_range( + std::size_t& seed, + std::vector::iterator first, + std::vector::iterator last) + { + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + } + + inline void hash_range( + std::size_t& seed, + std::vector::const_iterator first, + std::vector::const_iterator last) + { + for(; first != last; ++first) + { + hash_combine(seed, *first); + } + } + template std::size_t hash_value(std::vector const& v) { diff --git a/test/hash_info.cpp b/test/hash_info.cpp index 34378f5..b683746 100644 --- a/test/hash_info.cpp +++ b/test/hash_info.cpp @@ -39,7 +39,8 @@ void write_compiler_info() { {1900, "Visual C++ 14.00, VS2015"}, {1910, "Visual C++ 14.10, VS2017 15.1/2"}, {1911, "Visual C++ 14.11, VS2017 15.3/4"}, - {1912, "Visual C++ 14.12, VS2017 15.5"} + {1912, "Visual C++ 14.12, VS2017 15.5"}, + {1913, "Visual C++ 14.13, VS2017 15.6"} }; msvc_version msvc = { BOOST_MSVC, "" }; diff --git a/test/hash_vector_test.cpp b/test/hash_vector_test.cpp index 752438f..9e63f5b 100644 --- a/test/hash_vector_test.cpp +++ b/test/hash_vector_test.cpp @@ -25,11 +25,44 @@ using std::vector; #endif // BOOST_HASH_TEST_EXTENSIONS +namespace vector_bool_tests +{ + void vector_bool_test() { + std::vector x_empty1,x_empty2,x1,x1a,x2,x3; + + x1.push_back(0); + x1a.push_back(0); + x2.push_back(1); + x3.push_back(0); + x3.push_back(0); + + BOOST_HASH_TEST_NAMESPACE::hash > hasher; + + BOOST_TEST_EQ(hasher(x_empty1), hasher(x_empty1)); + BOOST_TEST_EQ(hasher(x_empty1), hasher(x_empty2)); + BOOST_TEST_NE(hasher(x_empty1), hasher(x1)); + BOOST_TEST_NE(hasher(x_empty1), hasher(x2)); + BOOST_TEST_NE(hasher(x_empty1), hasher(x3)); + + BOOST_TEST_EQ(hasher(x1), hasher(x1)); + BOOST_TEST_EQ(hasher(x1), hasher(x1a)); + BOOST_TEST_NE(hasher(x1), hasher(x2)); + BOOST_TEST_NE(hasher(x1), hasher(x3)); + + BOOST_TEST_EQ(hasher(x2), hasher(x2)); + BOOST_TEST_NE(hasher(x2), hasher(x3)); + + BOOST_TEST_EQ(hasher(x3), hasher(x3)); + } +} + int main() { #ifdef BOOST_HASH_TEST_EXTENSIONS vector_tests::vector_hash_integer_tests(); #endif + vector_bool_tests::vector_bool_test(); + return boost::report_errors(); }