WPILibC++ 2025.1.1
Loading...
Searching...
No Matches
allocator_traits.hpp
Go to the documentation of this file.
1// Copyright (C) 2015-2023 Jonathan Müller and foonathan/memory contributors
2// SPDX-License-Identifier: Zlib
3
4#ifndef WPI_MEMORY_ALLOCATOR_TRAITS_HPP_INCLUDED
5#define WPI_MEMORY_ALLOCATOR_TRAITS_HPP_INCLUDED
6
7/// \file
8/// The default specialization of the \ref wpi::memory::allocator_traits.
9
10#include <cstddef>
11#include <type_traits>
12
13#include "detail/align.hpp"
14#include "detail/utility.hpp"
15#include "config.hpp"
16
17#if WPI_HOSTED_IMPLEMENTATION
18#include <memory>
19#endif
20
21namespace wpi
22{
23 namespace memory
24 {
25 namespace detail
26 {
27 template <class Allocator>
28 std::true_type has_construct(int, WPI_SFINAE(std::declval<Allocator>().construct(
29 std::declval<typename Allocator::pointer>(),
30 std::declval<typename Allocator::value_type>())));
31
32 template <class Allocator>
33 std::false_type has_construct(short);
34
35 template <class Allocator>
36 std::true_type has_destroy(int, WPI_SFINAE(std::declval<Allocator>().destroy(
37 std::declval<typename Allocator::pointer>())));
38
39 template <class Allocator>
40 std::false_type has_destroy(short);
41
42 template <class Allocator>
44 {
47
48 using valid = std::integral_constant<bool, !custom_construct::value
49 && !custom_destroy::value>;
50 };
51 } // namespace detail
52
53 /// Traits class that checks whether or not a standard \c Allocator can be used as RawAllocator.
54 /// It checks the existence of a custom \c construct(), \c destroy() function, if provided,
55 /// it cannot be used since it would not be called.<br>
56 /// Specialize it for custom \c Allocator types to override this check.
57 /// \ingroup memory_core
58 template <class Allocator>
60 : WPI_EBO(detail::check_standard_allocator<Allocator>::valid)
61 {
62 };
63
64 /// Specialization of \ref allocator_is_raw_allocator that allows \c std::allocator again.
65 /// \ingroup memory_core
66 template <typename T>
67 struct allocator_is_raw_allocator<std::allocator<T>> : std::true_type
68 {
69 };
70
71 namespace traits_detail // use seperate namespace to avoid name clashes
72 {
73 // full_concept has the best conversion rank, error the lowest
74 // used to give priority to the functions
75 struct error
76 {
77 operator void*() const noexcept
78 {
80 "this is just to hide an error and move static_assert to the front");
81 return nullptr;
82 }
83 };
85 {
86 };
88 {
89 };
91 {
92 };
93
94 // used to delay assert in handle_error() until instantiation
95 template <typename T>
97 {
98 static const bool error = false;
99 };
100
101 //=== allocator_type ===//
102 // if Allocator has a member template `rebind`, use that to rebind to `char`
103 // else if Allocator has a member `value_type`, rebind by changing argument
104 // else does nothing
105 template <class Allocator>
106 auto rebind_impl(int) -> typename Allocator::template rebind<char>::other&;
107
108 template <class Allocator, typename T>
110 {
111 using type = Allocator&;
112 };
113
114 template <template <typename, typename...> class Alloc, typename U, typename... Args,
115 typename T>
116 struct allocator_rebinder<Alloc<U, Args...>, T>
117 {
118 using type = Alloc<T, Args...>&;
119 };
120
121 template <class Allocator, typename = typename Allocator::value_type>
123
124 template <class Allocator>
125 auto rebind_impl(...) -> Allocator&;
126
127 template <class Allocator>
128 struct allocator_type_impl // required for MSVC
129 {
130 using type = decltype(rebind_impl<Allocator>(0));
131 };
132
133 template <class Allocator>
135 typename std::decay<typename allocator_type_impl<Allocator>::type>::type;
136
137 //=== is_stateful ===//
138 // first try to access Allocator::is_stateful,
139 // then use whether or not the type is empty
140 template <class Allocator>
141 auto is_stateful(full_concept) -> decltype(typename Allocator::is_stateful{});
142
143 template <class Allocator, bool IsEmpty>
145
146 template <class Allocator>
147 struct is_stateful_impl<Allocator, true>
148 {
149 static_assert(std::is_default_constructible<Allocator>::value,
150 "RawAllocator is empty but not default constructible ."
151 "This means it is not a stateless allocator. "
152 "If this is actually intended provide the appropriate is_stateful "
153 "typedef in your class.");
154 using type = std::false_type;
155 };
156
157 template <class Allocator>
158 struct is_stateful_impl<Allocator, false>
159 {
160 using type = std::true_type;
161 };
162
163 template <class Allocator>
166
167 //=== allocate_node() ===//
168 // first try Allocator::allocate_node
169 // then assume std_allocator and call Allocator::allocate
170 // then error
171 template <class Allocator>
172 auto allocate_node(full_concept, Allocator& alloc, std::size_t size,
173 std::size_t alignment)
174 -> WPI_AUTO_RETURN_TYPE(alloc.allocate_node(size, alignment), void*)
175
176 template <class Allocator>
177 auto allocate_node(std_concept, Allocator& alloc, std::size_t size, std::size_t)
178 -> WPI_AUTO_RETURN(static_cast<void*>(alloc.allocate(size)))
179
180 template <class Allocator>
181 error allocate_node(error, Allocator&, std::size_t, std::size_t)
182 {
184 "type is not a RawAllocator as it does not provide: void* "
185 "allocate_node(std::size_t, "
186 "std::size_t)");
187 return {};
188 }
189
190 //=== deallocate_node() ===//
191 // first try Allocator::deallocate_node
192 // then assume std_allocator and call Allocator::deallocate
193 // then error
194 template <class Allocator>
195 auto deallocate_node(full_concept, Allocator& alloc, void* ptr, std::size_t size,
196 std::size_t alignment) noexcept
197 -> WPI_AUTO_RETURN_TYPE(alloc.deallocate_node(ptr, size, alignment), void)
198
199 template <class Allocator>
200 auto deallocate_node(std_concept, Allocator& alloc, void* ptr, std::size_t size,
201 std::size_t) noexcept
202 -> WPI_AUTO_RETURN_TYPE(alloc.deallocate(static_cast<char*>(ptr), size), void)
203
204 template <class Allocator>
205 error deallocate_node(error, Allocator&, void*, std::size_t, std::size_t)
206 {
208 "type is not a RawAllocator as it does not provide: void "
209 "deallocate_node(void*, std::size_t, "
210 "std::size_t)");
211 return error{};
212 }
213
214 //=== allocate_array() ===//
215 // first try Allocator::allocate_array
216 // then forward to allocate_node()
217 template <class Allocator>
218 auto allocate_array(full_concept, Allocator& alloc, std::size_t count, std::size_t size,
219 std::size_t alignment)
220 -> WPI_AUTO_RETURN_TYPE(alloc.allocate_array(count, size, alignment), void*)
221
222 template <class Allocator>
223 void* allocate_array(min_concept, Allocator& alloc, std::size_t count,
224 std::size_t size, std::size_t alignment)
225 {
226 return allocate_node(full_concept{}, alloc, count * size, alignment);
227 }
228
229 //=== deallocate_array() ===//
230 // first try Allocator::deallocate_array
231 // then forward to deallocate_node()
232 template <class Allocator>
233 auto deallocate_array(full_concept, Allocator& alloc, void* ptr, std::size_t count,
234 std::size_t size, std::size_t alignment) noexcept
235 -> WPI_AUTO_RETURN_TYPE(alloc.deallocate_array(ptr, count, size, alignment),
236 void)
237
238 template <class Allocator>
239 void deallocate_array(min_concept, Allocator& alloc, void* ptr,
240 std::size_t count, std::size_t size,
241 std::size_t alignment) noexcept
242 {
243 deallocate_node(full_concept{}, alloc, ptr, count * size, alignment);
244 }
245
246 //=== max_node_size() ===//
247 // first try Allocator::max_node_size()
248 // then return maximum value
249 template <class Allocator>
250 auto max_node_size(full_concept, const Allocator& alloc)
251 -> WPI_AUTO_RETURN_TYPE(alloc.max_node_size(), std::size_t)
252
253 template <class Allocator>
254 std::size_t max_node_size(min_concept, const Allocator&) noexcept
255 {
256 return std::size_t(-1);
257 }
258
259 //=== max_node_size() ===//
260 // first try Allocator::max_array_size()
261 // then forward to max_node_size()
262 template <class Allocator>
263 auto max_array_size(full_concept, const Allocator& alloc)
264 -> WPI_AUTO_RETURN_TYPE(alloc.max_array_size(), std::size_t)
265
266 template <class Allocator>
267 std::size_t max_array_size(min_concept, const Allocator& alloc)
268 {
269 return max_node_size(full_concept{}, alloc);
270 }
271
272 //=== max_alignment() ===//
273 // first try Allocator::max_alignment()
274 // then return detail::max_alignment
275 template <class Allocator>
276 auto max_alignment(full_concept, const Allocator& alloc)
277 -> WPI_AUTO_RETURN_TYPE(alloc.max_alignment(), std::size_t)
278
279 template <class Allocator>
280 std::size_t max_alignment(min_concept, const Allocator&)
281 {
283 }
284 } // namespace traits_detail
285
286 /// The default specialization of the allocator_traits for a RawAllocator.
287 /// See the last link for the requirements on types that do not specialize this class and the interface documentation.
288 /// Any specialization must provide the same interface.
289 /// \ingroup memory_core
290 template <class Allocator>
292 {
293 public:
297
298 static void* allocate_node(allocator_type& state, std::size_t size,
299 std::size_t alignment)
300 {
302 "Allocator cannot be used as RawAllocator because it provides custom "
303 "construct()/destroy()");
305 alignment);
306 }
307
308 static void* allocate_array(allocator_type& state, std::size_t count, std::size_t size,
309 std::size_t alignment)
310 {
312 "Allocator cannot be used as RawAllocator because it provides custom "
313 "construct()/destroy()");
315 size, alignment);
316 }
317
318 static void deallocate_node(allocator_type& state, void* node, std::size_t size,
319 std::size_t alignment) noexcept
320 {
322 "Allocator cannot be used as RawAllocator because it provides custom "
323 "construct()/destroy()");
325 alignment);
326 }
327
328 static void deallocate_array(allocator_type& state, void* array, std::size_t count,
329 std::size_t size, std::size_t alignment) noexcept
330 {
332 "Allocator cannot be used as RawAllocator because it provides custom "
333 "construct()/destroy()");
335 size, alignment);
336 }
337
338 static std::size_t max_node_size(const allocator_type& state)
339 {
341 "Allocator cannot be used as RawAllocator because it provides custom "
342 "construct()/destroy()");
344 }
345
346 static std::size_t max_array_size(const allocator_type& state)
347 {
349 "Allocator cannot be used as RawAllocator because it provides custom "
350 "construct()/destroy()");
352 }
353
354 static std::size_t max_alignment(const allocator_type& state)
355 {
357 "Allocator cannot be used as RawAllocator because it provides custom "
358 "construct()/destroy()");
360 }
361
362#if !defined(DOXYGEN)
363 using foonathan_memory_default_traits = std::true_type;
364#endif
365 };
366
367 namespace detail
368 {
369 template <class RawAllocator>
370 typename allocator_traits<RawAllocator>::foonathan_memory_default_traits
372
373 std::false_type alloc_uses_default_traits(...);
374
375 template <typename T>
377 : std::is_same<
378 decltype(traits_detail::allocate_node(traits_detail::full_concept{},
379 std::declval<typename allocator_traits<
380 T>::allocator_type&>(),
381 0, 0)),
382 traits_detail::error>
383 {
384 };
385
386 template <typename T>
388 : std::is_same<
389 decltype(traits_detail::deallocate_node(traits_detail::full_concept{},
390 std::declval<typename allocator_traits<
391 T>::allocator_type&>(),
392 nullptr, 0, 0)),
393 traits_detail::error>
394 {
395 };
396
397 template <typename T, class DefaultTraits>
398 struct is_raw_allocator : std::true_type
399 {
400 };
401
402 template <typename T>
403 struct is_raw_allocator<T, std::integral_constant<bool, true>>
404 : std::integral_constant<bool, allocator_is_raw_allocator<T>::value
405 && !(has_invalid_alloc_function<T>::value
406 || has_invalid_dealloc_function<T>::value)>
407 {
408 };
409 } // namespace detail
410
411 /// Traits that check whether a type models concept RawAllocator.<br>
412 /// It must either provide the necessary functions for the default traits specialization or has specialized it.
413 /// \ingroup memory_core
414 template <typename T>
417 decltype(detail::alloc_uses_default_traits(std::declval<T&>()))>
418 {
419 };
420
421 namespace traits_detail
422 {
423 //=== try_allocate_node() ===//
424 // try Allocator::try_allocate_node
425 // otherwise error
426 template <class Allocator>
427 auto try_allocate_node(full_concept, Allocator& alloc, std::size_t size,
428 std::size_t alignment) noexcept
429 -> WPI_AUTO_RETURN_TYPE(alloc.try_allocate_node(size, alignment), void*)
430
431 template <class Allocator>
432 error try_allocate_node(error, Allocator&, std::size_t, std::size_t)
433 {
435 "type is not a composable RawAllocator as it does not provide: void* "
436 "try_allocate_node(std::size_t, "
437 "std::size_t)");
438 return {};
439 }
440
441 //=== try_deallocate_node() ===//
442 // try Allocator::try_deallocate_node
443 // otherwise error
444 template <class Allocator>
445 auto try_deallocate_node(full_concept, Allocator& alloc, void* ptr, std::size_t size,
446 std::size_t alignment) noexcept
447 -> WPI_AUTO_RETURN_TYPE(alloc.try_deallocate_node(ptr, size, alignment), bool)
448
449 template <class Allocator>
450 error try_deallocate_node(error, Allocator&, void*, std::size_t, std::size_t)
451 {
453 "type is not a composable RawAllocator as it does not provide: bool "
454 "try_deallocate_node(void*, std::size_t, "
455 "std::size_t)");
456 return error{};
457 }
458
459 //=== try_allocate_array() ===//
460 // first try Allocator::try_allocate_array
461 // then forward to try_allocate_node()
462 template <class Allocator>
463 auto try_allocate_array(full_concept, Allocator& alloc, std::size_t count,
464 std::size_t size, std::size_t alignment) noexcept
465 -> WPI_AUTO_RETURN_TYPE(alloc.try_allocate_array(count, size, alignment),
466 void*)
467
468 template <class Allocator>
469 void* try_allocate_array(min_concept, Allocator& alloc, std::size_t count,
470 std::size_t size, std::size_t alignment)
471 {
472 return try_allocate_node(full_concept{}, alloc, count * size, alignment);
473 }
474
475 //=== try_deallocate_array() ===//
476 // first try Allocator::try_deallocate_array
477 // then forward to try_deallocate_node()
478 template <class Allocator>
479 auto try_deallocate_array(full_concept, Allocator& alloc, void* ptr, std::size_t count,
480 std::size_t size, std::size_t alignment) noexcept
481 -> WPI_AUTO_RETURN_TYPE(alloc.try_deallocate_array(ptr, count, size,
482 alignment),
483 bool)
484
485 template <class Allocator>
486 bool try_deallocate_array(min_concept, Allocator& alloc, void* ptr,
487 std::size_t count, std::size_t size,
488 std::size_t alignment) noexcept
489 {
490 return try_deallocate_node(full_concept{}, alloc, ptr, count * size, alignment);
491 }
492 } // namespace traits_detail
493
494 /// The default specialization of the composable_allocator_traits for a ComposableAllocator.
495 /// See the last link for the requirements on types that do not specialize this class and the interface documentation.
496 /// Any specialization must provide the same interface.
497 /// \ingroup memory_core
498 template <class Allocator>
500 {
501 public:
503
504 static void* try_allocate_node(allocator_type& state, std::size_t size,
505 std::size_t alignment) noexcept
506 {
508 "ComposableAllocator must be RawAllocator");
510 alignment);
511 }
512
513 static void* try_allocate_array(allocator_type& state, std::size_t count,
514 std::size_t size, std::size_t alignment) noexcept
515 {
517 "ComposableAllocator must be RawAllocator");
519 count, size, alignment);
520 }
521
522 static bool try_deallocate_node(allocator_type& state, void* node, std::size_t size,
523 std::size_t alignment) noexcept
524 {
526 "ComposableAllocator must be RawAllocator");
528 node, size, alignment);
529 }
530
531 static bool try_deallocate_array(allocator_type& state, void* array, std::size_t count,
532 std::size_t size, std::size_t alignment) noexcept
533 {
535 "ComposableAllocator must be RawAllocator");
537 array, count, size, alignment);
538 }
539
540#if !defined(DOXYGEN)
541 using foonathan_memory_default_traits = std::true_type;
542#endif
543 };
544
545 namespace detail
546 {
547 template <class RawAllocator>
548 typename composable_allocator_traits<RawAllocator>::foonathan_memory_default_traits
550
552
553 template <typename T>
555 : std::is_same<
556 decltype(traits_detail::try_allocate_node(traits_detail::full_concept{},
557 std::declval<typename allocator_traits<
558 T>::allocator_type&>(),
559 0, 0)),
560 traits_detail::error>
561 {
562 };
563
564 template <typename T>
566 : std::is_same<decltype(traits_detail::
567 try_deallocate_node(traits_detail::full_concept{},
568 std::declval<typename allocator_traits<
569 T>::allocator_type&>(),
570 nullptr, 0, 0)),
571 traits_detail::error>
572 {
573 };
574
575 template <typename T, class DefaultTraits>
579
580 template <typename T>
581 struct is_composable_allocator<T, std::integral_constant<bool, true>>
582 : std::integral_constant<bool, memory::is_raw_allocator<T>::value
583 && !(has_invalid_try_alloc_function<T>::value
584 || has_invalid_try_dealloc_function<T>::value)>
585 {
586 };
587 } // namespace detail
588
589 /// Traits that check whether a type models concept ComposableAllocator.<br>
590 /// It must be a RawAllocator and either provide the necessary functions for the default traits specialization or has specialized it.
591 /// \ingroup memory_core
592 template <typename T>
594 : detail::is_composable_allocator<T, decltype(detail::composable_alloc_uses_default_traits(
595 std::declval<T&>()))>
596 {
597 };
598 } // namespace memory
599} // namespace wpi
600
601#endif // WPI_MEMORY_ALLOCATOR_TRAITS_HPP_INCLUDED
This class is a wrapper around std::array that does compile time size checking.
Definition array.h:26
The default specialization of the allocator_traits for a RawAllocator.
Definition allocator_traits.hpp:292
static void deallocate_array(allocator_type &state, void *array, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:328
traits_detail::allocator_type< Allocator > allocator_type
Definition allocator_traits.hpp:294
static void * allocate_array(allocator_type &state, std::size_t count, std::size_t size, std::size_t alignment)
Definition allocator_traits.hpp:308
static std::size_t max_array_size(const allocator_type &state)
Definition allocator_traits.hpp:346
static std::size_t max_node_size(const allocator_type &state)
Definition allocator_traits.hpp:338
static std::size_t max_alignment(const allocator_type &state)
Definition allocator_traits.hpp:354
static void * allocate_node(allocator_type &state, std::size_t size, std::size_t alignment)
Definition allocator_traits.hpp:298
static void deallocate_node(allocator_type &state, void *node, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:318
decltype(traits_detail::is_stateful< Allocator >(traits_detail::full_concept{})) is_stateful
Definition allocator_traits.hpp:295
The default specialization of the composable_allocator_traits for a ComposableAllocator.
Definition allocator_traits.hpp:500
static void * try_allocate_node(allocator_type &state, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:504
typename allocator_traits< Allocator >::allocator_type allocator_type
Definition allocator_traits.hpp:502
static void * try_allocate_array(allocator_type &state, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:513
static bool try_deallocate_node(allocator_type &state, void *node, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:522
static bool try_deallocate_array(allocator_type &state, void *array, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:531
Configuration macros.
auto ptr(T p) -> const void *
Converts p to const void* for pointer formatting.
Definition format.h:3821
detail namespace with internal helper functions
Definition input_adapters.h:32
Implement std::hash so that hash_code can be used in STL containers.
Definition PointerIntPair.h:280
std::true_type has_construct(int,)
void construct(std::true_type, T *cur, T *end, Args &&... args)
Definition smart_ptr.hpp:45
std::true_type has_destroy(int,)
composable_allocator_traits< RawAllocator >::foonathan_memory_default_traits composable_alloc_uses_default_traits(RawAllocator &)
constexpr std::size_t max_alignment
Definition align.hpp:42
allocator_traits< RawAllocator >::foonathan_memory_default_traits alloc_uses_default_traits(RawAllocator &)
auto is_stateful(full_concept) -> decltype(typename Allocator::is_stateful{})
auto allocate_array(full_concept, Allocator &alloc, std::size_t count, std::size_t size, std::size_t alignment) -> WPI_AUTO_RETURN_TYPE(alloc.allocate_array(count, size, alignment), void *) template< class Allocator > void *allocate_array(min_concept, Allocator &alloc, std::size_t count, std::size_t size, std::size_t alignment)
Definition allocator_traits.hpp:218
auto allocate_node(full_concept, Allocator &alloc, std::size_t size, std::size_t alignment) -> WPI_AUTO_RETURN_TYPE(alloc.allocate_node(size, alignment), void *) template< class Allocator > auto allocate_node(std_concept, Allocator &alloc, std::size_t size, std::size_t) -> WPI_AUTO_RETURN(static_cast< void * >(alloc.allocate(size))) template< class Allocator > error allocate_node(error, Allocator &, std::size_t, std::size_t)
Definition allocator_traits.hpp:172
typename std::decay< typename allocator_type_impl< Allocator >::type >::type allocator_type
Definition allocator_traits.hpp:134
auto try_deallocate_node(full_concept, Allocator &alloc, void *ptr, std::size_t size, std::size_t alignment) noexcept -> WPI_AUTO_RETURN_TYPE(alloc.try_deallocate_node(ptr, size, alignment), bool) template< class Allocator > error try_deallocate_node(error, Allocator &, void *, std::size_t, std::size_t)
Definition allocator_traits.hpp:445
auto try_allocate_array(full_concept, Allocator &alloc, std::size_t count, std::size_t size, std::size_t alignment) noexcept -> WPI_AUTO_RETURN_TYPE(alloc.try_allocate_array(count, size, alignment), void *) template< class Allocator > void *try_allocate_array(min_concept, Allocator &alloc, std::size_t count, std::size_t size, std::size_t alignment)
Definition allocator_traits.hpp:463
auto deallocate_array(full_concept, Allocator &alloc, void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept -> WPI_AUTO_RETURN_TYPE(alloc.deallocate_array(ptr, count, size, alignment), void) template< class Allocator > void deallocate_array(min_concept, Allocator &alloc, void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:233
auto max_alignment(full_concept, const Allocator &alloc) -> WPI_AUTO_RETURN_TYPE(alloc.max_alignment(), std::size_t) template< class Allocator > std::size_t max_alignment(min_concept, const Allocator &)
Definition allocator_traits.hpp:276
auto rebind_impl(int) -> typename Allocator::template rebind< char >::other &
auto try_deallocate_array(full_concept, Allocator &alloc, void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept -> WPI_AUTO_RETURN_TYPE(alloc.try_deallocate_array(ptr, count, size, alignment), bool) template< class Allocator > bool try_deallocate_array(min_concept, Allocator &alloc, void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept
Definition allocator_traits.hpp:479
auto try_allocate_node(full_concept, Allocator &alloc, std::size_t size, std::size_t alignment) noexcept -> WPI_AUTO_RETURN_TYPE(alloc.try_allocate_node(size, alignment), void *) template< class Allocator > error try_allocate_node(error, Allocator &, std::size_t, std::size_t)
Definition allocator_traits.hpp:427
auto deallocate_node(full_concept, Allocator &alloc, void *ptr, std::size_t size, std::size_t alignment) noexcept -> WPI_AUTO_RETURN_TYPE(alloc.deallocate_node(ptr, size, alignment), void) template< class Allocator > auto deallocate_node(std_concept, Allocator &alloc, void *ptr, std::size_t size, std::size_t) noexcept -> WPI_AUTO_RETURN_TYPE(alloc.deallocate(static_cast< char * >(ptr), size), void) template< class Allocator > error deallocate_node(error, Allocator &, void *, std::size_t, std::size_t)
Definition allocator_traits.hpp:195
auto max_node_size(full_concept, const Allocator &alloc) -> WPI_AUTO_RETURN_TYPE(alloc.max_node_size(), std::size_t) template< class Allocator > std::size_t max_node_size(min_concept, const Allocator &) noexcept
Definition allocator_traits.hpp:250
auto max_array_size(full_concept, const Allocator &alloc) -> WPI_AUTO_RETURN_TYPE(alloc.max_array_size(), std::size_t) template< class Allocator > std::size_t max_array_size(min_concept, const Allocator &alloc)
Definition allocator_traits.hpp:263
Memory namespace.
Definition heap_allocator.hpp:20
Foonathan namespace.
Definition ntcore_cpp.h:26
array(T, Ts...) -> array< T, 1+sizeof...(Ts)>
Traits class that checks whether or not a standard Allocator can be used as RawAllocator.
Definition allocator_traits.hpp:61
Definition allocator_traits.hpp:44
decltype(has_construct< Allocator >(0)) custom_construct
Definition allocator_traits.hpp:45
decltype(has_destroy< Allocator >(0)) custom_destroy
Definition allocator_traits.hpp:46
std::integral_constant< bool, !custom_construct::value &&!custom_destroy::value > valid
Definition allocator_traits.hpp:48
Definition allocator_traits.hpp:383
Definition allocator_traits.hpp:394
Definition allocator_traits.hpp:561
Definition allocator_traits.hpp:577
Definition allocator_traits.hpp:399
Traits that check whether a type models concept ComposableAllocator.
Definition allocator_traits.hpp:596
Traits that check whether a type models concept RawAllocator.
Definition allocator_traits.hpp:418
Alloc< T, Args... > & type
Definition allocator_traits.hpp:118
Definition allocator_traits.hpp:110
Allocator & type
Definition allocator_traits.hpp:111
Definition allocator_traits.hpp:129
decltype(rebind_impl< Allocator >(0)) type
Definition allocator_traits.hpp:130
Definition allocator_traits.hpp:76
Definition allocator_traits.hpp:91
std::true_type type
Definition allocator_traits.hpp:160
std::false_type type
Definition allocator_traits.hpp:154
Definition allocator_traits.hpp:144
Definition allocator_traits.hpp:88
Definition allocator_traits.hpp:85
#define WPI_AUTO_RETURN(Expr)
Definition utility.hpp:88
#define WPI_AUTO_RETURN_TYPE(Expr, T)
Definition utility.hpp:95
#define WPI_SFINAE(Expr)
Definition utility.hpp:85
#define WPI_MEMORY_UNREACHABLE(Msg)
Definition assert.hpp:48