epoc32/include/stdapis/boost/detail/allocator_utilities.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 /* Copyright 2003-2005 Joaquín M López Muñoz.
     2  * Distributed under the Boost Software License, Version 1.0.
     3  * (See accompanying file LICENSE_1_0.txt or copy at
     4  * http://www.boost.org/LICENSE_1_0.txt)
     5  *
     6  * See Boost website at http://www.boost.org/
     7  */
     8 
     9 #ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
    10 #define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
    11 
    12 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
    13 #include <boost/detail/workaround.hpp>
    14 #include <boost/mpl/aux_/msvc_never_true.hpp>
    15 #include <boost/mpl/eval_if.hpp>
    16 #include <boost/type_traits/is_same.hpp>
    17 #include <cstddef>
    18 #include <memory>
    19 #include <new>
    20 
    21 namespace boost{
    22 
    23 namespace detail{
    24 
    25 /* Allocator adaption layer. Some stdlibs provide allocators without rebind
    26  * and template ctors. These facilities are simulated with the external
    27  * template class rebind_to and the aid of partial_std_allocator_wrapper.
    28  */
    29 
    30 namespace allocator{
    31 
    32 /* partial_std_allocator_wrapper inherits the functionality of a std
    33  * allocator while providing a templatized ctor.
    34  */
    35 
    36 template<typename Type>
    37 class partial_std_allocator_wrapper:public std::allocator<Type>
    38 {
    39 public:
    40   partial_std_allocator_wrapper(){};
    41 
    42   template<typename Other>
    43   partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
    44 
    45   partial_std_allocator_wrapper(const std::allocator<Type>& x):
    46     std::allocator<Type>(x)
    47   {
    48   };
    49 
    50 #if defined(BOOST_DINKUMWARE_STDLIB)
    51   /* Dinkumware guys didn't provide a means to call allocate() without
    52    * supplying a hint, in disagreement with the standard.
    53    */
    54 
    55   Type* allocate(std::size_t n,const void* hint=0)
    56   {
    57     std::allocator<Type>& a=*this;
    58     return a.allocate(n,hint);
    59   }
    60 #endif
    61 
    62 };
    63 
    64 /* Detects whether a given allocator belongs to a defective stdlib not
    65  * having the required member templates.
    66  * Note that it does not suffice to check the Boost.Config stdlib
    67  * macros, as the user might have passed a custom, compliant allocator.
    68  * The checks also considers partial_std_allocator_wrapper to be
    69  * a standard defective allocator.
    70  */
    71 
    72 #if defined(BOOST_NO_STD_ALLOCATOR)&&\
    73   (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
    74 
    75 template<typename Allocator>
    76 struct is_partial_std_allocator
    77 {
    78   BOOST_STATIC_CONSTANT(bool,
    79     value=
    80       (is_same<
    81         std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
    82         Allocator
    83       >::value)||
    84       (is_same<
    85         partial_std_allocator_wrapper<
    86           BOOST_DEDUCED_TYPENAME Allocator::value_type>,
    87         Allocator
    88       >::value));
    89 };
    90 
    91 #else
    92 
    93 template<typename Allocator>
    94 struct is_partial_std_allocator
    95 {
    96   BOOST_STATIC_CONSTANT(bool,value=false);
    97 };
    98 
    99 #endif
   100 
   101 /* rebind operations for defective std allocators */
   102 
   103 template<typename Allocator,typename Type>
   104 struct partial_std_allocator_rebind_to
   105 {
   106   typedef partial_std_allocator_wrapper<Type> type;
   107 };
   108 
   109 /* rebind operation in all other cases */
   110 
   111 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
   112 /* Workaround for a problem in MSVC with dependent template typedefs
   113  * when doing rebinding of allocators.
   114  * Modeled after <boost/mpl/aux_/msvc_dtw.hpp> (thanks, Aleksey!)
   115  */
   116 
   117 template<typename Allocator>
   118 struct rebinder
   119 {
   120   template<bool> struct fake_allocator:Allocator{};
   121   template<> struct fake_allocator<true>
   122   {
   123     template<typename Type> struct rebind{};
   124   };
   125 
   126   template<typename Type>
   127   struct result:
   128     fake_allocator<mpl::aux::msvc_never_true<Allocator>::value>::
   129       template rebind<Type>
   130   {
   131   };
   132 };
   133 #else
   134 template<typename Allocator>
   135 struct rebinder
   136 {
   137   template<typename Type>
   138   struct result
   139   {
   140       typedef typename Allocator::BOOST_NESTED_TEMPLATE 
   141           rebind<Type>::other other;
   142   };
   143 };
   144 #endif
   145 
   146 template<typename Allocator,typename Type>
   147 struct compliant_allocator_rebind_to
   148 {
   149   typedef typename rebinder<Allocator>::
   150       BOOST_NESTED_TEMPLATE result<Type>::other type;
   151 };
   152 
   153 /* rebind front-end */
   154 
   155 template<typename Allocator,typename Type>
   156 struct rebind_to:
   157   mpl::eval_if_c<
   158     is_partial_std_allocator<Allocator>::value,
   159     partial_std_allocator_rebind_to<Allocator,Type>,
   160     compliant_allocator_rebind_to<Allocator,Type>
   161   >
   162 {
   163 };
   164 
   165 /* allocator-independent versions of construct and destroy */
   166 
   167 template<typename Type>
   168 void construct(void* p,const Type& t)
   169 {
   170   new (p) Type(t);
   171 }
   172 
   173 template<typename Type>
   174 void destroy(const Type* p)
   175 {
   176   p->~Type();
   177 }
   178 
   179 } /* namespace boost::detail::allocator */
   180 
   181 } /* namespace boost::detail */
   182 
   183 } /* namespace boost */
   184 
   185 #endif