source: NonGTP/Boost/boost/detail/allocator_utilities.hpp @ 857

Revision 857, 4.5 KB checked in by igarcia, 18 years ago (diff)
Line 
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
21namespace boost{
22
23namespace 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
30namespace allocator{
31
32/* partial_std_allocator_wrapper inherits the functionality of a std
33 * allocator while providing a templatized ctor.
34 */
35
36template<typename Type>
37class partial_std_allocator_wrapper:public std::allocator<Type>
38{
39public:
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
75template<typename Allocator>
76struct 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
93template<typename Allocator>
94struct 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
103template<typename Allocator,typename Type>
104struct 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
117template<typename Allocator>
118struct 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
134template<typename Allocator>
135struct 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
146template<typename Allocator,typename Type>
147struct 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
155template<typename Allocator,typename Type>
156struct 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
167template<typename Type>
168void construct(void* p,const Type& t)
169{
170  new (p) Type(t);
171}
172
173template<typename Type>
174void 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
Note: See TracBrowser for help on using the repository browser.