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)
6 * See Boost website at http://www.boost.org/
9 #ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
10 #define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
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>
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.
32 /* partial_std_allocator_wrapper inherits the functionality of a std
33 * allocator while providing a templatized ctor.
36 template<typename Type>
37 class partial_std_allocator_wrapper:public std::allocator<Type>
40 partial_std_allocator_wrapper(){};
42 template<typename Other>
43 partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
45 partial_std_allocator_wrapper(const std::allocator<Type>& x):
46 std::allocator<Type>(x)
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.
55 Type* allocate(std::size_t n,const void* hint=0)
57 std::allocator<Type>& a=*this;
58 return a.allocate(n,hint);
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.
72 #if defined(BOOST_NO_STD_ALLOCATOR)&&\
73 (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
75 template<typename Allocator>
76 struct is_partial_std_allocator
78 BOOST_STATIC_CONSTANT(bool,
81 std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
85 partial_std_allocator_wrapper<
86 BOOST_DEDUCED_TYPENAME Allocator::value_type>,
93 template<typename Allocator>
94 struct is_partial_std_allocator
96 BOOST_STATIC_CONSTANT(bool,value=false);
101 /* rebind operations for defective std allocators */
103 template<typename Allocator,typename Type>
104 struct partial_std_allocator_rebind_to
106 typedef partial_std_allocator_wrapper<Type> type;
109 /* rebind operation in all other cases */
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!)
117 template<typename Allocator>
120 template<bool> struct fake_allocator:Allocator{};
121 template<> struct fake_allocator<true>
123 template<typename Type> struct rebind{};
126 template<typename Type>
128 fake_allocator<mpl::aux::msvc_never_true<Allocator>::value>::
129 template rebind<Type>
134 template<typename Allocator>
137 template<typename Type>
140 typedef typename Allocator::BOOST_NESTED_TEMPLATE
141 rebind<Type>::other other;
146 template<typename Allocator,typename Type>
147 struct compliant_allocator_rebind_to
149 typedef typename rebinder<Allocator>::
150 BOOST_NESTED_TEMPLATE result<Type>::other type;
153 /* rebind front-end */
155 template<typename Allocator,typename Type>
158 is_partial_std_allocator<Allocator>::value,
159 partial_std_allocator_rebind_to<Allocator,Type>,
160 compliant_allocator_rebind_to<Allocator,Type>
165 /* allocator-independent versions of construct and destroy */
167 template<typename Type>
168 void construct(void* p,const Type& t)
173 template<typename Type>
174 void destroy(const Type* p)
179 } /* namespace boost::detail::allocator */
181 } /* namespace boost::detail */
183 } /* namespace boost */