Home | History | Annotate | Download | only in bits
      1 // Allocators -*- C++ -*-
      2 
      3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
      4 // 2011 Free Software Foundation, Inc.
      5 //
      6 // This file is part of the GNU ISO C++ Library.  This library is free
      7 // software; you can redistribute it and/or modify it under the
      8 // terms of the GNU General Public License as published by the
      9 // Free Software Foundation; either version 3, or (at your option)
     10 // any later version.
     11 
     12 // This library is distributed in the hope that it will be useful,
     13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 // GNU General Public License for more details.
     16 
     17 // Under Section 7 of GPL version 3, you are granted additional
     18 // permissions described in the GCC Runtime Library Exception, version
     19 // 3.1, as published by the Free Software Foundation.
     20 
     21 // You should have received a copy of the GNU General Public License and
     22 // a copy of the GCC Runtime Library Exception along with this program;
     23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 // <http://www.gnu.org/licenses/>.
     25 
     26 /*
     27  * Copyright (c) 1996-1997
     28  * Silicon Graphics Computer Systems, Inc.
     29  *
     30  * Permission to use, copy, modify, distribute and sell this software
     31  * and its documentation for any purpose is hereby granted without fee,
     32  * provided that the above copyright notice appear in all copies and
     33  * that both that copyright notice and this permission notice appear
     34  * in supporting documentation.  Silicon Graphics makes no
     35  * representations about the suitability of this software for any
     36  * purpose.  It is provided "as is" without express or implied warranty.
     37  */
     38 
     39 /** @file bits/allocator.h
     40  *  This is an internal header file, included by other library headers.
     41  *  Do not attempt to use it directly. @headername{memory}
     42  */
     43 
     44 #ifndef _ALLOCATOR_H
     45 #define _ALLOCATOR_H 1
     46 
     47 // Define the base class to std::allocator.
     48 #include <bits/c++allocator.h>
     49 
     50 #ifdef __GXX_EXPERIMENTAL_CXX0X__
     51 #include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE
     52 #endif
     53 
     54 namespace std _GLIBCXX_VISIBILITY(default)
     55 {
     56 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     57 
     58   /**
     59    * @defgroup allocators Allocators
     60    * @ingroup memory
     61    *
     62    * Classes encapsulating memory operations.
     63    */
     64 
     65   template<typename _Tp>
     66     class allocator;
     67 
     68   /// allocator<void> specialization.
     69   template<>
     70     class allocator<void>
     71     {
     72     public:
     73       typedef size_t      size_type;
     74       typedef ptrdiff_t   difference_type;
     75       typedef void*       pointer;
     76       typedef const void* const_pointer;
     77       typedef void        value_type;
     78 
     79       template<typename _Tp1>
     80         struct rebind
     81         { typedef allocator<_Tp1> other; };
     82     };
     83 
     84   /**
     85    * @brief  The @a standard allocator, as per [20.4].
     86    * @ingroup allocators
     87    *
     88    *  Further details:
     89    *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html
     90    */
     91   template<typename _Tp>
     92     class allocator: public __glibcxx_base_allocator<_Tp>
     93     {
     94    public:
     95       typedef size_t     size_type;
     96       typedef ptrdiff_t  difference_type;
     97       typedef _Tp*       pointer;
     98       typedef const _Tp* const_pointer;
     99       typedef _Tp&       reference;
    100       typedef const _Tp& const_reference;
    101       typedef _Tp        value_type;
    102 
    103       template<typename _Tp1>
    104         struct rebind
    105         { typedef allocator<_Tp1> other; };
    106 
    107       allocator() throw() { }
    108 
    109       allocator(const allocator& __a) throw()
    110       : __glibcxx_base_allocator<_Tp>(__a) { }
    111 
    112       template<typename _Tp1>
    113         allocator(const allocator<_Tp1>&) throw() { }
    114 
    115       ~allocator() throw() { }
    116 
    117       // Inherit everything else.
    118     };
    119 
    120   template<typename _T1, typename _T2>
    121     inline bool
    122     operator==(const allocator<_T1>&, const allocator<_T2>&)
    123     { return true; }
    124 
    125   template<typename _Tp>
    126     inline bool
    127     operator==(const allocator<_Tp>&, const allocator<_Tp>&)
    128     { return true; }
    129 
    130   template<typename _T1, typename _T2>
    131     inline bool
    132     operator!=(const allocator<_T1>&, const allocator<_T2>&)
    133     { return false; }
    134 
    135   template<typename _Tp>
    136     inline bool
    137     operator!=(const allocator<_Tp>&, const allocator<_Tp>&)
    138     { return false; }
    139 
    140   // Inhibit implicit instantiations for required instantiations,
    141   // which are defined via explicit instantiations elsewhere.
    142 #if _GLIBCXX_EXTERN_TEMPLATE
    143   extern template class allocator<char>;
    144   extern template class allocator<wchar_t>;
    145 #endif
    146 
    147   // Undefine.
    148 #undef __glibcxx_base_allocator
    149 
    150   // To implement Option 3 of DR 431.
    151   template<typename _Alloc, bool = __is_empty(_Alloc)>
    152     struct __alloc_swap
    153     { static void _S_do_it(_Alloc&, _Alloc&) { } };
    154 
    155   template<typename _Alloc>
    156     struct __alloc_swap<_Alloc, false>
    157     {
    158       static void
    159       _S_do_it(_Alloc& __one, _Alloc& __two)
    160       {
    161 	// Precondition: swappable allocators.
    162 	if (__one != __two)
    163 	  swap(__one, __two);
    164       }
    165     };
    166 
    167   // Optimize for stateless allocators.
    168   template<typename _Alloc, bool = __is_empty(_Alloc)>
    169     struct __alloc_neq
    170     {
    171       static bool
    172       _S_do_it(const _Alloc&, const _Alloc&)
    173       { return false; }
    174     };
    175 
    176   template<typename _Alloc>
    177     struct __alloc_neq<_Alloc, false>
    178     {
    179       static bool
    180       _S_do_it(const _Alloc& __one, const _Alloc& __two)
    181       { return __one != __two; }
    182     };
    183 
    184 #ifdef __GXX_EXPERIMENTAL_CXX0X__
    185   // A very basic implementation for now.  In general we have to wait for
    186   // the availability of the infrastructure described in N2983:  we should
    187   // try when either T has a move constructor which cannot throw or T is
    188   // CopyContructible.
    189   // NB: This code doesn't properly belong here, we should find a more
    190   // suited place common to std::vector and std::deque.
    191   template<typename _Tp,
    192 	   bool = __has_trivial_copy(typename _Tp::value_type)>
    193     struct __shrink_to_fit
    194     { static void _S_do_it(_Tp&) { } };
    195 
    196   template<typename _Tp>
    197     struct __shrink_to_fit<_Tp, true>
    198     {
    199       static void
    200       _S_do_it(_Tp& __v)
    201       {
    202 	__try
    203 	  { _Tp(__v).swap(__v); }
    204 	__catch(...) { }
    205       }
    206     };
    207 
    208 
    209   /// [allocator.tag]
    210   struct allocator_arg_t { };
    211 
    212   constexpr allocator_arg_t allocator_arg = allocator_arg_t();
    213 
    214 _GLIBCXX_HAS_NESTED_TYPE(allocator_type)
    215 
    216   template<typename _Tp, typename _Alloc,
    217 	   bool = __has_allocator_type<_Tp>::value>
    218     struct __uses_allocator_helper
    219     : public false_type { };
    220 
    221   template<typename _Tp, typename _Alloc>
    222     struct __uses_allocator_helper<_Tp, _Alloc, true>
    223     : public integral_constant<bool, is_convertible<_Alloc,
    224 				     typename _Tp::allocator_type>::value>
    225     { };
    226 
    227   /// [allocator.uses.trait]
    228   template<typename _Tp, typename _Alloc>
    229     struct uses_allocator
    230     : public integral_constant<bool,
    231 			       __uses_allocator_helper<_Tp, _Alloc>::value>
    232     { };
    233 
    234 #endif
    235 
    236 _GLIBCXX_END_NAMESPACE_VERSION
    237 } // namespace std
    238 
    239 #endif
    240