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 */

Generated on Tue Apr 21 13:13:26 2009 for libstdc++ by  doxygen 1.5.8