Lumiera  0.pre.03
»edit your freedom«
hash-standard-to-boost-bridge-test.cpp
Go to the documentation of this file.
1 /*
2  HashStandardToBoostBridge(Test) - verify a workaround to combine both systems of hash function definition
3 
4  Copyright (C)
5  2014, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
20 #include "lib/hash-standard.hpp"
21 #include "lib/test/test-helper.hpp"
22 #include "lib/util.hpp"
23 
24 #include <boost/functional/hash.hpp>
25 #include <unordered_set>
26 #include <string>
27 #include <vector>
28 
29 using util::contains;
30 using std::unordered_set;
31 using std::vector;
32 using std::string;
33 
34 
35 namespace lib {
36 namespace test{
37 
38  /* == custom data items, each with its own private hash function == */
39 
44  class S
45  {
46  string s_;
47 
48  friend std::hash<S>;
49 
50  public:
51  S(string ss ="")
52  : s_(ss)
53  { }
54 
55  bool
56  operator== (S const& os) const
57  {
58  return s_ == os.s_;
59  }
60  };
61 
62 }}
63 // this is ugly: we have to close our own namespace and open namespace std
64 // for the sole purpose of placing our private hash function into the official extension point
65 
66 namespace std {
67 
68  using lib::test::S;
69 
70  template<>
71  struct hash<S>
72  {
73  size_t
74  operator() (S const& val) const noexcept
75  {
76  hash<string> string_hasher;
77  return string_hasher(val.s_);
78  }
79  };
80 
81 } // and back again into our own namespace...
82 namespace lib {
83 namespace test{
84 
85 
86 
87 
92  class V
93  {
94  vector<string> v_;
95 
96  public:
97  V(string ss ="")
98  {
99  v_.push_back(ss);
100  }
101 
102  bool
103  operator== (V const& ov) const
104  {
105  return v_ == ov.v_;
106  }
107 
108  friend size_t
109  hash_value (V const& v)
110  {
111  return boost::hash_value(v.v_);
112  }
113  };
114 
115 
116 
117 
118  /***********************************************************************/
134  class HashStandardToBoostBridge_test : public Test
135  {
136 
137  virtual void
138  run (Arg)
139  {
140  checkHashFunctionInvocation();
141  checkHashtableUsage();
142  }
143 
144 
145  void
146  checkHashFunctionInvocation ()
147  {
148  string p("Путин"), pp(p);
149  S s(p), ss(pp);
150  V v(p), vv(pp);
151 
152  std::hash<string> std_stringHasher;
153  boost::hash<string> boo_stringHasher;
154 
155  std::hash<S> std_customHasher;
156  boost::hash<V> boo_customHasher;
157 
158  CHECK(0 < std_stringHasher(p));
159  CHECK(0 < boo_stringHasher(p));
160  CHECK(0 < std_customHasher(p));
161  CHECK(0 < boo_customHasher(p));
162 
163  CHECK(std_stringHasher(p) == std_stringHasher(pp));
164  CHECK(boo_stringHasher(p) == boo_stringHasher(pp));
165  CHECK(std_customHasher(s) == std_customHasher(ss));
166  CHECK(boo_customHasher(v) == boo_customHasher(vv));
167 
168  // should be equal too, since the custom impl delegates to the standard string hasher
169  CHECK(std_stringHasher(p) == std_customHasher(s));
170 
171 
172  // verify the trait used to build the automatic bridge
175 
176  //verify the automatic bridge
177  std::hash<V> boo2std_crossHar;
178  CHECK(0 < boo2std_crossHar(v));
179 
180  // the std hash function delegates to the boost function...
181  CHECK(boo2std_crossHar(v) == boo_customHasher(v));
182 
183 // Note: does not compile,
184 // since there is not automatic bridge to use std::hash from boost::hash
185 //
186 // boost::hash<S>()(s);
187  }
188 
189 
190  void
191  checkHashtableUsage ()
192  {
193  string o1{randStr(5)},
194  o2{randStr(6)},
195  o3{randStr(7)},
196  o4{randStr(8)};
197  S s1{o1}, s2{o2}, s3{o3}, s4{o4}, s5{o2}, s6{o1};
198  V v1{o1}, v2{o2}, v3{o3}, v4{o4}, v5{o3}, v6{o2};
199 
200  unordered_set<S> us{s1,s2,s3,s4,s5,s6};
201  unordered_set<V> uv{v1,v2,v3,v1,v5,v6};
202 
203  CHECK(4 == us.size());
204  CHECK(3 == uv.size());
205 
206  CHECK(contains (us, s1));
207  CHECK(contains (us, s2));
208  CHECK(contains (us, s3));
209  CHECK(contains (us, s4));
210  CHECK(contains (us, s5));
211  CHECK(contains (us, s6));
212 
213  CHECK( contains (uv, v1));
214  CHECK( contains (uv, v2));
215  CHECK( contains (uv, v3));
216  CHECK(!contains (uv, v4));
217  CHECK( contains (uv, v5));
218  CHECK( contains (uv, v6));
219  }
220  };
221 
222 
224  LAUNCHER (HashStandardToBoostBridge_test, "unit common");
225 
226 
227 }} // namespace lib::test
Custom-Datatype 2: uses boost::hash extension point.
Definition: run.hpp:40
STL namespace.
Primary class template for std::hash.
Implementation namespace for support and library code.
string randStr(size_t len)
create garbage string of given length
Definition: test-helper.cpp:61
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Helper to use a single extension point for specialised hash functions.
A collection of frequently used helper functions to support unit testing.
HashVal hash_value(QueryText const &entry)
support using queries in hashtables.
Definition: query-text.cpp:52
trait template to detect if some custom type TY provides a boost compliant hash function through ADL ...
Custom-Datatype 1: uses std::hash extension point.
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255