allocator_utilities.hpp

Go to the documentation of this file.
00001 /* Copyright 2003-2005 Joaquín M López Muñoz.
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 <sysc/packages/boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
00013 #include <sysc/packages/boost/detail/workaround.hpp>
00014 #include <sysc/packages/boost/mpl/aux_/msvc_never_true.hpp>
00015 #include <sysc/packages/boost/mpl/eval_if.hpp>
00016 #include <sysc/packages/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.
00034  */
00035 
00036 template<typename Type>
00037 class partial_std_allocator_wrapper:public std::allocator<Type>
00038 {
00039 public:
00040   partial_std_allocator_wrapper(){};
00041 
00042   template<typename Other>
00043   partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
00044 
00045   partial_std_allocator_wrapper(const std::allocator<Type>& x):
00046     std::allocator<Type>(x)
00047   {
00048   };
00049 
00050 #if defined(BOOST_DINKUMWARE_STDLIB)
00051   /* Dinkumware guys didn't provide a means to call allocate() without
00052    * supplying a hint, in disagreement with the standard.
00053    */
00054 
00055   Type* allocate(std::size_t n,const void* hint=0)
00056   {
00057     std::allocator<Type>& a=*this;
00058     return a.allocate(n,hint);
00059   }
00060 #endif
00061 
00062 };
00063 
00064 /* Detects whether a given allocator belongs to a defective stdlib not
00065  * having the required member templates.
00066  * Note that it does not suffice to check the Boost.Config stdlib
00067  * macros, as the user might have passed a custom, compliant allocator.
00068  * The checks also considers partial_std_allocator_wrapper to be
00069  * a standard defective allocator.
00070  */
00071 
00072 #if defined(BOOST_NO_STD_ALLOCATOR)&&\
00073   (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
00074 
00075 template<typename Allocator>
00076 struct is_partial_std_allocator
00077 {
00078   BOOST_STATIC_CONSTANT(bool,
00079     value=
00080       (is_same<
00081         std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
00082         Allocator
00083       >::value)||
00084       (is_same<
00085         partial_std_allocator_wrapper<
00086           BOOST_DEDUCED_TYPENAME Allocator::value_type>,
00087         Allocator
00088       >::value));
00089 };
00090 
00091 #else
00092 
00093 template<typename Allocator>
00094 struct is_partial_std_allocator
00095 {
00096   BOOST_STATIC_CONSTANT(bool,value=false);
00097 };
00098 
00099 #endif
00100 
00101 /* rebind operations for defective std allocators */
00102 
00103 template<typename Allocator,typename Type>
00104 struct partial_std_allocator_rebind_to
00105 {
00106   typedef partial_std_allocator_wrapper<Type> type;
00107 };
00108 
00109 /* rebind operation in all other cases */
00110 
00111 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
00112 /* Workaround for a problem in MSVC with dependent template typedefs
00113  * when doing rebinding of allocators.
00114  * Modeled after <sysc/packages/boost/mpl/aux_/msvc_dtw.hpp> (thanks, Aleksey!)
00115  */
00116 
00117 template<typename Allocator>
00118 struct rebinder
00119 {
00120   template<bool> struct fake_allocator:Allocator{};
00121   template<> struct fake_allocator<true>
00122   {
00123     template<typename Type> struct rebind{};
00124   };
00125 
00126   template<typename Type>
00127   struct result:
00128     fake_allocator<mpl::aux::msvc_never_true<Allocator>::value>::
00129       template rebind<Type>
00130   {
00131   };
00132 };
00133 #else
00134 template<typename Allocator>
00135 struct rebinder
00136 {
00137   template<typename Type>
00138   struct result
00139   {
00140       typedef typename Allocator::BOOST_NESTED_TEMPLATE 
00141           rebind<Type>::other other;
00142   };
00143 };
00144 #endif
00145 
00146 template<typename Allocator,typename Type>
00147 struct compliant_allocator_rebind_to
00148 {
00149   typedef typename rebinder<Allocator>::
00150       BOOST_NESTED_TEMPLATE result<Type>::other type;
00151 };
00152 
00153 /* rebind front-end */
00154 
00155 template<typename Allocator,typename Type>
00156 struct rebind_to:
00157   mpl::eval_if_c<
00158     is_partial_std_allocator<Allocator>::value,
00159     partial_std_allocator_rebind_to<Allocator,Type>,
00160     compliant_allocator_rebind_to<Allocator,Type>
00161   >
00162 {
00163 };
00164 
00165 /* allocator-independent versions of construct and destroy */
00166 
00167 template<typename Type>
00168 void construct(void* p,const Type& t)
00169 {
00170   new (p) Type(t);
00171 }
00172 
00173 template<typename Type>
00174 void destroy(const Type* p)
00175 {
00176   p->~Type();
00177 }
00178 
00179 } /* namespace boost::detail::allocator */
00180 
00181 } /* namespace boost::detail */
00182 
00183 } /* namespace boost */
00184 
00185 #endif

Generated on Wed Jan 21 15:32:09 2009 for SystemC by  doxygen 1.5.5