# extptr_allocator.h

Go to the documentation of this file.

    00001 // <extptr_allocator.h> -*- C++ -*-
    00002
    00003 // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
    00004 //
    00005 // This file is part of the GNU ISO C++ Library.  This library is free
    00006 // software; you can redistribute it and/or modify it under the
    00007 // terms of the GNU General Public License as published by the
    00008 // Free Software Foundation; either version 3, or (at your option)
    00009 // any later version.
    00010
    00011 // This library is distributed in the hope that it will be useful,
    00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00014 // GNU General Public License for more details.
    00015
    00016 // Under Section 7 of GPL version 3, you are granted additional
    00017 // permissions described in the GCC Runtime Library Exception, version
    00018 // 3.1, as published by the Free Software Foundation.
    00019
    00020 // You should have received a copy of the GNU General Public License and
    00021 // a copy of the GCC Runtime Library Exception along with this program;
    00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00023 // <http://www.gnu.org/licenses/>.
    00024
    00025 /**
    00026  * @file ext/extptr_allocator.h
    00027  * @author Bob Walters
    00028  *
    00029  * An example allocator which uses an alternative pointer type from
    00030  * bits/pointer.h.  Supports test cases which confirm container support
    00031  * for alternative pointers.
    00032  */
    00033
    00034 #ifndef _EXTPTR_ALLOCATOR_H
    00035 #define _EXTPTR_ALLOCATOR_H 1
    00036
    00037 #include <memory>
    00038 #include <limits>
    00039 #include <ext/pointer.h>
    00040
    00041 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
    00042
    00043   /**
    00044    * @brief An example allocator which uses a non-standard pointer type.
    00045    * @ingroup allocators
    00046    *
    00047    * This allocator specifies that containers use a 'relative pointer' as it's
    00048    * pointer type.  (See ext/pointer.h)  Memory allocation in this example
    00049    * is still performed using std::allocator.
    00050    */
    00051   template<typename _Tp>
    00052     class _ExtPtr_allocator
    00053     {
    00054     public:
    00055       typedef std::size_t     size_type;
    00056       typedef std::ptrdiff_t  difference_type;
    00057
    00058       // Note the non-standard pointer types.
    00059       typedef _Pointer_adapter<_Relative_pointer_impl<_Tp> >       pointer;
    00060       typedef _Pointer_adapter<_Relative_pointer_impl<const _Tp> >
    00061                                                              const_pointer;
    00062
    00063       typedef _Tp&       reference;
    00064       typedef const _Tp& const_reference;
    00065       typedef _Tp        value_type;
    00066
    00067       template<typename _Up>
    00068         struct rebind
    00069         { typedef _ExtPtr_allocator<_Up> other; };
    00070
    00071       _ExtPtr_allocator() throw()
    00072       : _M_real_alloc() { }
    00073
    00074       _ExtPtr_allocator(const _ExtPtr_allocator &__rarg) throw()
    00075       : _M_real_alloc(__rarg._M_real_alloc) { }
    00076
    00077       template<typename _Up>
    00078         _ExtPtr_allocator(const _ExtPtr_allocator<_Up>& __rarg) throw()
    00079         : _M_real_alloc(__rarg._M_getUnderlyingImp()) { }
    00080
    00081       ~_ExtPtr_allocator() throw()
    00082       { }
    00083
    00084       pointer address(reference __x) const
    00085       { return &__x; }
    00086
    00087       const_pointer address(const_reference __x) const
    00088       { return &__x; }
    00089
    00090       pointer allocate(size_type __n, void* __hint = 0)
    00091       { return _M_real_alloc.allocate(__n,__hint); }
    00092
    00093       void deallocate(pointer __p, size_type __n)
    00094       { _M_real_alloc.deallocate(__p.get(), __n); }
    00095
    00096       size_type max_size() const throw()
    00097       { return std::numeric_limits<size_type>::max() / sizeof(_Tp); }
    00098
    00099       void construct(pointer __p, const _Tp& __val)
    00100       { ::new(__p.get()) _Tp(__val); }
    00101
    00102 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    00103       template<typename... _Args>
    00104         void
    00105         construct(pointer __p, _Args&&... __args)
    00106         { ::new(__p.get()) _Tp(std::forward<_Args>(__args)...); }
    00107 #endif
    00108
    00109       void destroy(pointer __p)
    00110       { __p->~_Tp(); }
    00111
    00112       template<typename _Up>
    00113         inline bool
    00114         operator==(const _ExtPtr_allocator<_Up>& __rarg)
    00115         { return _M_real_alloc == __rarg._M_getUnderlyingImp(); }
    00116
    00117       inline bool
    00118       operator==(const _ExtPtr_allocator& __rarg)
    00119       { return _M_real_alloc == __rarg._M_real_alloc; }
    00120
    00121       template<typename _Up>
    00122         inline bool
    00123         operator!=(const _ExtPtr_allocator<_Up>& __rarg)
    00124         { return _M_real_alloc != __rarg._M_getUnderlyingImp(); }
    00125
    00126       inline bool
    00127       operator!=(const _ExtPtr_allocator& __rarg)
    00128       { return _M_real_alloc != __rarg._M_real_alloc; }
    00129
    00130       template<typename _Up>
    00131         inline friend void
    00132         swap(_ExtPtr_allocator<_Up>&, _ExtPtr_allocator<_Up>&);
    00133
    00134       // A method specific to this implementation.
    00135       const std::allocator<_Tp>&
    00136       _M_getUnderlyingImp() const
    00137       { return _M_real_alloc; }
    00138
    00139     private:
    00140       std::allocator<_Tp>  _M_real_alloc;
    00141     };
    00142
    00143   // _ExtPtr_allocator<void> specialization.
    00144   template<>
    00145     class _ExtPtr_allocator<void>
    00146     {
    00147     public:
    00148       typedef std::size_t      size_type;
    00149       typedef std::ptrdiff_t   difference_type;
    00150       typedef void             value_type;
    00151
    00152       // Note the non-standard pointer types
    00153       typedef _Pointer_adapter<_Relative_pointer_impl<void> >       pointer;
    00154       typedef _Pointer_adapter<_Relative_pointer_impl<const void> >
    00155                                                               const_pointer;
    00156
    00157       template<typename _Up>
    00158         struct rebind
    00159         { typedef _ExtPtr_allocator<_Up> other; };
    00160
    00161     private:
    00162       std::allocator<void>  _M_real_alloc;
    00163     };
    00164
    00165   template<typename _Tp>
    00166     inline void
    00167     swap(_ExtPtr_allocator<_Tp>& __larg, _ExtPtr_allocator<_Tp>& __rarg)
    00168     {
    00169       std::allocator<_Tp> __tmp( __rarg._M_real_alloc );
    00170       __rarg._M_real_alloc = __larg._M_real_alloc;
    00171       __larg._M_real_alloc = __tmp;
    00172     }
    00173
    00174 _GLIBCXX_END_NAMESPACE
    00175
    00176 #endif /* _EXTPTR_ALLOCATOR_H */