comparison DEPENDENCIES/generic/include/boost/detail/allocator_utilities.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 /* Copyright 2003-2009 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/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 and other bits missing
34 * in some stdlib implementation or another.
35 */
36
37 template<typename Type>
38 class partial_std_allocator_wrapper:public std::allocator<Type>
39 {
40 public:
41 /* Oddly enough, STLport does not define std::allocator<void>::value_type
42 * when configured to work without partial template specialization.
43 * No harm in supplying the definition here unconditionally.
44 */
45
46 typedef Type value_type;
47
48 partial_std_allocator_wrapper(){};
49
50 template<typename Other>
51 partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
52
53 partial_std_allocator_wrapper(const std::allocator<Type>& x):
54 std::allocator<Type>(x)
55 {
56 };
57
58 #if defined(BOOST_DINKUMWARE_STDLIB)
59 /* Dinkumware guys didn't provide a means to call allocate() without
60 * supplying a hint, in disagreement with the standard.
61 */
62
63 Type* allocate(std::size_t n,const void* hint=0)
64 {
65 std::allocator<Type>& a=*this;
66 return a.allocate(n,hint);
67 }
68 #endif
69
70 };
71
72 /* Detects whether a given allocator belongs to a defective stdlib not
73 * having the required member templates.
74 * Note that it does not suffice to check the Boost.Config stdlib
75 * macros, as the user might have passed a custom, compliant allocator.
76 * The checks also considers partial_std_allocator_wrapper to be
77 * a standard defective allocator.
78 */
79
80 #if defined(BOOST_NO_STD_ALLOCATOR)&&\
81 (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
82
83 template<typename Allocator>
84 struct is_partial_std_allocator
85 {
86 BOOST_STATIC_CONSTANT(bool,
87 value=
88 (is_same<
89 std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
90 Allocator
91 >::value)||
92 (is_same<
93 partial_std_allocator_wrapper<
94 BOOST_DEDUCED_TYPENAME Allocator::value_type>,
95 Allocator
96 >::value));
97 };
98
99 #else
100
101 template<typename Allocator>
102 struct is_partial_std_allocator
103 {
104 BOOST_STATIC_CONSTANT(bool,value=false);
105 };
106
107 #endif
108
109 /* rebind operations for defective std allocators */
110
111 template<typename Allocator,typename Type>
112 struct partial_std_allocator_rebind_to
113 {
114 typedef partial_std_allocator_wrapper<Type> type;
115 };
116
117 /* rebind operation in all other cases */
118
119 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
120 /* Workaround for a problem in MSVC with dependent template typedefs
121 * when doing rebinding of allocators.
122 * Modeled after <boost/mpl/aux_/msvc_dtw.hpp> (thanks, Aleksey!)
123 */
124
125 template<typename Allocator>
126 struct rebinder
127 {
128 template<bool> struct fake_allocator:Allocator{};
129 template<> struct fake_allocator<true>
130 {
131 template<typename Type> struct rebind{};
132 };
133
134 template<typename Type>
135 struct result:
136 fake_allocator<mpl::aux::msvc_never_true<Allocator>::value>::
137 template rebind<Type>
138 {
139 };
140 };
141 #else
142 template<typename Allocator>
143 struct rebinder
144 {
145 template<typename Type>
146 struct result
147 {
148 typedef typename Allocator::BOOST_NESTED_TEMPLATE
149 rebind<Type>::other other;
150 };
151 };
152 #endif
153
154 template<typename Allocator,typename Type>
155 struct compliant_allocator_rebind_to
156 {
157 typedef typename rebinder<Allocator>::
158 BOOST_NESTED_TEMPLATE result<Type>::other type;
159 };
160
161 /* rebind front-end */
162
163 template<typename Allocator,typename Type>
164 struct rebind_to:
165 mpl::eval_if_c<
166 is_partial_std_allocator<Allocator>::value,
167 partial_std_allocator_rebind_to<Allocator,Type>,
168 compliant_allocator_rebind_to<Allocator,Type>
169 >
170 {
171 };
172
173 /* allocator-independent versions of construct and destroy */
174
175 template<typename Type>
176 void construct(void* p,const Type& t)
177 {
178 new (p) Type(t);
179 }
180
181 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
182 /* MSVC++ issues spurious warnings about unreferencend formal parameters
183 * in destroy<Type> when Type is a class with trivial dtor.
184 */
185
186 #pragma warning(push)
187 #pragma warning(disable:4100)
188 #endif
189
190 template<typename Type>
191 void destroy(const Type* p)
192 {
193
194 #if BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590))
195 const_cast<Type*>(p)->~Type();
196 #else
197 p->~Type();
198 #endif
199
200 }
201
202 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
203 #pragma warning(pop)
204 #endif
205
206 } /* namespace boost::detail::allocator */
207
208 } /* namespace boost::detail */
209
210 } /* namespace boost */
211
212 #endif