1/* Copyright 2003-2013 Joaquin M Lopez Munoz.
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/eval_if.hpp>
15#include <boost/type_traits/is_same.hpp>
16#include <cstddef>
17#include <memory>
18#include <new>
19
20namespace boost{
21
22namespace detail{
23
24/* Allocator adaption layer. Some stdlibs provide allocators without rebind
25 * and template ctors. These facilities are simulated with the external
26 * template class rebind_to and the aid of partial_std_allocator_wrapper.
27 */
28
29namespace allocator{
30
31/* partial_std_allocator_wrapper inherits the functionality of a std
32 * allocator while providing a templatized ctor and other bits missing
33 * in some stdlib implementation or another.
34 */
35
36template<typename Type>
37class partial_std_allocator_wrapper:public std::allocator<Type>
38{
39public:
40 /* Oddly enough, STLport does not define std::allocator<void>::value_type
41 * when configured to work without partial template specialization.
42 * No harm in supplying the definition here unconditionally.
43 */
44
45 typedef Type value_type;
46
47 partial_std_allocator_wrapper(){};
48
49 template<typename Other>
50 partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
51
52 partial_std_allocator_wrapper(const std::allocator<Type>& x):
53 std::allocator<Type>(x)
54 {
55 };
56
57#if defined(BOOST_DINKUMWARE_STDLIB)
58 /* Dinkumware guys didn't provide a means to call allocate() without
59 * supplying a hint, in disagreement with the standard.
60 */
61
62 Type* allocate(std::size_t n,const void* hint=0)
63 {
64 std::allocator<Type>& a=*this;
65 return a.allocate(n,hint);
66 }
67#endif
68
69};
70
71/* Detects whether a given allocator belongs to a defective stdlib not
72 * having the required member templates.
73 * Note that it does not suffice to check the Boost.Config stdlib
74 * macros, as the user might have passed a custom, compliant allocator.
75 * The checks also considers partial_std_allocator_wrapper to be
76 * a standard defective allocator.
77 */
78
79#if defined(BOOST_NO_STD_ALLOCATOR)&&\
80 (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
81
82template<typename Allocator>
83struct is_partial_std_allocator
84{
85 BOOST_STATIC_CONSTANT(bool,
86 value=
87 (is_same<
88 std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
89 Allocator
90 >::value)||
91 (is_same<
92 partial_std_allocator_wrapper<
93 BOOST_DEDUCED_TYPENAME Allocator::value_type>,
94 Allocator
95 >::value));
96};
97
98#else
99
100template<typename Allocator>
101struct is_partial_std_allocator
102{
103 BOOST_STATIC_CONSTANT(bool,value=false);
104};
105
106#endif
107
108/* rebind operations for defective std allocators */
109
110template<typename Allocator,typename Type>
111struct partial_std_allocator_rebind_to
112{
113 typedef partial_std_allocator_wrapper<Type> type;
114};
115
116/* rebind operation in all other cases */
117
118template<typename Allocator>
119struct rebinder
120{
121 template<typename Type>
122 struct result
123 {
124 typedef typename Allocator::BOOST_NESTED_TEMPLATE
125 rebind<Type>::other other;
126 };
127};
128
129template<typename Allocator,typename Type>
130struct compliant_allocator_rebind_to
131{
132 typedef typename rebinder<Allocator>::
133 BOOST_NESTED_TEMPLATE result<Type>::other type;
134};
135
136/* rebind front-end */
137
138template<typename Allocator,typename Type>
139struct rebind_to:
140 mpl::eval_if_c<
141 is_partial_std_allocator<Allocator>::value,
142 partial_std_allocator_rebind_to<Allocator,Type>,
143 compliant_allocator_rebind_to<Allocator,Type>
144 >
145{
146};
147
148/* allocator-independent versions of construct and destroy */
149
150template<typename Type>
151void construct(void* p,const Type& t)
152{
153 new (p) Type(t);
154}
155
156#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
157/* MSVC++ issues spurious warnings about unreferencend formal parameters
158 * in destroy<Type> when Type is a class with trivial dtor.
159 */
160
161#pragma warning(push)
162#pragma warning(disable:4100)
163#endif
164
165template<typename Type>
166void destroy(const Type* p)
167{
168
169#if BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590))
170 const_cast<Type*>(p)->~Type();
171#else
172 p->~Type();
173#endif
174
175}
176
177#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
178#pragma warning(pop)
179#endif
180
181} /* namespace boost::detail::allocator */
182
183} /* namespace boost::detail */
184
185} /* namespace boost */
186
187#endif
188

source code of boost/boost/detail/allocator_utilities.hpp