allocator_utilities.hpp
Go to the documentation of this file.
00001 /* Copyright 2003-2008 Joaquin M Lopez Munoz.
00002  * Distributed under the Boost Software License, Version 1.0.
00003  * (See accompanying file LICENSE_1_0.txt or copy at
00004  * http://www.boost.org/LICENSE_1_0.txt)
00005  *
00006  * See Boost website at http://www.boost.org/
00007  */
00008 
00009 #ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
00010 #define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
00011 
00012 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
00013 #include <boost/detail/workaround.hpp>
00014 #include <boost/mpl/aux_/msvc_never_true.hpp>
00015 #include <boost/mpl/eval_if.hpp>
00016 #include <boost/type_traits/is_same.hpp>
00017 #include <cstddef>
00018 #include <memory>
00019 #include <new>
00020 
00021 namespace boost{
00022 
00023 namespace detail{
00024 
00025 /* Allocator adaption layer. Some stdlibs provide allocators without rebind
00026  * and template ctors. These facilities are simulated with the external
00027  * template class rebind_to and the aid of partial_std_allocator_wrapper.
00028  */
00029 
00030 namespace allocator{
00031 
00032 /* partial_std_allocator_wrapper inherits the functionality of a std
00033  * allocator while providing a templatized ctor and other bits missing
00034  * in some stdlib implementation or another.
00035  */
00036 
00037 template<typename Type>
00038 class partial_std_allocator_wrapper:public std::allocator<Type>
00039 {
00040 public:
00041   /* Oddly enough, STLport does not define std::allocator<void>::value_type
00042    * when configured to work without partial template specialization.
00043    * No harm in supplying the definition here unconditionally.
00044    */
00045 
00046   typedef Type value_type;
00047 
00048   partial_std_allocator_wrapper(){};
00049 
00050   template<typename Other>
00051   partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
00052 
00053   partial_std_allocator_wrapper(const std::allocator<Type>& x):
00054     std::allocator<Type>(x)
00055   {
00056   };
00057 
00058 #if defined(BOOST_DINKUMWARE_STDLIB)
00059   /* Dinkumware guys didn't provide a means to call allocate() without
00060    * supplying a hint, in disagreement with the standard.
00061    */
00062 
00063   Type* allocate(std::size_t n,const void* hint=0)
00064   {
00065     std::allocator<Type>& a=*this;
00066     return a.allocate(n,hint);
00067   }
00068 #endif
00069 
00070 };
00071 
00072 /* Detects whether a given allocator belongs to a defective stdlib not
00073  * having the required member templates.
00074  * Note that it does not suffice to check the Boost.Config stdlib
00075  * macros, as the user might have passed a custom, compliant allocator.
00076  * The checks also considers partial_std_allocator_wrapper to be
00077  * a standard defective allocator.
00078  */
00079 
00080 #if defined(BOOST_NO_STD_ALLOCATOR)&&\
00081   (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
00082 
00083 template<typename Allocator>
00084 struct is_partial_std_allocator
00085 {
00086   BOOST_STATIC_CONSTANT(bool,
00087     value=
00088       (is_same<
00089         std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
00090         Allocator
00091       >::value)||
00092       (is_same<
00093         partial_std_allocator_wrapper<
00094           BOOST_DEDUCED_TYPENAME Allocator::value_type>,
00095         Allocator
00096       >::value));
00097 };
00098 
00099 #else
00100 
00101 template<typename Allocator>
00102 struct is_partial_std_allocator
00103 {
00104   BOOST_STATIC_CONSTANT(bool,value=false);
00105 };
00106 
00107 #endif
00108 
00109 /* rebind operations for defective std allocators */
00110 
00111 template<typename Allocator,typename Type>
00112 struct partial_std_allocator_rebind_to
00113 {
00114   typedef partial_std_allocator_wrapper<Type> type;
00115 };
00116 
00117 /* rebind operation in all other cases */
00118 
00119 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
00120 /* Workaround for a problem in MSVC with dependent template typedefs
00121  * when doing rebinding of allocators.
00122  * Modeled after <boost/mpl/aux_/msvc_dtw.hpp> (thanks, Aleksey!)
00123  */
00124 
00125 template<typename Allocator>
00126 struct rebinder
00127 {
00128   template<bool> struct fake_allocator:Allocator{};
00129   template<> struct fake_allocator<true>
00130   {
00131     template<typename Type> struct rebind{};
00132   };
00133 
00134   template<typename Type>
00135   struct result:
00136     fake_allocator<mpl::aux::msvc_never_true<Allocator>::value>::
00137       template rebind<Type>
00138   {
00139   };
00140 };
00141 #else
00142 template<typename Allocator>
00143 struct rebinder
00144 {
00145   template<typename Type>
00146   struct result
00147   {
00148       typedef typename Allocator::BOOST_NESTED_TEMPLATE 
00149           rebind<Type>::other other;
00150   };
00151 };
00152 #endif
00153 
00154 template<typename Allocator,typename Type>
00155 struct compliant_allocator_rebind_to
00156 {
00157   typedef typename rebinder<Allocator>::
00158       BOOST_NESTED_TEMPLATE result<Type>::other type;
00159 };
00160 
00161 /* rebind front-end */
00162 
00163 template<typename Allocator,typename Type>
00164 struct rebind_to:
00165   mpl::eval_if_c<
00166     is_partial_std_allocator<Allocator>::value,
00167     partial_std_allocator_rebind_to<Allocator,Type>,
00168     compliant_allocator_rebind_to<Allocator,Type>
00169   >
00170 {
00171 };
00172 
00173 /* allocator-independent versions of construct and destroy */
00174 
00175 template<typename Type>
00176 void construct(void* p,const Type& t)
00177 {
00178   new (p) Type(t);
00179 }
00180 
00181 template<typename Type>
00182 void destroy(const Type* p)
00183 {
00184   p->~Type();
00185 }
00186 
00187 } /* namespace boost::detail::allocator */
00188 
00189 } /* namespace boost::detail */
00190 
00191 } /* namespace boost */
00192 
00193 #endif


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:28