1 | /** |
2 | * MIT License |
3 | * |
4 | * Copyright (c) 2017 Tessil |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | * of this software and associated documentation files (the "Software"), to deal |
8 | * in the Software without restriction, including without limitation the rights |
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | * copies of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice shall be included in all |
14 | * copies or substantial portions of the Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
22 | * SOFTWARE. |
23 | */ |
24 | |
25 | #ifndef TSL_UTILS_H |
26 | #define TSL_UTILS_H |
27 | |
28 | |
29 | #include <cstddef> |
30 | #include <cstdint> |
31 | #include <functional> |
32 | #include <memory> |
33 | #include <ostream> |
34 | #include <string> |
35 | #include <utility> |
36 | |
37 | |
38 | template<unsigned int MOD> |
39 | class mod_hash { |
40 | public: |
41 | template<typename T> |
42 | std::size_t operator()(const T& value) const { |
43 | return std::hash<T>()(value) % MOD; |
44 | } |
45 | }; |
46 | |
47 | |
48 | class move_only_test { |
49 | public: |
50 | explicit move_only_test(std::int64_t value) : m_value(new std::int64_t(value)) { |
51 | } |
52 | |
53 | move_only_test(const move_only_test&) = delete; |
54 | move_only_test(move_only_test&&) = default; |
55 | move_only_test& operator=(const move_only_test&) = delete; |
56 | move_only_test& operator=(move_only_test&&) = default; |
57 | |
58 | friend std::ostream& operator<<(std::ostream& stream, const move_only_test& value) { |
59 | if(value.m_value == nullptr) { |
60 | stream << "null" ; |
61 | } |
62 | else { |
63 | stream << *value.m_value; |
64 | } |
65 | |
66 | return stream; |
67 | } |
68 | |
69 | friend bool operator==(const move_only_test& lhs, const move_only_test& rhs) { |
70 | if(lhs.m_value == nullptr || rhs.m_value == nullptr) { |
71 | return lhs.m_value == nullptr && rhs.m_value == nullptr; |
72 | } |
73 | else { |
74 | return *lhs.m_value == *rhs.m_value; |
75 | } |
76 | } |
77 | |
78 | friend bool operator!=(const move_only_test& lhs, const move_only_test& rhs) { |
79 | return !(lhs == rhs); |
80 | } |
81 | |
82 | std::int64_t value() const { |
83 | return *m_value; |
84 | } |
85 | |
86 | private: |
87 | std::unique_ptr<std::int64_t> m_value; |
88 | }; |
89 | |
90 | |
91 | namespace std { |
92 | template<> |
93 | struct hash<move_only_test> { |
94 | std::size_t operator()(const move_only_test& val) const { |
95 | return std::hash<std::int64_t>()(val.value()); |
96 | } |
97 | }; |
98 | } |
99 | |
100 | |
101 | class utils { |
102 | public: |
103 | template<typename T> |
104 | static T get_key(std::size_t counter); |
105 | |
106 | template<typename T> |
107 | static T get_value(std::size_t counter); |
108 | |
109 | template<typename HMap> |
110 | static HMap get_filled_hash_map(std::size_t nb_elements); |
111 | }; |
112 | |
113 | |
114 | |
115 | template<> |
116 | inline std::int64_t utils::get_key<std::int64_t>(std::size_t counter) { |
117 | return counter; |
118 | } |
119 | |
120 | template<> |
121 | inline std::string utils::get_key<std::string>(std::size_t counter) { |
122 | return "Key " + std::to_string(counter); |
123 | } |
124 | |
125 | template<> |
126 | inline move_only_test utils::get_key<move_only_test>(std::size_t counter) { |
127 | return move_only_test(counter); |
128 | } |
129 | |
130 | |
131 | |
132 | |
133 | template<> |
134 | inline std::int64_t utils::get_value<std::int64_t>(std::size_t counter) { |
135 | return counter*2; |
136 | } |
137 | |
138 | template<> |
139 | inline std::string utils::get_value<std::string>(std::size_t counter) { |
140 | return "Value " + std::to_string(counter); |
141 | } |
142 | |
143 | template<> |
144 | inline move_only_test utils::get_value<move_only_test>(std::size_t counter) { |
145 | return move_only_test(counter*2); |
146 | } |
147 | |
148 | |
149 | |
150 | template<typename HMap> |
151 | inline HMap utils::get_filled_hash_map(std::size_t nb_elements) { |
152 | using key_tt = typename HMap::key_type; using value_tt = typename HMap:: mapped_type; |
153 | |
154 | HMap map; |
155 | map.reserve(nb_elements); |
156 | |
157 | for(std::size_t i = 0; i < nb_elements; i++) { |
158 | map.insert({utils::get_key<key_tt>(i), utils::get_value<value_tt>(i)}); |
159 | } |
160 | |
161 | return map; |
162 | } |
163 | |
164 | #endif |
165 | |