BPHash
General object hashing library for C++
test_helpers.hpp
Go to the documentation of this file.
1 /*! \file
2  * \brief Helper functions for testing
3  */
4 
5 /* Copyright (c) 2016 Benjamin Pritchard <ben@bennyp.org>
6  * This file is part of the BPHash project, which is released
7  * under the BSD 3-clause license. See the LICENSE file for details
8  */
9 
10 #pragma once
11 
12 #include "bphash/Hasher.hpp"
13 #include "bphash/types/All.hpp"
14 
15 #include <iostream>
16 
17 //////////////////////////////////
18 // This is the data we test with
19 //////////////////////////////////
20 // integer values to test
21 // This contains negative integers, and we purposely pass them
22 // as unsigned sometimes.
23 // Unsigned overflow is defined behavior
24 static const std::vector<long>
25 int_test{ 0, 1, 10, 100, 241,
26  -1, -10, -100, -241};
27 
28 static const std::vector<double>
29 dbl_test{ 0, 1.0, 1.000001, 1.12e12, 1.12001e12, 1.12001e-12
30  -1.0, -1.000001, -1.12e12, -1.12001e12, -1.12001e-12};
31 
32 static std::vector<const char *>
34  " ",
35  "\n",
36  "String1",
37  "String 1",
38  "string1",
39  "string 1",
40  "STRING1",
41  " String1",
42  "String1!",
43  "String1!\n"};
44 
45 template<typename T>
46 void test_single(const T & val,
47  bphash::HashType htype,
48  std::vector<bphash::HashValue> & all_hashes)
49 {
50  using namespace bphash;
51  using namespace std;
52 
53  const char * type = typeid(T).name();
54  HashValue val_hash = make_hash(htype, val);
55 
56  // output the results
57  cout << "Testing type: " << type << "\n";
58  cout << " normal: " << hash_to_string(val_hash) << "\n"
59  << " trunc: " << hash_to_string(truncate_hash(val_hash, 8)) << "\n"
60  << " conv: " << convert_hash<size_t>(val_hash) << "\n";
61 
62  all_hashes.push_back(move(val_hash));
63 }
64 
65 
66 
67 template<typename To, typename From>
68 void test_values(const std::vector<From> & vals,
69  bphash::HashType htype,
70  std::vector<bphash::HashValue> & all_hashes)
71 {
72  for(const auto & it : vals)
73  test_single(static_cast<To>(it), htype, all_hashes);
74 }
75 
76 
77 template<typename To, typename From>
78 void test_pointers(const std::vector<From> & vals,
79  bphash::HashType htype,
80  std::vector<bphash::HashValue> & all_hashes)
81 {
82  std::vector<To *> new_rptrs;
83  std::vector<std::unique_ptr<To>> new_uptrs;
84  std::vector<std::shared_ptr<To>> new_sptrs;
85 
86  for(const auto & it : vals)
87  {
88  To new_val = static_cast<To>(it);
89  new_rptrs.push_back(new To(new_val));
90  new_uptrs.push_back(std::unique_ptr<To>(new To(new_val)));
91  new_sptrs.push_back(std::shared_ptr<To>(new To(new_val)));
92  }
93 
94  for(const auto & it : new_rptrs)
95  test_single(it, htype, all_hashes);
96 
97  for(const auto & it : new_uptrs)
98  test_single(it, htype, all_hashes);
99 
100  for(const auto & it : new_sptrs)
101  test_single(it, htype, all_hashes);
102 
103  for(const auto & it : new_rptrs)
104  delete it;
105 }
106 
107 
108 template<typename To, typename From, size_t N>
109 void test_array_helper(const std::vector<From> & vec,
110  bphash::HashType htype,
111  std::vector<bphash::HashValue> & all_hashes)
112 {
113  std::array<To, N> arr_values;
114  To plain_arr[N];
115 
116  for(size_t i = 0; i < N; i++)
117  {
118  arr_values[i] = static_cast<To>(vec.at(i));
119  plain_arr[i] = static_cast<To>(vec.at(i));
120 
121  }
122 
123  test_single(arr_values, htype, all_hashes);
124  test_single(bphash::hash_pointer(plain_arr, N), htype, all_hashes);
125 }
126 
127 
128 
129 #define HANDLE_TEST_ARRAY(N) \
130  case N: \
131  test_array_helper<To, From, N>(values, htype, all_hashes); \
132  break;
133 
134 template<typename To, typename From>
135 void test_arrays(const std::vector<From> & values,
136  bphash::HashType htype,
137  std::vector<bphash::HashValue> & all_hashes)
138 {
139  // arrays have to be handled slightly differently
140  for(size_t i = 0; i < values.size(); i++)
141  {
142  switch(i)
143  {
164  default:
165  break;
166  }
167  }
168 }
169 
170 #undef HANDLE_TEST_ARRAY
171 
172 
173 template<typename To, typename From>
174 void test_containers(const std::vector<From> & values,
175  bphash::HashType htype,
176  std::vector<bphash::HashValue> & all_hashes)
177 {
178  // tests the entire vector, as well subvectors
179  for(size_t i = 0; i <= values.size(); i++)
180  {
181  std::vector<To> new_vec{values.begin(), values.begin() + i};
182  std::list<To> new_list{values.begin(), values.begin() + i};
183  std::unordered_set<To> new_uset{values.begin(), values.begin() + i};
184  std::forward_list<To> new_flist{values.begin(), values.begin() + i};
185  std::set<To> new_set{values.begin(), values.begin() + i};
186 
187  test_single(new_vec, htype, all_hashes);
188  test_single(new_list, htype, all_hashes);
189  test_single(new_uset, htype, all_hashes);
190  test_single(new_flist, htype, all_hashes);
191  test_single(new_set, htype, all_hashes);
192  }
193 }
194 
195 
196 
197 template<typename To, typename From>
198 void test_fundamental(const std::vector<From> & values,
199  bphash::HashType htype,
200  std::vector<bphash::HashValue> & all_hashes)
201 {
202  test_values<To>(values, htype, all_hashes);
203  test_pointers<To>(values, htype, all_hashes);
204  test_arrays<To>(values, htype, all_hashes);
205  test_containers<To>(values, htype, all_hashes);
206 }
207 
208 
209 
210 template<typename To1, typename To2,
211  typename From1, typename From2>
212 void test_tuples_2(const std::vector<From1> & values1,
213  const std::vector<From2> & values2,
214  bphash::HashType htype,
215  std::vector<bphash::HashValue> & all_hashes)
216 {
217  typedef std::tuple<To1, To2> To12;
218  typedef std::pair<To1, To2> ToPair12;
219 
220  std::vector<To12> tup12;
221  std::vector<ToPair12> pair12;
222 
223  for(size_t i = 0; i < values1.size(); i++)
224  for(size_t j = 0; j < values2.size(); j++)
225  {
226  tup12.push_back(std::make_tuple<To1, To2>(
227  static_cast<To1>(values1.at(i)),
228  static_cast<To2>(values2.at(j))));
229 
230  pair12.push_back(std::make_pair<To1, To2>(
231  static_cast<To1>(values1.at(i)),
232  static_cast<To2>(values2.at(j))));
233  }
234 
235 
236  test_values <To12>(tup12, htype, all_hashes);
237  test_pointers<To12>(tup12, htype, all_hashes);
238  test_arrays <To12>(tup12, htype, all_hashes);
239  test_values <ToPair12>(pair12, htype, all_hashes);
240  test_pointers<ToPair12>(pair12, htype, all_hashes);
241  test_arrays <ToPair12>(pair12, htype, all_hashes);
242 
243  // test some containers
244  // tuple's don't have comparisons or std::hash
245  for(size_t i = 0; i <= tup12.size(); i++)
246  {
247  std::vector<To12> new_vec{tup12.begin(), tup12.begin() + i};
248  std::list<To12> new_list{tup12.begin(), tup12.begin() + i};
249  test_single(new_vec, htype, all_hashes);
250  test_single(new_list, htype, all_hashes);
251  }
252  for(size_t i = 0; i <= pair12.size(); i++)
253  {
254  std::vector<ToPair12> new_vec{pair12.begin(), pair12.begin() + i};
255  std::list<ToPair12> new_list{pair12.begin(), pair12.begin() + i};
256  test_single(new_vec, htype, all_hashes);
257  test_single(new_list, htype, all_hashes);
258  }
259 }
260 
261 
262 
263 
void test_arrays(const std::vector< From > &values, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)
void test_single(const T &val, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)
void test_tuples_2(const std::vector< From1 > &values1, const std::vector< From2 > &values2, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)
HashValue truncate_hash(const HashValue &hash, size_t nbytes)
Truncate the hash to a given number of bytes.
Definition: Hash.cpp:32
std::string hash_to_string(const HashValue &hash)
Return a string representation of a hash.
Definition: Hash.cpp:17
void test_array_helper(const std::vector< From > &vec, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)
A class that hashes objects (header)
static const std::vector< double > dbl_test
HashValue make_hash(HashType type, const Targs &...objs)
Convenience function for hashing objects in a single function call.
Definition: Hasher.hpp:254
HashType
Type of hash to use.
Definition: Hasher.hpp:25
std::vector< uint8_t > HashValue
Stores the value of a hash.
Definition: Hash.hpp:24
void test_pointers(const std::vector< From > &vals, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)
PointerWrapper< T > hash_pointer(const T *ptr, size_t len=1)
Wrap a raw pointer so that it can be hashed.
Definition: Hasher.hpp:67
#define HANDLE_TEST_ARRAY(N)
void test_values(const std::vector< From > &vals, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)
void test_containers(const std::vector< From > &values, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)
static const std::vector< long > int_test
A convenience header that includes all the types supported by bphash.
static std::vector< const char * > str_test
void test_fundamental(const std::vector< From > &values, bphash::HashType htype, std::vector< bphash::HashValue > &all_hashes)