source: mainline/uspace/lib/cpp/include/impl/memory.hpp@ e6c9fa6

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

cpp: fixed typos, copypasta errors and standard differences in memory

  • Property mode set to 100644
File size: 12.9 KB
Line 
1/*
2 * Copyright (c) 2017 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_MEMORY
30#define LIBCPP_MEMORY
31
32#include <internal/aux.hpp>
33#include <type_traits>
34
35namespace std
36{
37 /**
38 * 20.7.3, pointer traits:
39 */
40
41 template<class T>
42 struct pointer_traits
43 {
44 // TODO:
45 };
46
47 /**
48 * 20.7.8, allocator traits:
49 */
50
51 namespace aux
52 {
53 /**
54 * The standard mandates that we reuse type from allocators
55 * *if* they are defined or that we use something different.
56 * These structures help us alternate between those by
57 * using SFINAE.
58 * TODO: Create tests for these!
59 */
60
61 template<class T, class = void>
62 struct get_pointer: aux::type_is<typename T::value_type*>
63 { /* DUMMY BODY */ };
64
65 template<class T>
66 struct get_pointer<T, void_t<typename T::pointer>>
67 : aux::type_is<typename T::pointer>
68 { /* DUMMY BODY */ };
69
70 template<class T, class Ptr, class = void>
71 struct get_const_pointer
72 : aux::type_is<typename pointer_traits<Ptr>::template rebind<const typename T::value_type>>
73 { /* DUMMY BODY */ };
74
75 template<class T, class Ptr>
76 struct get_const_pointer<T, Ptr, void_t<typename T::const_pointer>>
77 : aux::type_is<typename T::const_pointer>
78 { /* DUMMY BODY */ };
79
80 template<class T, class Ptr, class = void>
81 struct get_void_pointer
82 : aux::type_is<typename pointer_traits<Ptr>::template rebind<void>>
83 { /* DUMMY BODY */ };
84
85 template<class T, class Ptr>
86 struct get_void_pointer<T, Ptr, void_t<typename T::void_pointer>>
87 : aux::type_is<typename T::void_pointer>
88 { /* DUMMY BODY */ };
89
90 template<class T, class Ptr, class = void>
91 struct get_const_void_pointer
92 : aux::type_is<typename pointer_traits<Ptr>::template rebind<const void>>
93 { /* DUMMY BODY */ };
94
95 template<class T, class Ptr>
96 struct get_const_void_pointer<T, Ptr, void_t<typename T::const_void_pointer>>
97 : aux::type_is<typename T::const_void_pointer>
98 { /* DUMMY BODY */ };
99
100 template<class T, class Ptr, class = void>
101 struct get_difference_type
102 : aux::type_is<typename pointer_traits<Ptr>::difference_type>
103 { /* DUMMY BODY */ };
104
105 template<class T, class Ptr>
106 struct get_difference_type<T, Ptr, void_t<typename T::difference_type>>
107 : aux::type_is<typename T::difference_type>
108 { /* DUMMY BODY */ };
109
110 template<class T, class Difference, class = void>
111 struct get_size_type: aux::type_is<make_unsigned_t<Difference>>
112 { /* DUMMY BODY */ };
113
114 template<class T, class Difference>
115 struct get_size_type<T, Difference, void_t<typename T::size_type>>
116 : aux::type_is<typename T::size_type>
117 { /* DUMMY BODY */ };
118
119 template<class T, class = void>
120 struct get_copy_propagate: aux::type_is<false_type>
121 { /* DUMMY BODY */ };
122
123 template<class T>
124 struct get_copy_propagate<T, void_t<typename T::propagate_on_container_copy_assignment>>
125 : aux::type_is<typename T::propagate_on_container_copy_assignment>
126 { /* DUMMY BODY */ };
127
128 template<class T, class = void>
129 struct get_move_propagate: aux::type_is<false_type>
130 { /* DUMMY BODY */ };
131
132 template<class T>
133 struct get_move_propagate<T, void_t<typename T::propagate_on_container_move_assignment>>
134 : aux::type_is<typename T::propagate_on_container_move_assignment>
135 { /* DUMMY BODY */ };
136
137 template<class T, class = void>
138 struct get_swap_propagate: aux::type_is<false_type>
139 { /* DUMMY BODY */ };
140
141 template<class T>
142 struct get_swap_propagate<T, void_t<typename T::propagate_on_container_swap>>
143 : aux::type_is<typename T::propagate_on_container_swap>
144 { /* DUMMY BODY */ };
145
146 template<class T, class = void>
147 struct get_always_equal: aux::type_is<typename is_empty<T>::type>
148 { /* DUMMY BODY */ };
149
150 template<class T>
151 struct get_always_equal<T, void_t<typename T::is_always_equal>>
152 : aux::type_is<typename T::is_always_equal>
153 { /* DUMMY BODY */ };
154
155 template<class Alloc, class T, class = void>
156 struct get_rebind_other
157 { /* DUMMY BODY */ };
158
159 template<class Alloc, class T>
160 struct get_rebind_other<Alloc, T, void_t<typename Alloc::template rebind<T>::other>>
161 : aux::type_is<typename Alloc::template rebind<T>::other>
162 { /* DUMMY BODY */ };
163
164 /* TODO: How am I suppose to do this?!
165 template<template<class T, class... Args> class Alloc>
166 struct get_rebind_args;
167 */
168
169 template<class Alloc, class T>
170 struct get_rebind_args: aux::type_is<typename get_rebind_other<Alloc, T>::type>
171 { /* DUMMY BODY */ };
172 }
173
174 template<class Alloc>
175 struct allocator_traits
176 {
177 using allocator_type = Alloc;
178
179 using value_type = typename Alloc::value_type;
180 using pointer = typename aux::get_pointer<Alloc>::type;
181 using const_pointer = typename aux::get_const_pointer<Alloc, pointer>::type;
182 using void_pointer = typename aux::get_void_pointer<Alloc, pointer>::type;
183 using const_void_pointer = typename aux::get_const_void_pointer<Alloc, pointer>::type;
184 using difference_type = typename aux::get_difference_type<Alloc, pointer>::type;
185 using size_type = typename aux::get_size_type<Alloc, difference_type>::type;
186
187 using propagate_on_container_copy_assignment = typename aux::get_copy_propagate<Alloc>::type;
188 using propagate_on_container_move_assignment = typename aux::get_move_propagate<Alloc>::type;
189 using propagate_on_container_swap = typename aux::get_swap_propagate<Alloc>::type;
190 using is_always_equal = typename aux::get_always_equal<Alloc>::type;
191
192 template<class T>
193 using rebind_alloc = typename aux::get_rebind_args<Alloc, T>;
194
195 template<class T>
196 using rebind_traits = allocator_traits<rebind_alloc<T>>;
197
198 static pointer allocate(Alloc& alloc, size_type n)
199 {
200 return alloc.allocate(n);
201 }
202
203 static pointer allocate(Alloc& alloc, size_type n, const_void_pointer hint)
204 { // TODO: this when it's well formed, otherwise alloc.allocate(n)
205 return alloc.allocate(n, hint);
206 }
207
208 static void deallocate(Alloc& alloc, pointer ptr, size_type n)
209 {
210 alloc.deallocate(ptr, n);
211 }
212
213 template<class T, class... Args>
214 static void construct(Alloc& alloc, T* ptr, Args&&... args)
215 {
216 // TODO: implement
217 }
218
219 template<class T>
220 static void destroy(Alloc& alloc, T* ptr)
221 {
222 // TODO: implement
223 }
224
225 static size_type max_size(const Alloc& alloc) noexcept
226 {
227 // TODO: implement
228 return 0;
229 }
230
231 static Alloc select_on_container_copy_construction(const Alloc& alloc)
232 {
233 // TODO: implement
234 return Alloc{};
235 }
236 };
237
238 /**
239 * 20.7.9, the default allocator
240 */
241
242 template<class T>
243 class allocator;
244
245 template<>
246 class allocator<void>
247 {
248 public:
249 using pointer = void*;
250 using const_pointer = const void*;
251 using value_type = void;
252
253 template<class U>
254 struct rebind
255 {
256 using other = allocator<U>;
257 };
258 };
259
260 template<class T>
261 class allocator
262 {
263 public:
264 using size_type = size_t;
265 using difference_type = ptrdiff_t;
266 using pointer = T*;
267 using const_pointer = const T*;
268 using reference = T&;
269 using const_reference = const T&;
270 using value_type = T;
271
272 template<class U>
273 struct rebind
274 {
275 using other = allocator<U>;
276 };
277
278 using propagate_on_container_move_assignment = true_type;
279 using is_always_equal = true_type;
280
281 allocator() noexcept;
282
283 allocator(const allocator&) noexcept;
284
285 template<class U>
286 allocator(const allocator<U>&) noexcept;
287
288 ~allocator() = default;
289
290 pointer address(reference x) const noexcept
291 { // TODO: see std::addressof
292 return &x;
293 }
294
295 const_pointer address(const_reference x) const noexcept
296 { // TODO: see std::addressof
297 return &x;
298 }
299
300 pointer allocate(size_type n, allocator<void>::const_pointer hint = 0)
301 {
302 /**
303 * Note: The usage of hint is unspecified.
304 * TODO: Check HelenOS hint allocation capabilities.
305 */
306 return ::operator new(n);
307 }
308
309 void deallocate(pointer ptr, size_type n)
310 {
311 ::operator delete(ptr, n);
312 }
313
314 size_type max_size() const noexcept
315 { // TODO: implement, max argument to allocate
316 return 0xFFFFFFFF;
317 }
318
319 template<class U, class... Args>
320 void construct(U* ptr, Args&&... args)
321 {
322 ::new((void*)ptr) U(forward<Args>(args)...);
323 }
324
325 template<class U>
326 void destroy(U* ptr)
327 {
328 ptr->~U();
329 }
330 };
331
332 template<class T1, class T2>
333 bool operator==(const allocator<T1>&, const allocator<T2>&) noexcept
334 {
335 return true;
336 }
337
338 template<class T1, class T2>
339 bool operator!=(const allocator<T1>&, const allocator<T2>&) noexcept
340 {
341 return false;
342 }
343
344 /**
345 * 20.7.10, raw storage iterator:
346 */
347
348 // TODO: implement
349
350 /**
351 * 20.7.11, temporary buffers:
352 */
353
354 // TODO: implement
355
356 /**
357 * 20.7.12, specialized algorithms:
358 */
359
360 template<class T>
361 T* addressof(T& x) noexcept
362 { // TODO: This should actually work even with overloaded operator&.
363 return &x;
364 }
365
366 template<class InputIterator, class ForwardIterator>
367 ForwardIterator unitialized_copy(
368 InputIterator first, InputIterator last,
369 ForwardIterator result
370 )
371 {
372 for (; first != last; ++first, ++result)
373 ::new (static_cast<void*>(&*result)) typename iterator_traits<ForwardIterator>::value_type(*first);
374
375 return result;
376 }
377
378 template<class InputIterator, class Size, class ForwardIterator>
379 ForwardIterator unitialized_copy_n(
380 InputIterator first, Size n, ForwardIterator result
381 )
382 {
383 for (; n > 0; ++first, --n, ++result)
384 ::new (static_cast<void*>(&*result)) typename iterator_traits<ForwardIterator>::value_type(*first);
385
386 return result;
387 }
388
389 template<class ForwardIterator, class T>
390 void unitialized_fill(
391 ForwardIterator first, ForwardIterator last, const T& x
392 )
393 {
394 for (; first != last; ++first)
395 ::new (static_cast<void*>(&*first)) typename iterator_traits<ForwardIterator>::value_type(x);
396 }
397
398 template<class ForwardIterator, class Size, class T>
399 ForwardIterator unitialized_fill_n(
400 ForwardIterator first, Size n, const T& x
401 )
402 {
403 for (; n > 0; ++first, --n)
404 ::new (static_cast<void*>(&*first)) typename iterator_traits<ForwardIterator>::value_type(x);
405
406 return first;
407 }
408}
409
410#endif
Note: See TracBrowser for help on using the repository browser.