1*e4b17023SJohn Marino // <extptr_allocator.h> -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino // 5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 7*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 9*e4b17023SJohn Marino // any later version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino // GNU General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino /** 26*e4b17023SJohn Marino * @file ext/extptr_allocator.h 27*e4b17023SJohn Marino * This file is a GNU extension to the Standard C++ Library. 28*e4b17023SJohn Marino * 29*e4b17023SJohn Marino * @author Bob Walters 30*e4b17023SJohn Marino * 31*e4b17023SJohn Marino * An example allocator which uses an alternative pointer type from 32*e4b17023SJohn Marino * bits/pointer.h. Supports test cases which confirm container support 33*e4b17023SJohn Marino * for alternative pointers. 34*e4b17023SJohn Marino */ 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino #ifndef _EXTPTR_ALLOCATOR_H 37*e4b17023SJohn Marino #define _EXTPTR_ALLOCATOR_H 1 38*e4b17023SJohn Marino 39*e4b17023SJohn Marino #include <memory> 40*e4b17023SJohn Marino #include <ext/numeric_traits.h> 41*e4b17023SJohn Marino #include <ext/pointer.h> 42*e4b17023SJohn Marino 43*e4b17023SJohn Marino namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 44*e4b17023SJohn Marino { 45*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 46*e4b17023SJohn Marino 47*e4b17023SJohn Marino /** 48*e4b17023SJohn Marino * @brief An example allocator which uses a non-standard pointer type. 49*e4b17023SJohn Marino * @ingroup allocators 50*e4b17023SJohn Marino * 51*e4b17023SJohn Marino * This allocator specifies that containers use a 'relative pointer' as it's 52*e4b17023SJohn Marino * pointer type. (See ext/pointer.h) Memory allocation in this example 53*e4b17023SJohn Marino * is still performed using std::allocator. 54*e4b17023SJohn Marino */ 55*e4b17023SJohn Marino template<typename _Tp> 56*e4b17023SJohn Marino class _ExtPtr_allocator 57*e4b17023SJohn Marino { 58*e4b17023SJohn Marino public: 59*e4b17023SJohn Marino typedef std::size_t size_type; 60*e4b17023SJohn Marino typedef std::ptrdiff_t difference_type; 61*e4b17023SJohn Marino 62*e4b17023SJohn Marino // Note the non-standard pointer types. 63*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> > pointer; 64*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> > 65*e4b17023SJohn Marino const_pointer; 66*e4b17023SJohn Marino 67*e4b17023SJohn Marino typedef _Tp& reference; 68*e4b17023SJohn Marino typedef const _Tp& const_reference; 69*e4b17023SJohn Marino typedef _Tp value_type; 70*e4b17023SJohn Marino 71*e4b17023SJohn Marino template<typename _Up> 72*e4b17023SJohn Marino struct rebind 73*e4b17023SJohn Marino { typedef _ExtPtr_allocator<_Up> other; }; 74*e4b17023SJohn Marino 75*e4b17023SJohn Marino _ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT 76*e4b17023SJohn Marino : _M_real_alloc() { } 77*e4b17023SJohn Marino 78*e4b17023SJohn Marino _ExtPtr_allocator(const _ExtPtr_allocator& __rarg) _GLIBCXX_USE_NOEXCEPT 79*e4b17023SJohn Marino : _M_real_alloc(__rarg._M_real_alloc) { } 80*e4b17023SJohn Marino 81*e4b17023SJohn Marino template<typename _Up> 82*e4b17023SJohn Marino _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) 83*e4b17023SJohn Marino _GLIBCXX_USE_NOEXCEPT 84*e4b17023SJohn Marino : _M_real_alloc(__rarg._M_getUnderlyingImp()) { } 85*e4b17023SJohn Marino 86*e4b17023SJohn Marino ~_ExtPtr_allocator() _GLIBCXX_USE_NOEXCEPT 87*e4b17023SJohn Marino { } 88*e4b17023SJohn Marino 89*e4b17023SJohn Marino pointer address(reference __x) const _GLIBCXX_NOEXCEPT 90*e4b17023SJohn Marino { return std::__addressof(__x); } 91*e4b17023SJohn Marino 92*e4b17023SJohn Marino const_pointer address(const_reference __x) const _GLIBCXX_NOEXCEPT 93*e4b17023SJohn Marino { return std::__addressof(__x); } 94*e4b17023SJohn Marino 95*e4b17023SJohn Marino pointer allocate(size_type __n, void* __hint = 0) 96*e4b17023SJohn Marino { return _M_real_alloc.allocate(__n,__hint); } 97*e4b17023SJohn Marino 98*e4b17023SJohn Marino void deallocate(pointer __p, size_type __n) 99*e4b17023SJohn Marino { _M_real_alloc.deallocate(__p.get(), __n); } 100*e4b17023SJohn Marino 101*e4b17023SJohn Marino size_type max_size() const _GLIBCXX_USE_NOEXCEPT 102*e4b17023SJohn Marino { return __numeric_traits<size_type>::__max / sizeof(_Tp); } 103*e4b17023SJohn Marino 104*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 105*e4b17023SJohn Marino template<typename _Up, typename... _Args> 106*e4b17023SJohn Marino void 107*e4b17023SJohn Marino construct(_Up* __p, _Args&&... __args) 108*e4b17023SJohn Marino { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino template<typename... _Args> 111*e4b17023SJohn Marino void 112*e4b17023SJohn Marino construct(pointer __p, _Args&&... __args) 113*e4b17023SJohn Marino { construct(__p.get(), std::forward<_Args>(__args)...); } 114*e4b17023SJohn Marino 115*e4b17023SJohn Marino template<typename _Up> 116*e4b17023SJohn Marino void 117*e4b17023SJohn Marino destroy(_Up* __p) 118*e4b17023SJohn Marino { __p->~_Up(); } 119*e4b17023SJohn Marino 120*e4b17023SJohn Marino void destroy(pointer __p) 121*e4b17023SJohn Marino { destroy(__p.get()); } 122*e4b17023SJohn Marino 123*e4b17023SJohn Marino #else 124*e4b17023SJohn Marino 125*e4b17023SJohn Marino void construct(pointer __p, const _Tp& __val) 126*e4b17023SJohn Marino { ::new(__p.get()) _Tp(__val); } 127*e4b17023SJohn Marino 128*e4b17023SJohn Marino void destroy(pointer __p) 129*e4b17023SJohn Marino { __p->~_Tp(); } 130*e4b17023SJohn Marino #endif 131*e4b17023SJohn Marino 132*e4b17023SJohn Marino template<typename _Up> 133*e4b17023SJohn Marino inline bool 134*e4b17023SJohn Marino operator==(const _ExtPtr_allocator<_Up>& __rarg) 135*e4b17023SJohn Marino { return _M_real_alloc == __rarg._M_getUnderlyingImp(); } 136*e4b17023SJohn Marino 137*e4b17023SJohn Marino inline bool 138*e4b17023SJohn Marino operator==(const _ExtPtr_allocator& __rarg) 139*e4b17023SJohn Marino { return _M_real_alloc == __rarg._M_real_alloc; } 140*e4b17023SJohn Marino 141*e4b17023SJohn Marino template<typename _Up> 142*e4b17023SJohn Marino inline bool 143*e4b17023SJohn Marino operator!=(const _ExtPtr_allocator<_Up>& __rarg) 144*e4b17023SJohn Marino { return _M_real_alloc != __rarg._M_getUnderlyingImp(); } 145*e4b17023SJohn Marino 146*e4b17023SJohn Marino inline bool 147*e4b17023SJohn Marino operator!=(const _ExtPtr_allocator& __rarg) 148*e4b17023SJohn Marino { return _M_real_alloc != __rarg._M_real_alloc; } 149*e4b17023SJohn Marino 150*e4b17023SJohn Marino template<typename _Up> 151*e4b17023SJohn Marino inline friend void 152*e4b17023SJohn Marino swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&); 153*e4b17023SJohn Marino 154*e4b17023SJohn Marino // A method specific to this implementation. 155*e4b17023SJohn Marino const std::allocator<_Tp>& 156*e4b17023SJohn Marino _M_getUnderlyingImp() const 157*e4b17023SJohn Marino { return _M_real_alloc; } 158*e4b17023SJohn Marino 159*e4b17023SJohn Marino private: 160*e4b17023SJohn Marino std::allocator<_Tp> _M_real_alloc; 161*e4b17023SJohn Marino }; 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino // _ExtPtr_allocator<void> specialization. 164*e4b17023SJohn Marino template<> 165*e4b17023SJohn Marino class _ExtPtr_allocator<void> 166*e4b17023SJohn Marino { 167*e4b17023SJohn Marino public: 168*e4b17023SJohn Marino typedef std::size_t size_type; 169*e4b17023SJohn Marino typedef std::ptrdiff_t difference_type; 170*e4b17023SJohn Marino typedef void value_type; 171*e4b17023SJohn Marino 172*e4b17023SJohn Marino // Note the non-standard pointer types 173*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<void> > pointer; 174*e4b17023SJohn Marino typedef _Pointer_adapter<_Relative_pointer_impl<const void> > 175*e4b17023SJohn Marino const_pointer; 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino template<typename _Up> 178*e4b17023SJohn Marino struct rebind 179*e4b17023SJohn Marino { typedef _ExtPtr_allocator<_Up> other; }; 180*e4b17023SJohn Marino 181*e4b17023SJohn Marino private: 182*e4b17023SJohn Marino std::allocator<void> _M_real_alloc; 183*e4b17023SJohn Marino }; 184*e4b17023SJohn Marino 185*e4b17023SJohn Marino template<typename _Tp> 186*e4b17023SJohn Marino inline void 187*e4b17023SJohn Marino swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg) 188*e4b17023SJohn Marino { 189*e4b17023SJohn Marino std::allocator<_Tp> __tmp( __rarg._M_real_alloc ); 190*e4b17023SJohn Marino __rarg._M_real_alloc = __larg._M_real_alloc; 191*e4b17023SJohn Marino __larg._M_real_alloc = __tmp; 192*e4b17023SJohn Marino } 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 195*e4b17023SJohn Marino } // namespace 196*e4b17023SJohn Marino 197*e4b17023SJohn Marino #endif /* _EXTPTR_ALLOCATOR_H */ 198