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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since baed175 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
RevLine 
[e679283]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
[6283bf15]32#include <internal/functional/conditional_function_typedefs.hpp>
[c866a83]33#include <internal/functional/invoke.hpp>
[22ba300]34#include <limits>
[9c00022]35#include <memory>
[e679283]36#include <type_traits>
[22ba300]37#include <utility>
[9f77d98]38
[e679283]39namespace std
40{
41 /**
42 * 20.9.3, invoke:
43 */
44
45 template<class F, class... Args>
[c866a83]46 decltype(auto) invoke(F&& f, Args&&... args)
[e679283]47 {
48 return aux::invoke(forward<F>(f)(forward<Args>(args)...));
49 }
50
[a30c04d]51 /**
52 * 20.9.11, member function adaptors:
53 */
54
55 namespace aux
56 {
57 template<class F>
58 class mem_fn_t
[94ac2ea]59 : public conditional_function_typedefs<remove_cv_t<remove_reference_t<F>>>
[a30c04d]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
[e679283]83 /**
84 * 20.9.13, hash function primary template:
85 */
86
[22ba300]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 {
[5ae8168]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);
[22ba300]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
[e679283]125 template<class T>
[9f77d98]126 struct hash
127 { /* DUMMY BODY */ };
[e679283]128
129 template<>
[9f77d98]130 struct hash<bool>
131 {
132 size_t operator()(bool x) const noexcept
133 {
[22ba300]134 return aux::hash(x);
[9f77d98]135 }
136
137 using argument_type = bool;
138 using result_type = size_t;
139 };
[e679283]140
141 template<>
[9f77d98]142 struct hash<char>
143 {
144 size_t operator()(char x) const noexcept
145 {
[22ba300]146 return aux::hash(x);
[9f77d98]147 }
148
149 using argument_type = char;
150 using result_type = size_t;
151 };
[e679283]152
153 template<>
[9f77d98]154 struct hash<signed char>
155 {
156 size_t operator()(signed char x) const noexcept
157 {
[22ba300]158 return aux::hash(x);
[9f77d98]159 }
160
161 using argument_type = signed char;
162 using result_type = size_t;
163 };
[e679283]164
165 template<>
[9f77d98]166 struct hash<unsigned char>
167 {
168 size_t operator()(unsigned char x) const noexcept
169 {
[22ba300]170 return aux::hash(x);
[9f77d98]171 }
172
173 using argument_type = unsigned char;
174 using result_type = size_t;
175 };
[e679283]176
177 template<>
[9f77d98]178 struct hash<char16_t>
179 {
180 size_t operator()(char16_t x) const noexcept
181 {
[22ba300]182 return aux::hash(x);
[9f77d98]183 }
184
185 using argument_type = char16_t;
186 using result_type = size_t;
187 };
[e679283]188
189 template<>
[9f77d98]190 struct hash<char32_t>
191 {
192 size_t operator()(char32_t x) const noexcept
193 {
[22ba300]194 return aux::hash(x);
[9f77d98]195 }
196
197 using argument_type = char32_t;
198 using result_type = size_t;
199 };
[e679283]200
201 template<>
[9f77d98]202 struct hash<wchar_t>
203 {
204 size_t operator()(wchar_t x) const noexcept
205 {
[22ba300]206 return aux::hash(x);
[9f77d98]207 }
208
209 using argument_type = wchar_t;
210 using result_type = size_t;
211 };
[e679283]212
213 template<>
[9f77d98]214 struct hash<short>
215 {
216 size_t operator()(short x) const noexcept
217 {
[22ba300]218 return aux::hash(x);
[9f77d98]219 }
220
221 using argument_type = short;
222 using result_type = size_t;
223 };
[e679283]224
225 template<>
[9f77d98]226 struct hash<unsigned short>
227 {
228 size_t operator()(unsigned short x) const noexcept
229 {
[22ba300]230 return aux::hash(x);
[9f77d98]231 }
232
233 using argument_type = unsigned short;
234 using result_type = size_t;
235 };
[e679283]236
237 template<>
[9f77d98]238 struct hash<int>
239 {
240 size_t operator()(int x) const noexcept
241 {
[22ba300]242 return aux::hash(x);
[9f77d98]243 }
244
245 using argument_type = int;
246 using result_type = size_t;
247 };
[e679283]248
249 template<>
[9f77d98]250 struct hash<unsigned int>
251 {
252 size_t operator()(unsigned int x) const noexcept
253 {
[22ba300]254 return aux::hash(x);
[9f77d98]255 }
256
257 using argument_type = unsigned int;
258 using result_type = size_t;
259 };
[e679283]260
261 template<>
[9f77d98]262 struct hash<long>
263 {
264 size_t operator()(long x) const noexcept
265 {
[22ba300]266 return aux::hash(x);
[9f77d98]267 }
268
269 using argument_type = long;
270 using result_type = size_t;
271 };
[e679283]272
273 template<>
[9f77d98]274 struct hash<long long>
275 {
276 size_t operator()(long long x) const noexcept
277 {
[22ba300]278 return aux::hash(x);
[9f77d98]279 }
280
281 using argument_type = long long;
282 using result_type = size_t;
283 };
[e679283]284
285 template<>
[9f77d98]286 struct hash<unsigned long>
287 {
288 size_t operator()(unsigned long x) const noexcept
289 {
[22ba300]290 return aux::hash(x);
[9f77d98]291 }
292
293 using argument_type = unsigned long;
294 using result_type = size_t;
295 };
[e679283]296
297 template<>
[9f77d98]298 struct hash<unsigned long long>
299 {
300 size_t operator()(unsigned long long x) const noexcept
301 {
[22ba300]302 return aux::hash(x);
[9f77d98]303 }
304
305 using argument_type = unsigned long long;
306 using result_type = size_t;
307 };
[e679283]308
309 template<>
[9f77d98]310 struct hash<float>
311 {
312 size_t operator()(float x) const noexcept
313 {
[22ba300]314 return aux::hash(x);
[9f77d98]315 }
316
317 using argument_type = float;
318 using result_type = size_t;
319 };
[e679283]320
321 template<>
[22ba300]322 struct hash<double>
[9f77d98]323 {
324 size_t operator()(double x) const noexcept
325 {
[22ba300]326 return aux::hash(x);
[9f77d98]327 }
328
329 using argument_type = double;
330 using result_type = size_t;
331 };
[e679283]332
333 template<>
[22ba300]334 struct hash<long double>
[9f77d98]335 {
336 size_t operator()(long double x) const noexcept
337 {
[22ba300]338 return aux::hash(x);
[9f77d98]339 }
340
341 using argument_type = long double;
342 using result_type = size_t;
343 };
[e679283]344
345 template<class T>
[9f77d98]346 struct hash<T*>
347 {
348 size_t operator()(T* x) const noexcept
349 {
[22ba300]350 return aux::hash(x);
[9f77d98]351 }
352
353 using argument_type = T*;
354 using result_type = size_t;
355 };
[e679283]356}
357
358#endif
Note: See TracBrowser for help on using the repository browser.