source: mainline/uspace/lib/cpp/include/impl/functional.hpp@ 6a3a64f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6a3a64f was db54a9d, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: moved arithmetic operations to their own header

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_FUNCTIONAL
30#define LIBCPP_FUNCTIONAL
31
32#include <internal/functional/conditional_function_typedefs.hpp>
33#include <internal/functional/invoke.hpp>
34#include <limits>
35#include <memory>
36#include <type_traits>
37#include <utility>
38
39namespace std
40{
41 /**
42 * 20.9.3, invoke:
43 */
44
45 template<class F, class... Args>
46 decltype(auto) invoke(F&& f, Args&&... args)
47 {
48 return aux::invoke(forward<F>(f)(forward<Args>(args)...));
49 }
50
51 /**
52 * 20.9.11, member function adaptors:
53 */
54
55 namespace aux
56 {
57 template<class F>
58 class mem_fn_t
59 : public conditional_function_typedefs<remove_cv_t<remove_reference_t<F>>>
60 {
61 public:
62 mem_fn_t(F f)
63 : func_{f}
64 { /* DUMMY BODY */ }
65
66 template<class... Args>
67 decltype(auto) operator()(Args&&... args)
68 {
69 return invoke(func_, forward<Args>(args)...);
70 }
71
72 private:
73 F func_;
74 };
75 }
76
77 template<class R, class T>
78 aux::mem_fn_t<R T::*> mem_fn(R T::* f)
79 {
80 return aux::mem_fn_t<R T::*>{f};
81 }
82
83 /**
84 * 20.9.13, hash function primary template:
85 */
86
87 namespace aux
88 {
89 template<class T>
90 union converter
91 {
92 T value;
93 uint64_t converted;
94 };
95
96 template<class T>
97 T hash_(uint64_t x) noexcept
98 {
99 /**
100 * Note: std::hash is used for indexing in
101 * unordered containers, not for cryptography.
102 * Because of this, we decided to simply convert
103 * the value to uin64_t, which will help us
104 * with testing (since in order to create
105 * a collision in a multiset or multimap
106 * we simply need 2 values that congruent
107 * by the size of the table.
108 */
109 return static_cast<T>(x);
110 }
111
112 template<class T>
113 size_t hash(T x) noexcept
114 {
115 static_assert(is_arithmetic_v<T> || is_pointer_v<T>,
116 "invalid type passed to aux::hash");
117
118 converter<T> conv;
119 conv.value = x;
120
121 return hash_<size_t>(conv.converted);
122 }
123 }
124
125 template<class T>
126 struct hash
127 { /* DUMMY BODY */ };
128
129 template<>
130 struct hash<bool>
131 {
132 size_t operator()(bool x) const noexcept
133 {
134 return aux::hash(x);
135 }
136
137 using argument_type = bool;
138 using result_type = size_t;
139 };
140
141 template<>
142 struct hash<char>
143 {
144 size_t operator()(char x) const noexcept
145 {
146 return aux::hash(x);
147 }
148
149 using argument_type = char;
150 using result_type = size_t;
151 };
152
153 template<>
154 struct hash<signed char>
155 {
156 size_t operator()(signed char x) const noexcept
157 {
158 return aux::hash(x);
159 }
160
161 using argument_type = signed char;
162 using result_type = size_t;
163 };
164
165 template<>
166 struct hash<unsigned char>
167 {
168 size_t operator()(unsigned char x) const noexcept
169 {
170 return aux::hash(x);
171 }
172
173 using argument_type = unsigned char;
174 using result_type = size_t;
175 };
176
177 template<>
178 struct hash<char16_t>
179 {
180 size_t operator()(char16_t x) const noexcept
181 {
182 return aux::hash(x);
183 }
184
185 using argument_type = char16_t;
186 using result_type = size_t;
187 };
188
189 template<>
190 struct hash<char32_t>
191 {
192 size_t operator()(char32_t x) const noexcept
193 {
194 return aux::hash(x);
195 }
196
197 using argument_type = char32_t;
198 using result_type = size_t;
199 };
200
201 template<>
202 struct hash<wchar_t>
203 {
204 size_t operator()(wchar_t x) const noexcept
205 {
206 return aux::hash(x);
207 }
208
209 using argument_type = wchar_t;
210 using result_type = size_t;
211 };
212
213 template<>
214 struct hash<short>
215 {
216 size_t operator()(short x) const noexcept
217 {
218 return aux::hash(x);
219 }
220
221 using argument_type = short;
222 using result_type = size_t;
223 };
224
225 template<>
226 struct hash<unsigned short>
227 {
228 size_t operator()(unsigned short x) const noexcept
229 {
230 return aux::hash(x);
231 }
232
233 using argument_type = unsigned short;
234 using result_type = size_t;
235 };
236
237 template<>
238 struct hash<int>
239 {
240 size_t operator()(int x) const noexcept
241 {
242 return aux::hash(x);
243 }
244
245 using argument_type = int;
246 using result_type = size_t;
247 };
248
249 template<>
250 struct hash<unsigned int>
251 {
252 size_t operator()(unsigned int x) const noexcept
253 {
254 return aux::hash(x);
255 }
256
257 using argument_type = unsigned int;
258 using result_type = size_t;
259 };
260
261 template<>
262 struct hash<long>
263 {
264 size_t operator()(long x) const noexcept
265 {
266 return aux::hash(x);
267 }
268
269 using argument_type = long;
270 using result_type = size_t;
271 };
272
273 template<>
274 struct hash<long long>
275 {
276 size_t operator()(long long x) const noexcept
277 {
278 return aux::hash(x);
279 }
280
281 using argument_type = long long;
282 using result_type = size_t;
283 };
284
285 template<>
286 struct hash<unsigned long>
287 {
288 size_t operator()(unsigned long x) const noexcept
289 {
290 return aux::hash(x);
291 }
292
293 using argument_type = unsigned long;
294 using result_type = size_t;
295 };
296
297 template<>
298 struct hash<unsigned long long>
299 {
300 size_t operator()(unsigned long long x) const noexcept
301 {
302 return aux::hash(x);
303 }
304
305 using argument_type = unsigned long long;
306 using result_type = size_t;
307 };
308
309 template<>
310 struct hash<float>
311 {
312 size_t operator()(float x) const noexcept
313 {
314 return aux::hash(x);
315 }
316
317 using argument_type = float;
318 using result_type = size_t;
319 };
320
321 template<>
322 struct hash<double>
323 {
324 size_t operator()(double x) const noexcept
325 {
326 return aux::hash(x);
327 }
328
329 using argument_type = double;
330 using result_type = size_t;
331 };
332
333 template<>
334 struct hash<long double>
335 {
336 size_t operator()(long double x) const noexcept
337 {
338 return aux::hash(x);
339 }
340
341 using argument_type = long double;
342 using result_type = size_t;
343 };
344
345 template<class T>
346 struct hash<T*>
347 {
348 size_t operator()(T* x) const noexcept
349 {
350 return aux::hash(x);
351 }
352
353 using argument_type = T*;
354 using result_type = size_t;
355 };
356}
357
358#endif
Note: See TracBrowser for help on using the repository browser.