// Copyright 2017, 2024 Peter Dimov. // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // lib1.hpp #include #include // forward declarations namespace boost { namespace hash2 { template BOOST_CXX14_CONSTEXPR void hash_append( Hash& h, Flavor const& f, T const& v ); struct hash_append_tag; } // namespace hash2 } // namespace boost // lib1::X namespace lib1 { class X { private: std::string s1_; std::string s2_; template friend void tag_invoke( boost::hash2::hash_append_tag const&, Hash& h, Flavor const& f, X const& x ) { boost::hash2::hash_append( h, f, x.s1_ ); boost::hash2::hash_append( h, f, x.s2_ ); } public: X(): s1_( "s1" ), s2_( "s2" ) { } }; } // namespace lib1 // lib2.hpp #include #include namespace lib2 { class fnv1a { private: std::uint32_t st_; public: typedef std::uint32_t result_type; fnv1a(): st_( 0x811C9DC5ul ) { } void update( void const* pv, std::size_t n ) { unsigned char const* p = static_cast( pv ); std::uint32_t h = st_; for( std::size_t i = 0; i < n; ++i ) { h ^= static_cast( p[i] ); h *= 0x01000193ul; } st_ = h; } std::uint32_t result() { std::uint32_t r = st_; st_ = ( st_ ^ 0xFF ) * 0x01000193ul; return r; } }; } // namespace lib2 // test #include #include #include #include #include template void test( R r ) { { Hash h; Flavor f; boost::hash2::hash_append( h, f, std::vector( 3 ) ); BOOST_TEST_EQ( h.result(), r ); } { Hash h; Flavor f; boost::hash2::hash_append( h, f, std::list( 3 ) ); BOOST_TEST_EQ( h.result(), r ); } } int main() { test( 4058687743ul ); test( 4058687743ul ); return boost::report_errors(); }