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