• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/base/functional.h"
6 
7 #include <limits>
8 #include <set>
9 
10 #include "test/unittests/test-utils.h"
11 
12 namespace v8 {
13 namespace base {
14 
TEST(FunctionalTest,HashBool)15 TEST(FunctionalTest, HashBool) {
16   hash<bool> h, h1, h2;
17   EXPECT_EQ(h1(true), h2(true));
18   EXPECT_EQ(h1(false), h2(false));
19   EXPECT_NE(h(true), h(false));
20 }
21 
22 
TEST(FunctionalTest,HashFloatZero)23 TEST(FunctionalTest, HashFloatZero) {
24   hash<float> h;
25   EXPECT_EQ(h(0.0f), h(-0.0f));
26 }
27 
28 
TEST(FunctionalTest,HashDoubleZero)29 TEST(FunctionalTest, HashDoubleZero) {
30   hash<double> h;
31   EXPECT_EQ(h(0.0), h(-0.0));
32 }
33 
34 
35 template <typename T>
36 class FunctionalTest : public TestWithRandomNumberGenerator {};
37 
38 typedef ::testing::Types<signed char, unsigned char,
39                          short,                    // NOLINT(runtime/int)
40                          unsigned short,           // NOLINT(runtime/int)
41                          int, unsigned int, long,  // NOLINT(runtime/int)
42                          unsigned long,            // NOLINT(runtime/int)
43                          long long,                // NOLINT(runtime/int)
44                          unsigned long long,       // NOLINT(runtime/int)
45                          int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
46                          int64_t, uint64_t, float, double> FunctionalTypes;
47 
48 TYPED_TEST_CASE(FunctionalTest, FunctionalTypes);
49 
50 
TYPED_TEST(FunctionalTest,EqualToImpliesSameHashCode)51 TYPED_TEST(FunctionalTest, EqualToImpliesSameHashCode) {
52   hash<TypeParam> h;
53   std::equal_to<TypeParam> e;
54   TypeParam values[32];
55   this->rng()->NextBytes(values, sizeof(values));
56   TRACED_FOREACH(TypeParam, v1, values) {
57     TRACED_FOREACH(TypeParam, v2, values) {
58       if (e(v1, v2)) EXPECT_EQ(h(v1), h(v2));
59     }
60   }
61 }
62 
63 
TYPED_TEST(FunctionalTest,HashEqualsHashValue)64 TYPED_TEST(FunctionalTest, HashEqualsHashValue) {
65   for (int i = 0; i < 128; ++i) {
66     TypeParam v;
67     this->rng()->NextBytes(&v, sizeof(v));
68     hash<TypeParam> h;
69     EXPECT_EQ(h(v), hash_value(v));
70   }
71 }
72 
73 
TYPED_TEST(FunctionalTest,HashIsStateless)74 TYPED_TEST(FunctionalTest, HashIsStateless) {
75   hash<TypeParam> h1, h2;
76   for (int i = 0; i < 128; ++i) {
77     TypeParam v;
78     this->rng()->NextBytes(&v, sizeof(v));
79     EXPECT_EQ(h1(v), h2(v));
80   }
81 }
82 
83 
TYPED_TEST(FunctionalTest,HashIsOkish)84 TYPED_TEST(FunctionalTest, HashIsOkish) {
85   std::set<TypeParam> vs;
86   for (size_t i = 0; i < 128; ++i) {
87     TypeParam v;
88     this->rng()->NextBytes(&v, sizeof(v));
89     vs.insert(v);
90   }
91   std::set<size_t> hs;
92   for (const auto& v : vs) {
93     hash<TypeParam> h;
94     hs.insert(h(v));
95   }
96   EXPECT_LE(vs.size() / 4u, hs.size());
97 }
98 
99 
TYPED_TEST(FunctionalTest,HashValueArrayUsesHashRange)100 TYPED_TEST(FunctionalTest, HashValueArrayUsesHashRange) {
101   TypeParam values[128];
102   this->rng()->NextBytes(&values, sizeof(values));
103   EXPECT_EQ(hash_range(values, values + arraysize(values)), hash_value(values));
104 }
105 
106 
TYPED_TEST(FunctionalTest,BitEqualTo)107 TYPED_TEST(FunctionalTest, BitEqualTo) {
108   bit_equal_to<TypeParam> pred;
109   for (size_t i = 0; i < 128; ++i) {
110     TypeParam v1, v2;
111     this->rng()->NextBytes(&v1, sizeof(v1));
112     this->rng()->NextBytes(&v2, sizeof(v2));
113     EXPECT_PRED2(pred, v1, v1);
114     EXPECT_PRED2(pred, v2, v2);
115     EXPECT_EQ(memcmp(&v1, &v2, sizeof(TypeParam)) == 0, pred(v1, v2));
116   }
117 }
118 
119 
TYPED_TEST(FunctionalTest,BitEqualToImpliesSameBitHash)120 TYPED_TEST(FunctionalTest, BitEqualToImpliesSameBitHash) {
121   bit_hash<TypeParam> h;
122   bit_equal_to<TypeParam> e;
123   TypeParam values[32];
124   this->rng()->NextBytes(&values, sizeof(values));
125   TRACED_FOREACH(TypeParam, v1, values) {
126     TRACED_FOREACH(TypeParam, v2, values) {
127       if (e(v1, v2)) EXPECT_EQ(h(v1), h(v2));
128     }
129   }
130 }
131 
132 
133 namespace {
134 
135 struct Foo {
136   int x;
137   double y;
138 };
139 
140 
hash_value(Foo const & v)141 size_t hash_value(Foo const& v) { return hash_combine(v.x, v.y); }
142 
143 }  // namespace
144 
145 
TEST(FunctionalTest,HashUsesArgumentDependentLookup)146 TEST(FunctionalTest, HashUsesArgumentDependentLookup) {
147   const int kIntValues[] = {std::numeric_limits<int>::min(), -1, 0, 1, 42,
148                             std::numeric_limits<int>::max()};
149   const double kDoubleValues[] = {
150       std::numeric_limits<double>::min(), -1, -0, 0, 1,
151       std::numeric_limits<double>::max()};
152   TRACED_FOREACH(int, x, kIntValues) {
153     TRACED_FOREACH(double, y, kDoubleValues) {
154       hash<Foo> h;
155       Foo foo = {x, y};
156       EXPECT_EQ(hash_combine(x, y), h(foo));
157     }
158   }
159 }
160 
161 
TEST(FunctionalTest,BitEqualToFloat)162 TEST(FunctionalTest, BitEqualToFloat) {
163   bit_equal_to<float> pred;
164   EXPECT_FALSE(pred(0.0f, -0.0f));
165   EXPECT_FALSE(pred(-0.0f, 0.0f));
166   float const qNaN = std::numeric_limits<float>::quiet_NaN();
167   float const sNaN = std::numeric_limits<float>::signaling_NaN();
168   EXPECT_PRED2(pred, qNaN, qNaN);
169   EXPECT_PRED2(pred, sNaN, sNaN);
170 }
171 
172 
TEST(FunctionalTest,BitHashFloatDifferentForZeroAndMinusZero)173 TEST(FunctionalTest, BitHashFloatDifferentForZeroAndMinusZero) {
174   bit_hash<float> h;
175   EXPECT_NE(h(0.0f), h(-0.0f));
176 }
177 
178 
TEST(FunctionalTest,BitEqualToDouble)179 TEST(FunctionalTest, BitEqualToDouble) {
180   bit_equal_to<double> pred;
181   EXPECT_FALSE(pred(0.0, -0.0));
182   EXPECT_FALSE(pred(-0.0, 0.0));
183   double const qNaN = std::numeric_limits<double>::quiet_NaN();
184   double const sNaN = std::numeric_limits<double>::signaling_NaN();
185   EXPECT_PRED2(pred, qNaN, qNaN);
186   EXPECT_PRED2(pred, sNaN, sNaN);
187 }
188 
189 
TEST(FunctionalTest,BitHashDoubleDifferentForZeroAndMinusZero)190 TEST(FunctionalTest, BitHashDoubleDifferentForZeroAndMinusZero) {
191   bit_hash<double> h;
192   EXPECT_NE(h(0.0), h(-0.0));
193 }
194 
195 }  // namespace base
196 }  // namespace v8
197