1/*
2Copyright 2020 Glen Joseph Fernandes
3(glenjofe@gmail.com)
4
5Distributed under the Boost Software License, Version 1.0.
6(http://www.boost.org/LICENSE_1_0.txt)
7*/
8#ifndef BOOST_CORE_ALLOCATOR_ACCESS_HPP
9#define BOOST_CORE_ALLOCATOR_ACCESS_HPP
10
11#include <boost/config.hpp>
12#if !defined(BOOST_NO_CXX11_ALLOCATOR)
13#include <boost/core/pointer_traits.hpp>
14#if !defined(BOOST_MSVC)
15#include <limits>
16#else
17#include <memory>
18#endif
19#include <type_traits>
20#endif
21#include <new>
22#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
23#include <utility>
24#endif
25
26namespace boost {
27namespace detail {
28
29#if defined(BOOST_NO_CXX11_ALLOCATOR)
30struct alloc_false {
31 BOOST_STATIC_CONSTEXPR bool value = false;
32};
33#else
34template<class>
35struct alloc_void {
36 typedef void type;
37};
38#endif
39
40} /* detail */
41
42template<class A>
43struct allocator_value_type {
44 typedef typename A::value_type type;
45};
46
47#if defined(BOOST_NO_CXX11_ALLOCATOR)
48template<class A>
49struct allocator_pointer {
50 typedef typename A::pointer type;
51};
52#elif defined(BOOST_MSVC)
53template<class A>
54struct allocator_pointer {
55 typedef typename std::allocator_traits<A>::pointer type;
56};
57#else
58template<class A, class = void>
59struct allocator_pointer {
60 typedef typename A::value_type* type;
61};
62
63template<class A>
64struct allocator_pointer<A,
65 typename detail::alloc_void<typename A::pointer>::type> {
66 typedef typename A::pointer type;
67};
68#endif
69
70#if defined(BOOST_NO_CXX11_ALLOCATOR)
71template<class A>
72struct allocator_const_pointer {
73 typedef typename A::const_pointer type;
74};
75#elif defined(BOOST_MSVC)
76template<class A>
77struct allocator_const_pointer {
78 typedef typename std::allocator_traits<A>::const_pointer type;
79};
80#else
81template<class A, class = void>
82struct allocator_const_pointer {
83 typedef typename pointer_traits<typename
84 allocator_pointer<A>::type>::template
85 rebind_to<const typename A::value_type>::type type;
86};
87
88template<class A>
89struct allocator_const_pointer<A,
90 typename detail::alloc_void<typename A::const_pointer>::type> {
91 typedef typename A::const_pointer type;
92};
93#endif
94
95#if defined(BOOST_NO_CXX11_ALLOCATOR)
96template<class A>
97struct allocator_void_pointer {
98 typedef typename A::template rebind<void>::other::pointer type;
99};
100#else
101template<class A, class = void>
102struct allocator_void_pointer {
103 typedef typename pointer_traits<typename
104 allocator_pointer<A>::type>::template
105 rebind_to<void>::type type;
106};
107
108template<class A>
109struct allocator_void_pointer<A,
110 typename detail::alloc_void<typename A::void_pointer>::type> {
111 typedef typename A::void_pointer type;
112};
113#endif
114
115#if defined(BOOST_NO_CXX11_ALLOCATOR)
116template<class A>
117struct allocator_const_void_pointer {
118 typedef typename A::template rebind<void>::other::const_pointer type;
119};
120#else
121template<class A, class = void>
122struct allocator_const_void_pointer {
123 typedef typename pointer_traits<typename
124 allocator_pointer<A>::type>::template
125 rebind_to<const void>::type type;
126};
127
128template<class A>
129struct allocator_const_void_pointer<A,
130 typename detail::alloc_void<typename A::const_void_pointer>::type> {
131 typedef typename A::const_void_pointer type;
132};
133#endif
134
135#if defined(BOOST_NO_CXX11_ALLOCATOR)
136template<class A>
137struct allocator_difference_type {
138 typedef typename A::difference_type type;
139};
140#elif defined(BOOST_MSVC)
141template<class A>
142struct allocator_difference_type {
143 typedef typename std::allocator_traits<A>::difference_type type;
144};
145#else
146template<class A, class = void>
147struct allocator_difference_type {
148 typedef typename pointer_traits<typename
149 allocator_pointer<A>::type>::difference_type type;
150};
151
152template<class A>
153struct allocator_difference_type<A,
154 typename detail::alloc_void<typename A::difference_type>::type> {
155 typedef typename A::difference_type type;
156};
157#endif
158
159#if defined(BOOST_NO_CXX11_ALLOCATOR)
160template<class A>
161struct allocator_size_type {
162 typedef typename A::size_type type;
163};
164#elif defined(BOOST_MSVC)
165template<class A>
166struct allocator_size_type {
167 typedef typename std::allocator_traits<A>::size_type type;
168};
169#else
170template<class A, class = void>
171struct allocator_size_type {
172 typedef typename std::make_unsigned<typename
173 allocator_difference_type<A>::type>::type type;
174};
175
176template<class A>
177struct allocator_size_type<A,
178 typename detail::alloc_void<typename A::size_type>::type> {
179 typedef typename A::size_type type;
180};
181#endif
182
183#if defined(BOOST_NO_CXX11_ALLOCATOR)
184template<class A>
185struct allocator_propagate_on_container_copy_assignment {
186 typedef detail::alloc_false type;
187};
188#else
189template<class A, class = void>
190struct allocator_propagate_on_container_copy_assignment {
191 typedef std::false_type type;
192};
193
194template<class A>
195struct allocator_propagate_on_container_copy_assignment<A,
196 typename detail::alloc_void<typename
197 A::propagate_on_container_copy_assignment>::type> {
198 typedef typename A::propagate_on_container_copy_assignment type;
199};
200#endif
201
202#if defined(BOOST_NO_CXX11_ALLOCATOR)
203template<class A>
204struct allocator_propagate_on_container_move_assignment {
205 typedef detail::alloc_false type;
206};
207#else
208template<class A, class = void>
209struct allocator_propagate_on_container_move_assignment {
210 typedef std::false_type type;
211};
212
213template<class A>
214struct allocator_propagate_on_container_move_assignment<A,
215 typename detail::alloc_void<typename
216 A::propagate_on_container_move_assignment>::type> {
217 typedef typename A::propagate_on_container_move_assignment type;
218};
219#endif
220
221#if defined(BOOST_NO_CXX11_ALLOCATOR)
222template<class A>
223struct allocator_propagate_on_container_swap {
224 typedef detail::alloc_false type;
225};
226#else
227template<class A, class = void>
228struct allocator_propagate_on_container_swap {
229 typedef std::false_type type;
230};
231
232template<class A>
233struct allocator_propagate_on_container_swap<A,
234 typename detail::alloc_void<typename
235 A::propagate_on_container_swap>::type> {
236 typedef typename A::propagate_on_container_swap type;
237};
238#endif
239
240#if defined(BOOST_NO_CXX11_ALLOCATOR)
241template<class A>
242struct allocator_is_always_equal {
243 typedef detail::alloc_false type;
244};
245#else
246template<class A, class = void>
247struct allocator_is_always_equal {
248 typedef typename std::is_empty<A>::type type;
249};
250
251template<class A>
252struct allocator_is_always_equal<A,
253 typename detail::alloc_void<typename A::is_always_equal>::type> {
254 typedef typename A::is_always_equal type;
255};
256#endif
257
258#if defined(BOOST_NO_CXX11_ALLOCATOR)
259template<class A, class T>
260struct allocator_rebind {
261 typedef typename A::template rebind<T>::other type;
262};
263#elif defined(BOOST_MSVC)
264template<class A, class T>
265struct allocator_rebind {
266 typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
267};
268#else
269namespace detail {
270
271template<class, class>
272struct alloc_to { };
273
274template<template<class, class...> class A, class T, class U, class... V>
275struct alloc_to<A<U, V...>, T> {
276 typedef A<T, V...> type;
277};
278
279} /* detail */
280
281template<class A, class T, class = void>
282struct allocator_rebind {
283 typedef typename detail::alloc_to<A, T>::type type;
284};
285
286template<class A, class T>
287struct allocator_rebind<A, T,
288 typename detail::alloc_void<typename A::template rebind<T>::other>::type> {
289 typedef typename A::template rebind<T>::other type;
290};
291#endif
292
293template<class A>
294inline typename allocator_pointer<A>::type
295allocator_allocate(A& a, typename allocator_size_type<A>::type n)
296{
297 return a.allocate(n);
298}
299
300template<class A>
301inline void
302allocator_deallocate(A& a, typename allocator_pointer<A>::type p,
303 typename allocator_size_type<A>::type n)
304{
305 a.deallocate(p, n);
306}
307
308#if defined(BOOST_NO_CXX11_ALLOCATOR)
309template<class A>
310inline typename allocator_pointer<A>::type
311allocator_allocate(A& a, typename allocator_size_type<A>::type n,
312 typename allocator_const_void_pointer<A>::type h)
313{
314 return a.allocate(n, h);
315}
316#elif defined(BOOST_MSVC)
317template<class A>
318inline typename allocator_pointer<A>::type
319allocator_allocate(A& a, typename allocator_size_type<A>::type n,
320 typename allocator_const_void_pointer<A>::type h)
321{
322 return std::allocator_traits<A>::allocate(a, n, h);
323}
324#else
325namespace detail {
326
327template<class, class, class, class = void>
328struct alloc_has_allocate {
329 BOOST_STATIC_CONSTEXPR bool value = false;
330};
331
332template<class A, class N, class H>
333struct alloc_has_allocate<A, N, H,
334 typename alloc_void<decltype(std::declval<A&>().allocate(std::declval<N>(),
335 std::declval<H>()))>::type> {
336 BOOST_STATIC_CONSTEXPR bool value = true;
337};
338
339} /* detail */
340
341template<class A>
342inline typename std::enable_if<detail::alloc_has_allocate<A,
343 typename allocator_size_type<A>::type,
344 typename allocator_const_void_pointer<A>::type>::value,
345 typename allocator_pointer<A>::type>::type
346allocator_allocate(A& a, typename allocator_size_type<A>::type n,
347 typename allocator_const_void_pointer<A>::type h)
348{
349 return a.allocate(n, h);
350}
351
352template<class A>
353inline typename std::enable_if<!detail::alloc_has_allocate<A,
354 typename allocator_size_type<A>::type,
355 typename allocator_const_void_pointer<A>::type>::value,
356 typename allocator_pointer<A>::type>::type
357allocator_allocate(A& a, typename allocator_size_type<A>::type n,
358 typename allocator_const_void_pointer<A>::type)
359{
360 return a.allocate(n);
361}
362#endif
363
364#if defined(BOOST_NO_CXX11_ALLOCATOR)
365template<class A, class T>
366inline void
367allocator_construct(A&, T* p)
368{
369 ::new((void*)p) T();
370}
371
372#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
373#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
374template<class A, class T, class V, class... Args>
375inline void
376allocator_construct(A&, T* p, V&& v, Args&&... args)
377{
378 ::new((void*)p) T(std::forward<V>(v), std::forward<Args>(args)...);
379}
380#else
381template<class A, class T, class V>
382inline void
383allocator_construct(A&, T* p, V&& v)
384{
385 ::new((void*)p) T(std::forward<V>(v));
386}
387#endif
388#else
389template<class A, class T, class V>
390inline void
391allocator_construct(A&, T* p, const V& v)
392{
393 ::new((void*)p) T(v);
394}
395
396template<class A, class T, class V>
397inline void
398allocator_construct(A&, T* p, V& v)
399{
400 ::new((void*)p) T(v);
401}
402#endif
403#elif defined(BOOST_MSVC)
404template<class A, class T, class... Args>
405inline void
406allocator_construct(A& a, T* p, Args&&... args)
407{
408 std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...);
409}
410#else
411namespace detail {
412
413template<class, class, class, class...>
414struct alloc_has_construct {
415 BOOST_STATIC_CONSTEXPR bool value = false;
416};
417
418template<class A, class T, class... Args>
419struct alloc_has_construct<typename alloc_void<decltype(std::declval<A
420 &>().construct(std::declval<T*>(), std::declval<Args&&>()...))>::type,
421 A, T, Args...> {
422 BOOST_STATIC_CONSTEXPR bool value = true;
423};
424
425} /* detail */
426
427template<class A, class T, class... Args>
428inline typename std::enable_if<detail::alloc_has_construct<void, A, T,
429 Args...>::value>::type
430allocator_construct(A& a, T* p, Args&&... args)
431{
432 a.construct(p, std::forward<Args>(args)...);
433}
434
435template<class A, class T, class... Args>
436inline typename std::enable_if<!detail::alloc_has_construct<void, A, T,
437 Args...>::value>::type
438allocator_construct(A&, T* p, Args&&... args)
439{
440 ::new((void*)p) T(std::forward<Args>(args)...);
441}
442#endif
443
444#if defined(BOOST_NO_CXX11_ALLOCATOR)
445template<class A, class T>
446inline void
447allocator_destroy(A&, T* p)
448{
449 p->~T();
450 (void)p;
451}
452#elif defined(BOOST_MSVC)
453template<class A, class T>
454inline void
455allocator_destroy(A& a, T* p)
456{
457 std::allocator_traits<A>::destroy(a, p);
458}
459#else
460namespace detail {
461
462template<class, class, class = void>
463struct alloc_has_destroy {
464 BOOST_STATIC_CONSTEXPR bool value = false;
465};
466
467template<class A, class T>
468struct alloc_has_destroy<A, T,
469 typename alloc_void<decltype(std::declval<A
470 &>().destroy(std::declval<T*>()))>::type> {
471 BOOST_STATIC_CONSTEXPR bool value = true;
472};
473
474} /* detail */
475
476template<class A, class T>
477inline typename std::enable_if<detail::alloc_has_destroy<A, T>::value>::type
478allocator_destroy(A& a, T* p)
479{
480 a.destroy(p);
481}
482
483template<class A, class T>
484inline typename std::enable_if<!detail::alloc_has_destroy<A, T>::value>::type
485allocator_destroy(A&, T* p)
486{
487 p->~T();
488 (void)p;
489}
490#endif
491
492#if defined(BOOST_NO_CXX11_ALLOCATOR)
493template<class A>
494inline typename allocator_size_type<A>::type
495allocator_max_size(const A& a)
496{
497 return a.max_size();
498}
499#elif defined(BOOST_MSVC)
500template<class A>
501inline typename allocator_size_type<A>::type
502allocator_max_size(const A& a)
503{
504 return std::allocator_traits<A>::max_size(a);
505}
506#else
507namespace detail {
508
509template<class, class = void>
510struct alloc_has_max_size {
511 BOOST_STATIC_CONSTEXPR bool value = false;
512};
513
514template<class A>
515struct alloc_has_max_size<A,
516 typename alloc_void<decltype(std::declval<const
517 A&>().max_size())>::type> {
518 BOOST_STATIC_CONSTEXPR bool value = true;
519};
520
521} /* detail */
522
523template<class A>
524inline typename std::enable_if<detail::alloc_has_max_size<A>::value,
525 typename allocator_size_type<A>::type>::type
526allocator_max_size(const A& a)
527{
528 return a.max_size();
529}
530
531template<class A>
532inline typename std::enable_if<!detail::alloc_has_max_size<A>::value,
533 typename allocator_size_type<A>::type>::type
534allocator_max_size(const A&)
535{
536 return (std::numeric_limits<typename
537 allocator_size_type<A>::type>::max)() / sizeof(typename A::value_type);
538}
539#endif
540
541#if defined(BOOST_NO_CXX11_ALLOCATOR)
542template<class A>
543inline A
544allocator_select_on_container_copy_construction(const A& a)
545{
546 return a;
547}
548#elif defined(BOOST_MSVC)
549template<class A>
550inline A
551allocator_select_on_container_copy_construction(const A& a)
552{
553 return std::allocator_traits<A>::select_on_container_copy_construction(a);
554}
555#else
556namespace detail {
557
558template<class, class = void>
559struct alloc_has_soccc {
560 BOOST_STATIC_CONSTEXPR bool value = false;
561};
562
563template<class A>
564struct alloc_has_soccc<A,
565 typename alloc_void<decltype(std::declval<const
566 A&>().select_on_container_copy_construction())>::type> {
567 BOOST_STATIC_CONSTEXPR bool value = true;
568};
569
570} /* detail */
571
572template<class A>
573inline typename std::enable_if<detail::alloc_has_soccc<A>::value, A>::type
574allocator_select_on_container_copy_construction(const A& a)
575{
576 return a.select_on_container_copy_construction();
577}
578
579template<class A>
580inline typename std::enable_if<!detail::alloc_has_soccc<A>::value, A>::type
581allocator_select_on_container_copy_construction(const A& a)
582{
583 return a;
584}
585#endif
586
587#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
588template<class A>
589using allocator_value_type_t = typename allocator_value_type<A>::type;
590
591template<class A>
592using allocator_pointer_t = typename allocator_pointer<A>::type;
593
594template<class A>
595using allocator_const_pointer_t = typename allocator_const_pointer<A>::type;
596
597template<class A>
598using allocator_void_pointer_t = typename allocator_void_pointer<A>::type;
599
600template<class A>
601using allocator_const_void_pointer_t =
602 typename allocator_const_void_pointer<A>::type;
603
604template<class A>
605using allocator_difference_type_t =
606 typename allocator_difference_type<A>::type;
607
608template<class A>
609using allocator_size_type_t = typename allocator_size_type<A>::type;
610
611template<class A>
612using allocator_propagate_on_container_copy_assignment_t =
613 typename allocator_propagate_on_container_copy_assignment<A>::type;
614
615template<class A>
616using allocator_propagate_on_container_move_assignment_t =
617 typename allocator_propagate_on_container_move_assignment<A>::type;
618
619template<class A>
620using allocator_propagate_on_container_swap_t =
621 typename allocator_propagate_on_container_swap<A>::type;
622
623template<class A>
624using allocator_is_always_equal_t =
625 typename allocator_is_always_equal<A>::type;
626
627template<class A, class T>
628using allocator_rebind_t = typename allocator_rebind<A, T>::type;
629#endif
630
631} /* boost */
632
633#endif
634

source code of include/boost/core/allocator_access.hpp