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
38template<unsigned int MOD>
39class mod_hash {
40public:
41 template<typename T>
42 std::size_t operator()(const T& value) const {
43 return std::hash<T>()(value) % MOD;
44 }
45};
46
47
48class move_only_test {
49public:
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
86private:
87 std::unique_ptr<std::int64_t> m_value;
88};
89
90
91namespace std {
92template<>
93struct 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
101class utils {
102public:
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
115template<>
116inline std::int64_t utils::get_key<std::int64_t>(std::size_t counter) {
117 return counter;
118}
119
120template<>
121inline std::string utils::get_key<std::string>(std::size_t counter) {
122 return "Key " + std::to_string(counter);
123}
124
125template<>
126inline move_only_test utils::get_key<move_only_test>(std::size_t counter) {
127 return move_only_test(counter);
128}
129
130
131
132
133template<>
134inline std::int64_t utils::get_value<std::int64_t>(std::size_t counter) {
135 return counter*2;
136}
137
138template<>
139inline std::string utils::get_value<std::string>(std::size_t counter) {
140 return "Value " + std::to_string(counter);
141}
142
143template<>
144inline move_only_test utils::get_value<move_only_test>(std::size_t counter) {
145 return move_only_test(counter*2);
146}
147
148
149
150template<typename HMap>
151inline 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