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) Lumiera.org
5  2014, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/hash-standard.hpp"
30 #include "lib/test/test-helper.hpp"
31 #include "lib/util.hpp"
32 
33 #include <boost/functional/hash.hpp>
34 #include <unordered_set>
35 #include <string>
36 #include <vector>
37 
38 using util::contains;
39 using std::unordered_set;
40 using std::vector;
41 using std::string;
42 
43 
44 namespace lib {
45 namespace test{
46 
47  /* == custom data items, each with its own private hash function == */
48 
53  class S
54  {
55  string s_;
56 
57  friend std::hash<S>;
58 
59  public:
60  S(string ss ="")
61  : s_(ss)
62  { }
63 
64  bool
65  operator== (S const& os) const
66  {
67  return s_ == os.s_;
68  }
69  };
70 
71 }}
72 // this is ugly: we have to close our own namespace and open namespace std
73 // for the sole purpose of placing our private hash function into the official extension point
74 
75 namespace std {
76 
77  using lib::test::S;
78 
79  template<>
80  struct hash<S>
81  {
82  size_t
83  operator() (S const& val) const noexcept
84  {
85  hash<string> string_hasher;
86  return string_hasher(val.s_);
87  }
88  };
89 
90 } // and back again into our own namespace...
91 namespace lib {
92 namespace test{
93 
94 
95 
96 
101  class V
102  {
103  vector<string> v_;
104 
105  public:
106  V(string ss ="")
107  {
108  v_.push_back(ss);
109  }
110 
111  bool
112  operator== (V const& ov) const
113  {
114  return v_ == ov.v_;
115  }
116 
117  friend size_t
118  hash_value (V const& v)
119  {
120  return boost::hash_value(v.v_);
121  }
122  };
123 
124 
125 
126 
127  /***********************************************************************/
143  class HashStandardToBoostBridge_test : public Test
144  {
145 
146  virtual void
147  run (Arg)
148  {
149  checkHashFunctionInvocation();
150  checkHashtableUsage();
151  }
152 
153 
154  void
155  checkHashFunctionInvocation ()
156  {
157  string p("Путин"), pp(p);
158  S s(p), ss(pp);
159  V v(p), vv(pp);
160 
161  std::hash<string> std_stringHasher;
162  boost::hash<string> boo_stringHasher;
163 
164  std::hash<S> std_customHasher;
165  boost::hash<V> boo_customHasher;
166 
167  CHECK(0 < std_stringHasher(p));
168  CHECK(0 < boo_stringHasher(p));
169  CHECK(0 < std_customHasher(p));
170  CHECK(0 < boo_customHasher(p));
171 
172  CHECK(std_stringHasher(p) == std_stringHasher(pp));
173  CHECK(boo_stringHasher(p) == boo_stringHasher(pp));
174  CHECK(std_customHasher(s) == std_customHasher(ss));
175  CHECK(boo_customHasher(v) == boo_customHasher(vv));
176 
177  // should be equal too, since the custom impl delegates to the standard string hasher
178  CHECK(std_stringHasher(p) == std_customHasher(s));
179 
180 
181  // verify the trait used to build the automatic bridge
184 
185  //verify the automatic bridge
186  std::hash<V> boo2std_crossHar;
187  CHECK(0 < boo2std_crossHar(v));
188 
189  // the std hash function delegates to the boost function...
190  CHECK(boo2std_crossHar(v) == boo_customHasher(v));
191 
192 // Note: does not compile,
193 // since there is not automatic bridge to use std::hash from boost::hash
194 //
195 // boost::hash<S>()(s);
196  }
197 
198 
199  void
200  checkHashtableUsage ()
201  {
202  string o1{randStr(5)},
203  o2{randStr(6)},
204  o3{randStr(7)},
205  o4{randStr(8)};
206  S s1{o1}, s2{o2}, s3{o3}, s4{o4}, s5{o2}, s6{o1};
207  V v1{o1}, v2{o2}, v3{o3}, v4{o4}, v5{o3}, v6{o2};
208 
209  unordered_set<S> us{s1,s2,s3,s4,s5,s6};
210  unordered_set<V> uv{v1,v2,v3,v1,v5,v6};
211 
212  CHECK(4 == us.size());
213  CHECK(3 == uv.size());
214 
215  CHECK(contains (us, s1));
216  CHECK(contains (us, s2));
217  CHECK(contains (us, s3));
218  CHECK(contains (us, s4));
219  CHECK(contains (us, s5));
220  CHECK(contains (us, s6));
221 
222  CHECK( contains (uv, v1));
223  CHECK( contains (uv, v2));
224  CHECK( contains (uv, v3));
225  CHECK(!contains (uv, v4));
226  CHECK( contains (uv, v5));
227  CHECK( contains (uv, v6));
228  }
229  };
230 
231 
233  LAUNCHER (HashStandardToBoostBridge_test, "unit common");
234 
235 
236 }} // namespace lib::test
Custom-Datatype 2: uses boost::hash extension point.
Definition: run.hpp:49
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:69
Simple 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:61
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