File third-party/pmr/polymorphic_allocator.hpp changed (mode: 100644) (index caeb6f3..b5ba949) |
... |
... |
bool operator!=(const memory_resource& a, const memory_resource& b) |
74 |
74 |
return ! (a == b); |
return ! (a == b); |
75 |
75 |
} |
} |
76 |
76 |
|
|
77 |
|
namespace __details { |
|
|
77 |
|
namespace _details { |
78 |
78 |
|
|
79 |
79 |
// STL allocator that holds a pointer to a polymorphic allocator resource. |
// STL allocator that holds a pointer to a polymorphic allocator resource. |
80 |
80 |
// Used to implement `polymorphic_allocator`, which is a scoped allocator. |
// Used to implement `polymorphic_allocator`, which is a scoped allocator. |
|
... |
... |
class resource_adaptor_imp : public memory_resource |
164 |
164 |
allocator_type get_allocator() const { return m_alloc; } |
allocator_type get_allocator() const { return m_alloc; } |
165 |
165 |
}; |
}; |
166 |
166 |
|
|
167 |
|
} // end namespace __details |
|
|
167 |
|
} // end namespace _details |
168 |
168 |
|
|
169 |
169 |
// A resource_adaptor converts a traditional STL allocator to a polymorphic |
// A resource_adaptor converts a traditional STL allocator to a polymorphic |
170 |
170 |
// memory resource. Somehow, this didn't make it into C++17, but it should |
// memory resource. Somehow, this didn't make it into C++17, but it should |
|
... |
... |
class resource_adaptor_imp : public memory_resource |
173 |
173 |
// `resource_adaptor<U>` are always the same type, whether or not |
// `resource_adaptor<U>` are always the same type, whether or not |
174 |
174 |
// `T` and `U` are the same type. |
// `T` and `U` are the same type. |
175 |
175 |
template <class Allocator> |
template <class Allocator> |
176 |
|
using resource_adaptor = __details::resource_adaptor_imp< |
|
|
176 |
|
using resource_adaptor = _details::resource_adaptor_imp< |
177 |
177 |
typename allocator_traits<Allocator>::template rebind_alloc<byte>>; |
typename allocator_traits<Allocator>::template rebind_alloc<byte>>; |
178 |
178 |
|
|
179 |
179 |
// Memory resource that uses new and delete. |
// Memory resource that uses new and delete. |
|
... |
... |
memory_resource *set_default_resource(memory_resource *r); |
190 |
190 |
|
|
191 |
191 |
template <class Tp> |
template <class Tp> |
192 |
192 |
class polymorphic_allocator : |
class polymorphic_allocator : |
193 |
|
public scoped_allocator_adaptor<__details::polymorphic_allocator_imp<Tp>> |
|
|
193 |
|
public scoped_allocator_adaptor<_details::polymorphic_allocator_imp<Tp>> |
194 |
194 |
{ |
{ |
195 |
|
typedef __details::polymorphic_allocator_imp<Tp> Imp; |
|
|
195 |
|
typedef _details::polymorphic_allocator_imp<Tp> Imp; |
196 |
196 |
typedef scoped_allocator_adaptor<Imp> Base; |
typedef scoped_allocator_adaptor<Imp> Base; |
197 |
197 |
|
|
198 |
198 |
public: |
public: |
|
... |
... |
class polymorphic_allocator : |
209 |
209 |
: Base(Imp((other.resource()))) { } |
: Base(Imp((other.resource()))) { } |
210 |
210 |
|
|
211 |
211 |
template <class U> |
template <class U> |
212 |
|
polymorphic_allocator(const __details::polymorphic_allocator_imp<U>& other) |
|
|
212 |
|
polymorphic_allocator(const _details::polymorphic_allocator_imp<U>& other) |
213 |
213 |
: Base(other) { } |
: Base(other) { } |
214 |
214 |
|
|
215 |
215 |
// Return a default-constructed allocator |
// Return a default-constructed allocator |
|
... |
... |
pmr::set_default_resource(pmr::memory_resource *r) |
268 |
268 |
template <class Allocator> |
template <class Allocator> |
269 |
269 |
template <class Allocator2> |
template <class Allocator2> |
270 |
270 |
inline |
inline |
271 |
|
pmr::__details::resource_adaptor_imp<Allocator>::resource_adaptor_imp( |
|
|
271 |
|
pmr::_details::resource_adaptor_imp<Allocator>::resource_adaptor_imp( |
272 |
272 |
Allocator2&& a2, typename |
Allocator2&& a2, typename |
273 |
273 |
enable_if<is_convertible<Allocator2, Allocator>::value, int>::type) |
enable_if<is_convertible<Allocator2, Allocator>::value, int>::type) |
274 |
274 |
: m_alloc(forward<Allocator2>(a2)) |
: m_alloc(forward<Allocator2>(a2)) |
|
... |
... |
pmr::__details::resource_adaptor_imp<Allocator>::resource_adaptor_imp( |
278 |
278 |
template <class Allocator> |
template <class Allocator> |
279 |
279 |
template <size_t Align> |
template <size_t Align> |
280 |
280 |
void * |
void * |
281 |
|
pmr::__details::resource_adaptor_imp<Allocator>::allocate_imp(size_t bytes) |
|
|
281 |
|
pmr::_details::resource_adaptor_imp<Allocator>::allocate_imp(size_t bytes) |
282 |
282 |
{ |
{ |
283 |
|
typedef __details::aligned_chunk<Align> chunk; |
|
|
283 |
|
typedef _details::aligned_chunk<Align> chunk; |
284 |
284 |
size_t chunks = (bytes + Align - 1) / Align; |
size_t chunks = (bytes + Align - 1) / Align; |
285 |
285 |
|
|
286 |
286 |
typedef typename allocator_traits<Allocator>:: |
typedef typename allocator_traits<Allocator>:: |
|
... |
... |
pmr::__details::resource_adaptor_imp<Allocator>::allocate_imp(size_t bytes) |
292 |
292 |
template <class Allocator> |
template <class Allocator> |
293 |
293 |
template <size_t Align> |
template <size_t Align> |
294 |
294 |
void |
void |
295 |
|
pmr::__details::resource_adaptor_imp<Allocator>::deallocate_imp(void *p, |
|
296 |
|
size_t bytes) |
|
|
295 |
|
pmr::_details::resource_adaptor_imp<Allocator>::deallocate_imp(void *p, |
|
296 |
|
size_t bytes) |
297 |
297 |
{ |
{ |
298 |
|
typedef __details::aligned_chunk<Align> chunk; |
|
|
298 |
|
typedef _details::aligned_chunk<Align> chunk; |
299 |
299 |
size_t chunks = (bytes + Align - 1) / Align; |
size_t chunks = (bytes + Align - 1) / Align; |
300 |
300 |
|
|
301 |
301 |
typedef typename allocator_traits<Allocator>:: |
typedef typename allocator_traits<Allocator>:: |
|
... |
... |
pmr::__details::resource_adaptor_imp<Allocator>::deallocate_imp(void *p, |
306 |
306 |
|
|
307 |
307 |
template <class Allocator> |
template <class Allocator> |
308 |
308 |
void * |
void * |
309 |
|
pmr::__details::resource_adaptor_imp<Allocator>::do_allocate(size_t bytes, |
|
310 |
|
size_t alignment) |
|
|
309 |
|
pmr::_details::resource_adaptor_imp<Allocator>::do_allocate(size_t bytes, |
|
310 |
|
size_t alignment) |
311 |
311 |
{ |
{ |
312 |
312 |
static const size_t max_natural_alignment = sizeof(max_align_t); |
static const size_t max_natural_alignment = sizeof(max_align_t); |
313 |
313 |
|
|
|
... |
... |
pmr::__details::resource_adaptor_imp<Allocator>::do_allocate(size_t bytes, |
348 |
348 |
|
|
349 |
349 |
template <class Allocator> |
template <class Allocator> |
350 |
350 |
void |
void |
351 |
|
pmr::__details::resource_adaptor_imp<Allocator>::do_deallocate(void *p, |
|
352 |
|
size_t bytes, |
|
353 |
|
size_t alignment) |
|
|
351 |
|
pmr::_details::resource_adaptor_imp<Allocator>::do_deallocate(void *p, |
|
352 |
|
size_t bytes, |
|
353 |
|
size_t alignment) |
354 |
354 |
{ |
{ |
355 |
355 |
static const size_t max_natural_alignment = sizeof(max_align_t); |
static const size_t max_natural_alignment = sizeof(max_align_t); |
356 |
356 |
|
|
|
... |
... |
pmr::__details::resource_adaptor_imp<Allocator>::do_deallocate(void *p, |
380 |
380 |
} |
} |
381 |
381 |
|
|
382 |
382 |
template <class Allocator> |
template <class Allocator> |
383 |
|
bool pmr::__details::resource_adaptor_imp<Allocator>::do_is_equal( |
|
|
383 |
|
bool pmr::_details::resource_adaptor_imp<Allocator>::do_is_equal( |
384 |
384 |
const memory_resource& other) const noexcept |
const memory_resource& other) const noexcept |
385 |
385 |
{ |
{ |
386 |
386 |
const resource_adaptor_imp *other_p = |
const resource_adaptor_imp *other_p = |
|
... |
... |
bool pmr::__details::resource_adaptor_imp<Allocator>::do_is_equal( |
393 |
393 |
} |
} |
394 |
394 |
|
|
395 |
395 |
|
|
396 |
|
namespace __pmrd = pmr::__details; |
|
|
396 |
|
namespace _pmrd = pmr::_details; |
397 |
397 |
|
|
398 |
398 |
template <class Tp> |
template <class Tp> |
399 |
399 |
inline |
inline |
400 |
|
__pmrd::polymorphic_allocator_imp<Tp>::polymorphic_allocator_imp() |
|
|
400 |
|
_pmrd::polymorphic_allocator_imp<Tp>::polymorphic_allocator_imp() |
401 |
401 |
: m_resource(get_default_resource()) |
: m_resource(get_default_resource()) |
402 |
402 |
{ |
{ |
403 |
403 |
} |
} |
404 |
404 |
|
|
405 |
405 |
template <class Tp> |
template <class Tp> |
406 |
406 |
inline |
inline |
407 |
|
__pmrd::polymorphic_allocator_imp<Tp>::polymorphic_allocator_imp( |
|
|
407 |
|
_pmrd::polymorphic_allocator_imp<Tp>::polymorphic_allocator_imp( |
408 |
408 |
pmr::memory_resource *r) |
pmr::memory_resource *r) |
409 |
409 |
: m_resource(r ? r : get_default_resource()) |
: m_resource(r ? r : get_default_resource()) |
410 |
410 |
{ |
{ |
|
... |
... |
__pmrd::polymorphic_allocator_imp<Tp>::polymorphic_allocator_imp( |
413 |
413 |
template <class Tp> |
template <class Tp> |
414 |
414 |
template <class U> |
template <class U> |
415 |
415 |
inline |
inline |
416 |
|
__pmrd::polymorphic_allocator_imp<Tp>::polymorphic_allocator_imp( |
|
417 |
|
const __pmrd::polymorphic_allocator_imp<U>& other) |
|
|
416 |
|
_pmrd::polymorphic_allocator_imp<Tp>::polymorphic_allocator_imp( |
|
417 |
|
const _pmrd::polymorphic_allocator_imp<U>& other) |
418 |
418 |
: m_resource(other.resource()) |
: m_resource(other.resource()) |
419 |
419 |
{ |
{ |
420 |
420 |
} |
} |
421 |
421 |
|
|
422 |
422 |
template <class Tp> |
template <class Tp> |
423 |
423 |
inline |
inline |
424 |
|
Tp *__pmrd::polymorphic_allocator_imp<Tp>::allocate(size_t n) |
|
|
424 |
|
Tp *_pmrd::polymorphic_allocator_imp<Tp>::allocate(size_t n) |
425 |
425 |
{ |
{ |
426 |
426 |
return static_cast<Tp*>(m_resource->allocate(n * sizeof(Tp), alignof(Tp))); |
return static_cast<Tp*>(m_resource->allocate(n * sizeof(Tp), alignof(Tp))); |
427 |
427 |
} |
} |
428 |
428 |
|
|
429 |
429 |
template <class Tp> |
template <class Tp> |
430 |
430 |
inline |
inline |
431 |
|
void __pmrd::polymorphic_allocator_imp<Tp>::deallocate(Tp *p, size_t n) |
|
|
431 |
|
void _pmrd::polymorphic_allocator_imp<Tp>::deallocate(Tp *p, size_t n) |
432 |
432 |
{ |
{ |
433 |
433 |
m_resource->deallocate(p, n * sizeof(Tp), alignof(Tp)); |
m_resource->deallocate(p, n * sizeof(Tp), alignof(Tp)); |
434 |
434 |
} |
} |
435 |
435 |
|
|
436 |
436 |
template <class Tp> |
template <class Tp> |
437 |
437 |
inline |
inline |
438 |
|
__pmrd::polymorphic_allocator_imp<Tp> |
|
439 |
|
__pmrd::polymorphic_allocator_imp<Tp>::select_on_container_copy_construction() |
|
|
438 |
|
_pmrd::polymorphic_allocator_imp<Tp> |
|
439 |
|
_pmrd::polymorphic_allocator_imp<Tp>::select_on_container_copy_construction() |
440 |
440 |
const |
const |
441 |
441 |
{ |
{ |
442 |
|
return __pmrd::polymorphic_allocator_imp<Tp>(); |
|
|
442 |
|
return _pmrd::polymorphic_allocator_imp<Tp>(); |
443 |
443 |
} |
} |
444 |
444 |
|
|
445 |
445 |
template <class Tp> |
template <class Tp> |
446 |
446 |
inline |
inline |
447 |
447 |
pmr::memory_resource * |
pmr::memory_resource * |
448 |
|
__pmrd::polymorphic_allocator_imp<Tp>::resource() const |
|
|
448 |
|
_pmrd::polymorphic_allocator_imp<Tp>::resource() const |
449 |
449 |
{ |
{ |
450 |
450 |
return m_resource; |
return m_resource; |
451 |
451 |
} |
} |
452 |
452 |
|
|
453 |
453 |
template <class T1, class T2> |
template <class T1, class T2> |
454 |
454 |
inline |
inline |
455 |
|
bool __pmrd::operator==(const __pmrd::polymorphic_allocator_imp<T1>& a, |
|
456 |
|
const __pmrd::polymorphic_allocator_imp<T2>& b) |
|
|
455 |
|
bool _pmrd::operator==(const _pmrd::polymorphic_allocator_imp<T1>& a, |
|
456 |
|
const _pmrd::polymorphic_allocator_imp<T2>& b) |
457 |
457 |
{ |
{ |
458 |
458 |
// `operator==` for `memory_resource` first checks for equality of |
// `operator==` for `memory_resource` first checks for equality of |
459 |
459 |
// addresses and calls `is_equal` only if the addresses differ. The call |
// addresses and calls `is_equal` only if the addresses differ. The call |
|
... |
... |
bool __pmrd::operator==(const __pmrd::polymorphic_allocator_imp<T1>& a, |
466 |
466 |
|
|
467 |
467 |
template <class T1, class T2> |
template <class T1, class T2> |
468 |
468 |
inline |
inline |
469 |
|
bool __pmrd::operator!=(const __pmrd::polymorphic_allocator_imp<T1>& a, |
|
470 |
|
const __pmrd::polymorphic_allocator_imp<T2>& b) |
|
|
469 |
|
bool _pmrd::operator!=(const _pmrd::polymorphic_allocator_imp<T1>& a, |
|
470 |
|
const _pmrd::polymorphic_allocator_imp<T2>& b) |
471 |
471 |
{ |
{ |
472 |
472 |
return *a.resource() != *b.resource(); |
return *a.resource() != *b.resource(); |
473 |
473 |
} |
} |