LCOV - code coverage report
Current view: top level - usr/include/boost/container_hash - hash.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 21 27 77.8 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : // Copyright 2005-2014 Daniel James.
       3             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       4             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       5             : 
       6             : //  Based on Peter Dimov's proposal
       7             : //  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
       8             : //  issue 6.18.
       9             : //
      10             : //  This also contains public domain code from MurmurHash. From the
      11             : //  MurmurHash header:
      12             : 
      13             : // MurmurHash3 was written by Austin Appleby, and is placed in the public
      14             : // domain. The author hereby disclaims copyright to this source code.
      15             : 
      16             : #if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
      17             : #define BOOST_FUNCTIONAL_HASH_HASH_HPP
      18             : 
      19             : #include <boost/container_hash/hash_fwd.hpp>
      20             : #include <functional>
      21             : #include <boost/container_hash/detail/hash_float.hpp>
      22             : #include <string>
      23             : #include <boost/limits.hpp>
      24             : #include <boost/type_traits/is_enum.hpp>
      25             : #include <boost/type_traits/is_integral.hpp>
      26             : #include <boost/core/enable_if.hpp>
      27             : #include <boost/cstdint.hpp>
      28             : 
      29             : #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
      30             : #include <boost/type_traits/is_pointer.hpp>
      31             : #endif
      32             : 
      33             : #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
      34             : #include <typeindex>
      35             : #endif
      36             : 
      37             : #if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
      38             : #include <system_error>
      39             : #endif
      40             : 
      41             : #if defined(BOOST_MSVC)
      42             : #pragma warning(push)
      43             : 
      44             : #if BOOST_MSVC >= 1400
      45             : #pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values
      46             :                               // are always of range '0' to '4294967295'.
      47             :                               // Loop executes infinitely.
      48             : #endif
      49             : 
      50             : #endif
      51             : 
      52             : #if BOOST_WORKAROUND(__GNUC__, < 3) \
      53             :     && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
      54             : #define BOOST_HASH_CHAR_TRAITS string_char_traits
      55             : #else
      56             : #define BOOST_HASH_CHAR_TRAITS char_traits
      57             : #endif
      58             : 
      59             : #if defined(_MSC_VER)
      60             : #   define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
      61             : #else
      62             : #   define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
      63             : #endif
      64             : 
      65             : // Detect whether standard library has C++17 headers
      66             : 
      67             : #if !defined(BOOST_HASH_CXX17)
      68             : #   if defined(BOOST_MSVC)
      69             : #       if defined(_HAS_CXX17) && _HAS_CXX17
      70             : #           define BOOST_HASH_CXX17 1
      71             : #       endif
      72             : #   elif defined(__cplusplus) && __cplusplus >= 201703
      73             : #       define BOOST_HASH_CXX17 1
      74             : #   endif
      75             : #endif
      76             : 
      77             : #if !defined(BOOST_HASH_CXX17)
      78             : #   define BOOST_HASH_CXX17 0
      79             : #endif
      80             : 
      81             : #if BOOST_HASH_CXX17 && defined(__has_include)
      82             : #   if !defined(BOOST_HASH_HAS_STRING_VIEW) && __has_include(<string_view>)
      83             : #       define BOOST_HASH_HAS_STRING_VIEW 1
      84             : #   endif
      85             : #   if !defined(BOOST_HASH_HAS_OPTIONAL) && __has_include(<optional>)
      86             : #       define BOOST_HASH_HAS_OPTIONAL 1
      87             : #   endif
      88             : #   if !defined(BOOST_HASH_HAS_VARIANT) && __has_include(<variant>)
      89             : #       define BOOST_HASH_HAS_VARIANT 1
      90             : #   endif
      91             : #endif
      92             : 
      93             : #if !defined(BOOST_HASH_HAS_STRING_VIEW)
      94             : #   define BOOST_HASH_HAS_STRING_VIEW 0
      95             : #endif
      96             : 
      97             : #if !defined(BOOST_HASH_HAS_OPTIONAL)
      98             : #   define BOOST_HASH_HAS_OPTIONAL 0
      99             : #endif
     100             : 
     101             : #if !defined(BOOST_HASH_HAS_VARIANT)
     102             : #   define BOOST_HASH_HAS_VARIANT 0
     103             : #endif
     104             : 
     105             : #if BOOST_HASH_HAS_STRING_VIEW
     106             : #   include <string_view>
     107             : #endif
     108             : 
     109             : #if BOOST_HASH_HAS_OPTIONAL
     110             : #   include <optional>
     111             : #endif
     112             : 
     113             : #if BOOST_HASH_HAS_VARIANT
     114             : #   include <variant>
     115             : #endif
     116             : 
     117             : namespace boost
     118             : {
     119             :     namespace hash_detail
     120             :     {
     121             : #if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC
     122             :         template <typename T>
     123             :         struct hash_base
     124             :         {
     125             :             typedef T argument_type;
     126             :             typedef std::size_t result_type;
     127             :         };
     128             : #else
     129             :         template <typename T>
     130             :         struct hash_base : std::unary_function<T, std::size_t> {};
     131             : #endif
     132             : 
     133             :         struct enable_hash_value { typedef std::size_t type; };
     134             : 
     135             :         template <typename T> struct basic_numbers {};
     136             :         template <typename T> struct long_numbers;
     137             :         template <typename T> struct ulong_numbers;
     138             :         template <typename T> struct float_numbers {};
     139             : 
     140             :         template <> struct basic_numbers<bool> :
     141             :             boost::hash_detail::enable_hash_value {};
     142             :         template <> struct basic_numbers<char> :
     143             :             boost::hash_detail::enable_hash_value {};
     144             :         template <> struct basic_numbers<unsigned char> :
     145             :             boost::hash_detail::enable_hash_value {};
     146             :         template <> struct basic_numbers<signed char> :
     147             :             boost::hash_detail::enable_hash_value {};
     148             :         template <> struct basic_numbers<short> :
     149             :             boost::hash_detail::enable_hash_value {};
     150             :         template <> struct basic_numbers<unsigned short> :
     151             :             boost::hash_detail::enable_hash_value {};
     152             :         template <> struct basic_numbers<int> :
     153             :             boost::hash_detail::enable_hash_value {};
     154             :         template <> struct basic_numbers<unsigned int> :
     155             :             boost::hash_detail::enable_hash_value {};
     156             :         template <> struct basic_numbers<long> :
     157             :             boost::hash_detail::enable_hash_value {};
     158             :         template <> struct basic_numbers<unsigned long> :
     159             :             boost::hash_detail::enable_hash_value {};
     160             : 
     161             : #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
     162             :         template <> struct basic_numbers<wchar_t> :
     163             :             boost::hash_detail::enable_hash_value {};
     164             : #endif
     165             : 
     166             : #if !defined(BOOST_NO_CXX11_CHAR16_T)
     167             :         template <> struct basic_numbers<char16_t> :
     168             :             boost::hash_detail::enable_hash_value {};
     169             : #endif
     170             : 
     171             : #if !defined(BOOST_NO_CXX11_CHAR32_T)
     172             :         template <> struct basic_numbers<char32_t> :
     173             :             boost::hash_detail::enable_hash_value {};
     174             : #endif
     175             : 
     176             :         // long_numbers is defined like this to allow for separate
     177             :         // specialization for long_long and int128_type, in case
     178             :         // they conflict.
     179             :         template <typename T> struct long_numbers2 {};
     180             :         template <typename T> struct ulong_numbers2 {};
     181             :         template <typename T> struct long_numbers : long_numbers2<T> {};
     182             :         template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
     183             : 
     184             : #if !defined(BOOST_NO_LONG_LONG)
     185             :         template <> struct long_numbers<boost::long_long_type> :
     186             :             boost::hash_detail::enable_hash_value {};
     187             :         template <> struct ulong_numbers<boost::ulong_long_type> :
     188             :             boost::hash_detail::enable_hash_value {};
     189             : #endif
     190             : 
     191             : #if defined(BOOST_HAS_INT128)
     192             :         template <> struct long_numbers2<boost::int128_type> :
     193             :             boost::hash_detail::enable_hash_value {};
     194             :         template <> struct ulong_numbers2<boost::uint128_type> :
     195             :             boost::hash_detail::enable_hash_value {};
     196             : #endif
     197             : 
     198             :         template <> struct float_numbers<float> :
     199             :             boost::hash_detail::enable_hash_value {};
     200             :         template <> struct float_numbers<double> :
     201             :             boost::hash_detail::enable_hash_value {};
     202             :         template <> struct float_numbers<long double> :
     203             :             boost::hash_detail::enable_hash_value {};
     204             :     }
     205             : 
     206             :     template <typename T>
     207             :     typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
     208             :     template <typename T>
     209             :     typename boost::hash_detail::long_numbers<T>::type hash_value(T);
     210             :     template <typename T>
     211             :     typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
     212             : 
     213             :     template <typename T>
     214             :     typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
     215             :         hash_value(T);
     216             : 
     217             : #if !BOOST_WORKAROUND(__DMC__, <= 0x848)
     218             :     template <class T> std::size_t hash_value(T* const&);
     219             : #else
     220             :     template <class T> std::size_t hash_value(T*);
     221             : #endif
     222             : 
     223             : #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
     224             :     template< class T, unsigned N >
     225             :     std::size_t hash_value(const T (&x)[N]);
     226             : 
     227             :     template< class T, unsigned N >
     228             :     std::size_t hash_value(T (&x)[N]);
     229             : #endif
     230             : 
     231             :     template <class Ch, class A>
     232             :     std::size_t hash_value(
     233             :         std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
     234             : 
     235             : #if BOOST_HASH_HAS_STRING_VIEW
     236             :     template <class Ch>
     237             :     std::size_t hash_value(
     238             :         std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const&);
     239             : #endif
     240             : 
     241             :     template <typename T>
     242             :     typename boost::hash_detail::float_numbers<T>::type hash_value(T);
     243             : 
     244             : #if BOOST_HASH_HAS_OPTIONAL
     245             :     template <typename T>
     246             :     std::size_t hash_value(std::optional<T> const&);
     247             : #endif
     248             : 
     249             : #if BOOST_HASH_HAS_VARIANT
     250             :     std::size_t hash_value(std::monostate);
     251             :     template <typename... Types>
     252             :     std::size_t hash_value(std::variant<Types...> const&);
     253             : #endif
     254             : 
     255             : #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
     256             :     std::size_t hash_value(std::type_index);
     257             : #endif
     258             : 
     259             : #if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
     260             :     std::size_t hash_value(std::error_code const&);
     261             :     std::size_t hash_value(std::error_condition const&);
     262             : #endif
     263             : 
     264             :     // Implementation
     265             : 
     266             :     namespace hash_detail
     267             :     {
     268             :         template <class T>
     269             :         inline std::size_t hash_value_signed(T val)
     270             :         {
     271             :              const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits;
     272             :              // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
     273             :              const int length = (std::numeric_limits<T>::digits - 1)
     274             :                  / static_cast<int>(size_t_bits);
     275             : 
     276             :              std::size_t seed = 0;
     277             :              T positive = val < 0 ? -1 - val : val;
     278             : 
     279             :              // Hopefully, this loop can be unrolled.
     280             :              for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
     281             :              {
     282             :                  seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
     283             :              }
     284             :              seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
     285             : 
     286             :              return seed;
     287             :         }
     288             : 
     289             :         template <class T>
     290             :         inline std::size_t hash_value_unsigned(T val)
     291             :         {
     292             :              const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits;
     293             :              // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
     294             :              const int length = (std::numeric_limits<T>::digits - 1)
     295             :                  / static_cast<int>(size_t_bits);
     296             : 
     297             :              std::size_t seed = 0;
     298             : 
     299             :              // Hopefully, this loop can be unrolled.
     300             :              for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
     301             :              {
     302             :                  seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
     303             :              }
     304             :              seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
     305             : 
     306             :              return seed;
     307             :         }
     308             : 
     309             :         template <typename SizeT>
     310             :         inline void hash_combine_impl(SizeT& seed, SizeT value)
     311             :         {
     312             :             seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
     313             :         }
     314             : 
     315             :         inline void hash_combine_impl(boost::uint32_t& h1,
     316             :                 boost::uint32_t k1)
     317             :         {
     318             :             const uint32_t c1 = 0xcc9e2d51;
     319             :             const uint32_t c2 = 0x1b873593;
     320             : 
     321             :             k1 *= c1;
     322             :             k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15);
     323             :             k1 *= c2;
     324             : 
     325             :             h1 ^= k1;
     326             :             h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13);
     327             :             h1 = h1*5+0xe6546b64;
     328             :         }
     329             : 
     330             : 
     331             : // Don't define 64-bit hash combine on platforms without 64 bit integers,
     332             : // and also not for 32-bit gcc as it warns about the 64-bit constant.
     333             : #if !defined(BOOST_NO_INT64_T) && \
     334             :         !(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
     335             : 
     336  1123090000 :         inline void hash_combine_impl(boost::uint64_t& h,
     337             :                 boost::uint64_t k)
     338             :         {
     339  1123090000 :             const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
     340  1123090000 :             const int r = 47;
     341             : 
     342  1123090000 :             k *= m;
     343  1123090000 :             k ^= k >> r;
     344  1123090000 :             k *= m;
     345             : 
     346  1123090000 :             h ^= k;
     347  1123090000 :             h *= m;
     348             : 
     349             :             // Completely arbitrary number, to prevent 0's
     350             :             // from hashing to 0.
     351  1123090000 :             h += 0xe6546b64;
     352             :         }
     353             : 
     354             : #endif // BOOST_NO_INT64_T
     355             :     }
     356             : 
     357             :     template <typename T>
     358  1123090000 :     typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
     359             :     {
     360  1123090000 :         return static_cast<std::size_t>(v);
     361             :     }
     362             : 
     363             :     template <typename T>
     364             :     typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
     365             :     {
     366             :         return hash_detail::hash_value_signed(v);
     367             :     }
     368             : 
     369             :     template <typename T>
     370             :     typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
     371             :     {
     372             :         return hash_detail::hash_value_unsigned(v);
     373             :     }
     374             : 
     375             :     template <typename T>
     376             :     typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
     377             :         hash_value(T v)
     378             :     {
     379             :         return static_cast<std::size_t>(v);
     380             :     }
     381             : 
     382             :     // Implementation by Alberto Barbati and Dave Harris.
     383             : #if !BOOST_WORKAROUND(__DMC__, <= 0x848)
     384           0 :     template <class T> std::size_t hash_value(T* const& v)
     385             : #else
     386             :     template <class T> std::size_t hash_value(T* v)
     387             : #endif
     388             :     {
     389             : #if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
     390             :     // for some reason ptrdiff_t on OpenVMS compiler with
     391             :     // 64 bit is not 64 bit !!!
     392             :         std::size_t x = static_cast<std::size_t>(
     393             :            reinterpret_cast<long long int>(v));
     394             : #else
     395           0 :         std::size_t x = static_cast<std::size_t>(
     396             :            reinterpret_cast<std::ptrdiff_t>(v));
     397             : #endif
     398           0 :         return x + (x >> 3);
     399             :     }
     400             : 
     401             : #if defined(BOOST_MSVC)
     402             : #pragma warning(push)
     403             : #if BOOST_MSVC <= 1400
     404             : #pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
     405             :                               // 'unsigned int', possible loss of data
     406             :                               // A misguided attempt to detect 64-bit
     407             :                               // incompatability.
     408             : #endif
     409             : #endif
     410             : 
     411             :     template <class T>
     412  1123090000 :     inline void hash_combine(std::size_t& seed, T const& v)
     413             :     {
     414             :         boost::hash<T> hasher;
     415  1123090000 :         return boost::hash_detail::hash_combine_impl(seed, hasher(v));
     416             :     }
     417             : 
     418             : #if defined(BOOST_MSVC)
     419             : #pragma warning(pop)
     420             : #endif
     421             : 
     422             :     template <class It>
     423    40859000 :     inline std::size_t hash_range(It first, It last)
     424             :     {
     425    40859000 :         std::size_t seed = 0;
     426             : 
     427  1163950000 :         for(; first != last; ++first)
     428             :         {
     429  1123090000 :             hash_combine(seed, *first);
     430             :         }
     431             : 
     432             :         return seed;
     433             :     }
     434             : 
     435             :     template <class It>
     436             :     inline void hash_range(std::size_t& seed, It first, It last)
     437             :     {
     438             :         for(; first != last; ++first)
     439             :         {
     440             :             hash_combine(seed, *first);
     441             :         }
     442             :     }
     443             : 
     444             : #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
     445             :     template <class T>
     446             :     inline std::size_t hash_range(T* first, T* last)
     447             :     {
     448             :         std::size_t seed = 0;
     449             : 
     450             :         for(; first != last; ++first)
     451             :         {
     452             :             boost::hash<T> hasher;
     453             :             seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
     454             :         }
     455             : 
     456             :         return seed;
     457             :     }
     458             : 
     459             :     template <class T>
     460             :     inline void hash_range(std::size_t& seed, T* first, T* last)
     461             :     {
     462             :         for(; first != last; ++first)
     463             :         {
     464             :             boost::hash<T> hasher;
     465             :             seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
     466             :         }
     467             :     }
     468             : #endif
     469             : 
     470             : #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
     471             :     template< class T, unsigned N >
     472             :     inline std::size_t hash_value(const T (&x)[N])
     473             :     {
     474             :         return hash_range(x, x + N);
     475             :     }
     476             : 
     477             :     template< class T, unsigned N >
     478             :     inline std::size_t hash_value(T (&x)[N])
     479             :     {
     480             :         return hash_range(x, x + N);
     481             :     }
     482             : #endif
     483             : 
     484             :     template <class Ch, class A>
     485    40859000 :     inline std::size_t hash_value(
     486             :         std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
     487             :     {
     488    40859000 :         return hash_range(v.begin(), v.end());
     489             :     }
     490             : 
     491             : #if BOOST_HASH_HAS_STRING_VIEW
     492             :     template <class Ch>
     493             :     inline std::size_t hash_value(
     494             :         std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const& v)
     495             :     {
     496             :         return hash_range(v.begin(), v.end());
     497             :     }
     498             : #endif
     499             : 
     500             :     template <typename T>
     501             :     typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
     502             :     {
     503             :         return boost::hash_detail::float_hash_value(v);
     504             :     }
     505             : 
     506             : #if BOOST_HASH_HAS_OPTIONAL
     507             :     template <typename T>
     508             :     inline std::size_t hash_value(std::optional<T> const& v) {
     509             :         if (!v) {
     510             :             // Arbitray value for empty optional.
     511             :             return 0x12345678;
     512             :         } else {
     513             :             boost::hash<T> hf;
     514             :             return hf(*v);
     515             :         }
     516             :     }
     517             : #endif
     518             : 
     519             : #if BOOST_HASH_HAS_VARIANT
     520             :     inline std::size_t hash_value(std::monostate) {
     521             :         return 0x87654321;
     522             :     }
     523             : 
     524             :     template <typename... Types>
     525             :     inline std::size_t hash_value(std::variant<Types...> const& v) {
     526             :         std::size_t seed = 0;
     527             :         hash_combine(seed, v.index());
     528             :         std::visit([&seed](auto&& x) { hash_combine(seed, x); }, v);
     529             :         return seed;
     530             :     }
     531             : #endif
     532             : 
     533             : 
     534             : #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
     535             :     inline std::size_t hash_value(std::type_index v)
     536             :     {
     537             :         return v.hash_code();
     538             :     }
     539             : #endif
     540             : 
     541             : #if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
     542             :     inline std::size_t hash_value(std::error_code const& v) {
     543             :         std::size_t seed = 0;
     544             :         hash_combine(seed, v.value());
     545             :         hash_combine(seed, &v.category());
     546             :         return seed;
     547             :     }
     548             : 
     549             :     inline std::size_t hash_value(std::error_condition const& v) {
     550             :         std::size_t seed = 0;
     551             :         hash_combine(seed, v.value());
     552             :         hash_combine(seed, &v.category());
     553             :         return seed;
     554             :     }
     555             : #endif
     556             : 
     557             :     //
     558             :     // boost::hash
     559             :     //
     560             : 
     561             :     // Define the specializations required by the standard. The general purpose
     562             :     // boost::hash is defined later in extensions.hpp if
     563             :     // BOOST_HASH_NO_EXTENSIONS is not defined.
     564             : 
     565             :     // BOOST_HASH_SPECIALIZE - define a specialization for a type which is
     566             :     // passed by copy.
     567             :     //
     568             :     // BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
     569             :     // passed by const reference.
     570             :     //
     571             :     // These are undefined later.
     572             : 
     573             : #define BOOST_HASH_SPECIALIZE(type) \
     574             :     template <> struct hash<type> \
     575             :          : public boost::hash_detail::hash_base<type> \
     576             :     { \
     577             :         std::size_t operator()(type v) const \
     578             :         { \
     579             :             return boost::hash_value(v); \
     580             :         } \
     581             :     };
     582             : 
     583             : #define BOOST_HASH_SPECIALIZE_REF(type) \
     584             :     template <> struct hash<type> \
     585             :          : public boost::hash_detail::hash_base<type> \
     586             :     { \
     587             :         std::size_t operator()(type const& v) const \
     588             :         { \
     589             :             return boost::hash_value(v); \
     590             :         } \
     591             :     };
     592             : 
     593             : #define BOOST_HASH_SPECIALIZE_TEMPLATE_REF(type) \
     594             :     struct hash<type> \
     595             :          : public boost::hash_detail::hash_base<type> \
     596             :     { \
     597             :         std::size_t operator()(type const& v) const \
     598             :         { \
     599             :             return boost::hash_value(v); \
     600             :         } \
     601             :     };
     602             : 
     603             :     BOOST_HASH_SPECIALIZE(bool)
     604  1123090000 :     BOOST_HASH_SPECIALIZE(char)
     605             :     BOOST_HASH_SPECIALIZE(signed char)
     606             :     BOOST_HASH_SPECIALIZE(unsigned char)
     607             : #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
     608             :     BOOST_HASH_SPECIALIZE(wchar_t)
     609             : #endif
     610             : #if !defined(BOOST_NO_CXX11_CHAR16_T)
     611             :     BOOST_HASH_SPECIALIZE(char16_t)
     612             : #endif
     613             : #if !defined(BOOST_NO_CXX11_CHAR32_T)
     614             :     BOOST_HASH_SPECIALIZE(char32_t)
     615             : #endif
     616             :     BOOST_HASH_SPECIALIZE(short)
     617             :     BOOST_HASH_SPECIALIZE(unsigned short)
     618           0 :     BOOST_HASH_SPECIALIZE(int)
     619             :     BOOST_HASH_SPECIALIZE(unsigned int)
     620             :     BOOST_HASH_SPECIALIZE(long)
     621             :     BOOST_HASH_SPECIALIZE(unsigned long)
     622             : 
     623             :     BOOST_HASH_SPECIALIZE(float)
     624             :     BOOST_HASH_SPECIALIZE(double)
     625             :     BOOST_HASH_SPECIALIZE(long double)
     626             : 
     627    81718000 :     BOOST_HASH_SPECIALIZE_REF(std::string)
     628             : #if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
     629             :     BOOST_HASH_SPECIALIZE_REF(std::wstring)
     630             : #endif
     631             : #if !defined(BOOST_NO_CXX11_CHAR16_T)
     632             :     BOOST_HASH_SPECIALIZE_REF(std::basic_string<char16_t>)
     633             : #endif
     634             : #if !defined(BOOST_NO_CXX11_CHAR32_T)
     635             :     BOOST_HASH_SPECIALIZE_REF(std::basic_string<char32_t>)
     636             : #endif
     637             : 
     638             : #if BOOST_HASH_HAS_STRING_VIEW
     639             :     BOOST_HASH_SPECIALIZE_REF(std::string_view)
     640             : #   if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
     641             :     BOOST_HASH_SPECIALIZE_REF(std::wstring_view)
     642             : #   endif
     643             : #   if !defined(BOOST_NO_CXX11_CHAR16_T)
     644             :     BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char16_t>)
     645             : #   endif
     646             : #   if !defined(BOOST_NO_CXX11_CHAR32_T)
     647             :     BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char32_t>)
     648             : #   endif
     649             : #endif
     650             : 
     651             : #if !defined(BOOST_NO_LONG_LONG)
     652             :     BOOST_HASH_SPECIALIZE(boost::long_long_type)
     653             :     BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
     654             : #endif
     655             : 
     656             : #if defined(BOOST_HAS_INT128)
     657             :     BOOST_HASH_SPECIALIZE(boost::int128_type)
     658             :     BOOST_HASH_SPECIALIZE(boost::uint128_type)
     659             : #endif
     660             : 
     661             : #if BOOST_HASH_HAS_OPTIONAL
     662             :     template <typename T>
     663             :     BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::optional<T>)
     664             : #endif
     665             : 
     666             : #if !defined(BOOST_HASH_HAS_VARIANT)
     667             :     template <typename... T>
     668             :     BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::variant<T...>)
     669             :     BOOST_HASH_SPECIALIZE(std::monostate)
     670             : #endif
     671             : 
     672             : #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
     673             :     BOOST_HASH_SPECIALIZE(std::type_index)
     674             : #endif
     675             : 
     676             : #undef BOOST_HASH_SPECIALIZE
     677             : #undef BOOST_HASH_SPECIALIZE_REF
     678             : #undef BOOST_HASH_SPECIALIZE_TEMPLATE_REF
     679             : 
     680             : // Specializing boost::hash for pointers.
     681             : 
     682             : #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
     683             : 
     684             :     template <class T>
     685             :     struct hash<T*>
     686             :         : public boost::hash_detail::hash_base<T*>
     687             :     {
     688           0 :         std::size_t operator()(T* v) const
     689             :         {
     690             : #if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
     691           0 :             return boost::hash_value(v);
     692             : #else
     693             :             std::size_t x = static_cast<std::size_t>(
     694             :                 reinterpret_cast<std::ptrdiff_t>(v));
     695             : 
     696             :             return x + (x >> 3);
     697             : #endif
     698             :         }
     699             :     };
     700             : 
     701             : #else
     702             : 
     703             :     // For compilers without partial specialization, we define a
     704             :     // boost::hash for all remaining types. But hash_impl is only defined
     705             :     // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
     706             :     // is defined there will still be a compile error for types not supported
     707             :     // in the standard.
     708             : 
     709             :     namespace hash_detail
     710             :     {
     711             :         template <bool IsPointer>
     712             :         struct hash_impl;
     713             : 
     714             :         template <>
     715             :         struct hash_impl<true>
     716             :         {
     717             :             template <class T>
     718             :             struct inner
     719             :                 : public boost::hash_detail::hash_base<T>
     720             :             {
     721             :                 std::size_t operator()(T val) const
     722             :                 {
     723             : #if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
     724             :                     return boost::hash_value(val);
     725             : #else
     726             :                     std::size_t x = static_cast<std::size_t>(
     727             :                         reinterpret_cast<std::ptrdiff_t>(val));
     728             : 
     729             :                     return x + (x >> 3);
     730             : #endif
     731             :                 }
     732             :             };
     733             :         };
     734             :     }
     735             : 
     736             :     template <class T> struct hash
     737             :         : public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
     738             :             ::BOOST_NESTED_TEMPLATE inner<T>
     739             :     {
     740             :     };
     741             : 
     742             : #endif
     743             : }
     744             : 
     745             : #undef BOOST_HASH_CHAR_TRAITS
     746             : #undef BOOST_FUNCTIONAL_HASH_ROTL32
     747             : 
     748             : #if defined(BOOST_MSVC)
     749             : #pragma warning(pop)
     750             : #endif
     751             : 
     752             : #endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
     753             : 
     754             : // Include this outside of the include guards in case the file is included
     755             : // twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
     756             : // undefined.
     757             : 
     758             : #if !defined(BOOST_HASH_NO_EXTENSIONS) \
     759             :     && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
     760             : #include <boost/container_hash/extensions.hpp>
     761             : #endif

Generated by: LCOV version 1.14