LCOV - code coverage report
Current view: top level - src/base - functional.h (source / functions) Hit Total Coverage
Test: app.info Lines: 20 20 100.0 %
Date: 2019-02-19 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_BASE_FUNCTIONAL_H_
       6             : #define V8_BASE_FUNCTIONAL_H_
       7             : 
       8             : #include <stddef.h>
       9             : #include <stdint.h>
      10             : 
      11             : #include <cstddef>
      12             : #include <cstring>
      13             : #include <functional>
      14             : #include <utility>
      15             : 
      16             : #include "src/base/base-export.h"
      17             : #include "src/base/macros.h"
      18             : 
      19             : namespace v8 {
      20             : namespace base {
      21             : 
      22             : // base::hash is an implementation of the hash function object specified by
      23             : // C++11. It was designed to be compatible with std::hash (in C++11) and
      24             : // boost:hash (which in turn is based on the hash function object specified by
      25             : // the Draft Technical Report on C++ Library Extensions (TR1)).
      26             : //
      27             : // base::hash is implemented by calling the hash_value function. The namespace
      28             : // isn't specified so that it can detect overloads via argument dependent
      29             : // lookup. So if there is a free function hash_value in the same namespace as a
      30             : // custom type, it will get called.
      31             : //
      32             : // If users are asked to implement a hash function for their own types with no
      33             : // guidance, they generally write bad hash functions. Instead, we provide  a
      34             : // simple function base::hash_combine to pass hash-relevant member variables
      35             : // into, in order to define a decent hash function. base::hash_combine is
      36             : // declared as:
      37             : //
      38             : //   template<typename T, typename... Ts>
      39             : //   size_t hash_combine(const T& v, const Ts& ...vs);
      40             : //
      41             : // Consider the following example:
      42             : //
      43             : //   namespace v8 {
      44             : //   namespace bar {
      45             : //     struct Point { int x; int y; };
      46             : //     size_t hash_value(Point const& p) {
      47             : //       return base::hash_combine(p.x, p.y);
      48             : //     }
      49             : //   }
      50             : //
      51             : //   namespace foo {
      52             : //     void DoSomeWork(bar::Point const& p) {
      53             : //       base::hash<bar::Point> h;
      54             : //       ...
      55             : //       size_t hash_code = h(p);  // calls bar::hash_value(Point const&)
      56             : //       ...
      57             : //     }
      58             : //   }
      59             : //   }
      60             : //
      61             : // Based on the "Hashing User-Defined Types in C++1y" proposal from Jeffrey
      62             : // Yasskin and Chandler Carruth, see
      63             : // http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2012/n3333.html.
      64             : 
      65             : template <typename>
      66             : struct hash;
      67             : 
      68             : 
      69             : V8_INLINE size_t hash_combine() { return 0u; }
      70             : V8_INLINE size_t hash_combine(size_t seed) { return seed; }
      71             : V8_BASE_EXPORT size_t hash_combine(size_t seed, size_t value);
      72             : template <typename T, typename... Ts>
      73    14620023 : V8_INLINE size_t hash_combine(T const& v, Ts const&... vs) {
      74   763121957 :   return hash_combine(hash_combine(vs...), hash<T>()(v));
      75             : }
      76             : 
      77             : 
      78             : template <typename Iterator>
      79             : V8_INLINE size_t hash_range(Iterator first, Iterator last) {
      80             :   size_t seed = 0;
      81    78975427 :   for (; first != last; ++first) {
      82         512 :     seed = hash_combine(seed, *first);
      83             :   }
      84             :   return seed;
      85             : }
      86             : 
      87             : 
      88             : #define V8_BASE_HASH_VALUE_TRIVIAL(type) \
      89             :   V8_INLINE size_t hash_value(type v) { return static_cast<size_t>(v); }
      90      266880 : V8_BASE_HASH_VALUE_TRIVIAL(bool)
      91    66613871 : V8_BASE_HASH_VALUE_TRIVIAL(unsigned char)
      92   118209513 : V8_BASE_HASH_VALUE_TRIVIAL(unsigned short)  // NOLINT(runtime/int)
      93             : #undef V8_BASE_HASH_VALUE_TRIVIAL
      94             : 
      95             : V8_BASE_EXPORT size_t hash_value(unsigned int);
      96             : V8_BASE_EXPORT size_t hash_value(unsigned long);       // NOLINT(runtime/int)
      97             : V8_BASE_EXPORT size_t hash_value(unsigned long long);  // NOLINT(runtime/int)
      98             : 
      99             : #define V8_BASE_HASH_VALUE_SIGNED(type)            \
     100             :   V8_INLINE size_t hash_value(signed type v) {     \
     101             :     return hash_value(bit_cast<unsigned type>(v)); \
     102             :   }
     103             : V8_BASE_HASH_VALUE_SIGNED(char)
     104             : V8_BASE_HASH_VALUE_SIGNED(short)      // NOLINT(runtime/int)
     105   248102661 : V8_BASE_HASH_VALUE_SIGNED(int)        // NOLINT(runtime/int)
     106    38793537 : V8_BASE_HASH_VALUE_SIGNED(long)       // NOLINT(runtime/int)
     107        1024 : V8_BASE_HASH_VALUE_SIGNED(long long)  // NOLINT(runtime/int)
     108             : #undef V8_BASE_HASH_VALUE_SIGNED
     109             : 
     110             : V8_INLINE size_t hash_value(float v) {
     111             :   // 0 and -0 both hash to zero.
     112        1920 :   return v != 0.0f ? hash_value(bit_cast<uint32_t>(v)) : 0;
     113             : }
     114             : 
     115             : V8_INLINE size_t hash_value(double v) {
     116             :   // 0 and -0 both hash to zero.
     117        2040 :   return v != 0.0 ? hash_value(bit_cast<uint64_t>(v)) : 0;
     118             : }
     119             : 
     120             : template <typename T, size_t N>
     121             : V8_INLINE size_t hash_value(const T (&v)[N]) {
     122             :   return hash_range(v, v + N);
     123             : }
     124             : 
     125             : template <typename T, size_t N>
     126             : V8_INLINE size_t hash_value(T (&v)[N]) {
     127             :   return hash_range(v, v + N);
     128             : }
     129             : 
     130             : template <typename T>
     131             : V8_INLINE size_t hash_value(T* const& v) {
     132    15933703 :   return hash_value(bit_cast<uintptr_t>(v));
     133             : }
     134             : 
     135             : template <typename T1, typename T2>
     136             : V8_INLINE size_t hash_value(std::pair<T1, T2> const& v) {
     137      238529 :   return hash_combine(v.first, v.second);
     138             : }
     139             : 
     140             : template <typename T>
     141             : struct hash {
     142   131186571 :   V8_INLINE size_t operator()(T const& v) const { return hash_value(v); }
     143             : };
     144             : 
     145             : #define V8_BASE_HASH_SPECIALIZE(type)                 \
     146             :   template <>                                         \
     147             :   struct hash<type> {                                 \
     148             :     V8_INLINE size_t operator()(type const v) const { \
     149             :       return ::v8::base::hash_value(v);               \
     150             :     }                                                 \
     151             :   };
     152             : V8_BASE_HASH_SPECIALIZE(bool)
     153             : V8_BASE_HASH_SPECIALIZE(signed char)
     154             : V8_BASE_HASH_SPECIALIZE(unsigned char)
     155             : V8_BASE_HASH_SPECIALIZE(short)           // NOLINT(runtime/int)
     156             : V8_BASE_HASH_SPECIALIZE(unsigned short)  // NOLINT(runtime/int)
     157             : V8_BASE_HASH_SPECIALIZE(int)
     158   557462032 : V8_BASE_HASH_SPECIALIZE(unsigned int)
     159             : V8_BASE_HASH_SPECIALIZE(long)                // NOLINT(runtime/int)
     160   854066804 : V8_BASE_HASH_SPECIALIZE(unsigned long)       // NOLINT(runtime/int)
     161             : V8_BASE_HASH_SPECIALIZE(long long)           // NOLINT(runtime/int)
     162         896 : V8_BASE_HASH_SPECIALIZE(unsigned long long)  // NOLINT(runtime/int)
     163             : V8_BASE_HASH_SPECIALIZE(float)
     164             : V8_BASE_HASH_SPECIALIZE(double)
     165             : #undef V8_BASE_HASH_SPECIALIZE
     166             : 
     167             : template <typename T>
     168             : struct hash<T*> {
     169             :   V8_INLINE size_t operator()(T* const v) const {
     170             :     return ::v8::base::hash_value(v);
     171             :   }
     172             : };
     173             : 
     174             : // base::bit_equal_to is a function object class for bitwise equality
     175             : // comparison, similar to std::equal_to, except that the comparison is performed
     176             : // on the bit representation of the operands.
     177             : //
     178             : // base::bit_hash is a function object class for bitwise hashing, similar to
     179             : // base::hash. It can be used together with base::bit_equal_to to implement a
     180             : // hash data structure based on the bitwise representation of types.
     181             : 
     182             : template <typename T>
     183             : struct bit_equal_to {};
     184             : 
     185             : template <typename T>
     186             : struct bit_hash {};
     187             : 
     188             : #define V8_BASE_BIT_SPECIALIZE_TRIVIAL(type)                 \
     189             :   template <>                                                \
     190             :   struct bit_equal_to<type> : public std::equal_to<type> {}; \
     191             :   template <>                                                \
     192             :   struct bit_hash<type> : public hash<type> {};
     193             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(signed char)
     194             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned char)
     195             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(short)           // NOLINT(runtime/int)
     196             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned short)  // NOLINT(runtime/int)
     197             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(int)
     198             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned int)
     199             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(long)                // NOLINT(runtime/int)
     200             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned long)       // NOLINT(runtime/int)
     201             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(long long)           // NOLINT(runtime/int)
     202             : V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned long long)  // NOLINT(runtime/int)
     203             : #undef V8_BASE_BIT_SPECIALIZE_TRIVIAL
     204             : 
     205             : #define V8_BASE_BIT_SPECIALIZE_BIT_CAST(type, btype)       \
     206             :   template <>                                              \
     207             :   struct bit_equal_to<type> {                              \
     208             :     V8_INLINE bool operator()(type lhs, type rhs) const {  \
     209             :       return bit_cast<btype>(lhs) == bit_cast<btype>(rhs); \
     210             :     }                                                      \
     211             :   };                                                       \
     212             :   template <>                                              \
     213             :   struct bit_hash<type> {                                  \
     214             :     V8_INLINE size_t operator()(type v) const {            \
     215             :       hash<btype> h;                                       \
     216             :       return h(bit_cast<btype>(v));                        \
     217             :     }                                                      \
     218             :   };
     219         644 : V8_BASE_BIT_SPECIALIZE_BIT_CAST(float, uint32_t)
     220     1030974 : V8_BASE_BIT_SPECIALIZE_BIT_CAST(double, uint64_t)
     221             : #undef V8_BASE_BIT_SPECIALIZE_BIT_CAST
     222             : 
     223             : }  // namespace base
     224             : }  // namespace v8
     225             : 
     226             : #endif  // V8_BASE_FUNCTIONAL_H_

Generated by: LCOV version 1.10