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