0,0 → 1,197 |
// <extptr_allocator.h> -*- C++ -*- |
|
// Copyright (C) 2008-2015 Free Software Foundation, Inc. |
// |
// This file is part of the GNU ISO C++ Library. This library is free |
// software; you can redistribute it and/or modify it under the |
// terms of the GNU General Public License as published by the |
// Free Software Foundation; either version 3, or (at your option) |
// any later version. |
|
// This library is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
|
// Under Section 7 of GPL version 3, you are granted additional |
// permissions described in the GCC Runtime Library Exception, version |
// 3.1, as published by the Free Software Foundation. |
|
// You should have received a copy of the GNU General Public License and |
// a copy of the GCC Runtime Library Exception along with this program; |
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
// <http://www.gnu.org/licenses/>. |
|
/** |
* @file ext/extptr_allocator.h |
* This file is a GNU extension to the Standard C++ Library. |
* |
* @author Bob Walters |
* |
* An example allocator which uses an alternative pointer type from |
* bits/pointer.h. Supports test cases which confirm container support |
* for alternative pointers. |
*/ |
|
#ifndef _EXTPTR_ALLOCATOR_H |
#define _EXTPTR_ALLOCATOR_H 1 |
|
#include <memory> |
#include <ext/numeric_traits.h> |
#include <ext/pointer.h> |
|
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) |
{ |
_GLIBCXX_BEGIN_NAMESPACE_VERSION |
|
/** |
* @brief An example allocator which uses a non-standard pointer type. |
* @ingroup allocators |
* |
* This allocator specifies that containers use a 'relative pointer' as it's |
* pointer type. (See ext/pointer.h) Memory allocation in this example |
* is still performed using std::allocator. |
*/ |
template<typename _Tp> |
class _ExtPtr_allocator |
{ |
public: |
typedef std::size_t size_type; |
typedef std::ptrdiff_t difference_type; |
|
// Note the non-standard pointer types. |
typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer; |
typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> > |
const_pointer; |
|
typedef _Tp& reference; |
typedef const _Tp& const_reference; |
typedef _Tp value_type; |
|
template<typename _Up> |
struct rebind |
{ typedef _ExtPtr_allocator<_Up> other; }; |
|
_ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT |
: _M_real_alloc() { } |
|
_ExtPtr_allocator(const _ExtPtr_allocator& __rarg) _GLIBCXX_USE_NOEXCEPT |
: _M_real_alloc(__rarg._M_real_alloc) { } |
|
template<typename _Up> |
_ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) |
_GLIBCXX_USE_NOEXCEPT |
: _M_real_alloc(__rarg._M_getUnderlyingImp()) { } |
|
~_ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT |
{ } |
|
pointer address(reference __x) const _GLIBCXX_NOEXCEPT |
{ return std::__addressof(__x); } |
|
const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT |
{ return std::__addressof(__x); } |
|
pointer allocate(size_type __n, void* __hint = 0) |
{ return _M_real_alloc.allocate(__n,__hint); } |
|
void deallocate(pointer __p, size_type __n) |
{ _M_real_alloc.deallocate(__p.get(), __n); } |
|
size_type max_size() const _GLIBCXX_USE_NOEXCEPT |
{ return __numeric_traits<size_type>::__max / sizeof(_Tp); } |
|
#if __cplusplus >= 201103L |
template<typename _Up, typename... _Args> |
void |
construct(_Up* __p, _Args&&... __args) |
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } |
|
template<typename... _Args> |
void |
construct(pointer __p, _Args&&... __args) |
{ construct(__p.get(), std::forward<_Args>(__args)...); } |
|
template<typename _Up> |
void |
destroy(_Up* __p) |
{ __p->~_Up(); } |
|
void destroy(pointer __p) |
{ destroy(__p.get()); } |
|
#else |
|
void construct(pointer __p, const _Tp& __val) |
{ ::new(__p.get()) _Tp(__val); } |
|
void destroy(pointer __p) |
{ __p->~_Tp(); } |
#endif |
|
template<typename _Up> |
inline bool |
operator==(const _ExtPtr_allocator<_Up>& __rarg) |
{ return _M_real_alloc == __rarg._M_getUnderlyingImp(); } |
|
inline bool |
operator==(const _ExtPtr_allocator& __rarg) |
{ return _M_real_alloc == __rarg._M_real_alloc; } |
|
template<typename _Up> |
inline bool |
operator!=(const _ExtPtr_allocator<_Up>& __rarg) |
{ return _M_real_alloc != __rarg._M_getUnderlyingImp(); } |
|
inline bool |
operator!=(const _ExtPtr_allocator& __rarg) |
{ return _M_real_alloc != __rarg._M_real_alloc; } |
|
template<typename _Up> |
inline friend void |
swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&); |
|
// A method specific to this implementation. |
const std::allocator<_Tp>& |
_M_getUnderlyingImp() const |
{ return _M_real_alloc; } |
|
private: |
std::allocator<_Tp> _M_real_alloc; |
}; |
|
// _ExtPtr_allocator<void> specialization. |
template<> |
class _ExtPtr_allocator<void> |
{ |
public: |
typedef std::size_t size_type; |
typedef std::ptrdiff_t difference_type; |
typedef void value_type; |
|
// Note the non-standard pointer types |
typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer; |
typedef _Pointer_adapter<_Relative_pointer_impl<const void> > |
const_pointer; |
|
template<typename _Up> |
struct rebind |
{ typedef _ExtPtr_allocator<_Up> other; }; |
|
private: |
std::allocator<void> _M_real_alloc; |
}; |
|
template<typename _Tp> |
inline void |
swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg) |
{ |
std::allocator<_Tp> __tmp( __rarg._M_real_alloc ); |
__rarg._M_real_alloc = __larg._M_real_alloc; |
__larg._M_real_alloc = __tmp; |
} |
|
_GLIBCXX_END_NAMESPACE_VERSION |
} // namespace |
|
#endif /* _EXTPTR_ALLOCATOR_H */ |