Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:30:41

0001 /* Copyright 2003-2013 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See Boost website at http://www.boost.org/
0007  */
0008 
0009 #ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
0010 #define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
0011 
0012 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0013 #include <boost/detail/workaround.hpp>
0014 #include <boost/detail/select_type.hpp>
0015 #include <boost/type_traits/is_same.hpp>
0016 #include <cstddef>
0017 #include <memory>
0018 #include <new>
0019 
0020 namespace boost{
0021 
0022 namespace detail{
0023 
0024 /* Allocator adaption layer. Some stdlibs provide allocators without rebind
0025  * and template ctors. These facilities are simulated with the external
0026  * template class rebind_to and the aid of partial_std_allocator_wrapper.
0027  */
0028 
0029 namespace allocator{
0030 
0031 /* partial_std_allocator_wrapper inherits the functionality of a std
0032  * allocator while providing a templatized ctor and other bits missing
0033  * in some stdlib implementation or another.
0034  */
0035 
0036 template<typename Type>
0037 class partial_std_allocator_wrapper:public std::allocator<Type>
0038 {
0039 public:
0040   /* Oddly enough, STLport does not define std::allocator<void>::value_type
0041    * when configured to work without partial template specialization.
0042    * No harm in supplying the definition here unconditionally.
0043    */
0044 
0045   typedef Type value_type;
0046 
0047   partial_std_allocator_wrapper(){}
0048 
0049   template<typename Other>
0050   partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
0051 
0052   partial_std_allocator_wrapper(const std::allocator<Type>& x):
0053     std::allocator<Type>(x)
0054   {
0055   }
0056 
0057 #if defined(BOOST_DINKUMWARE_STDLIB)
0058   /* Dinkumware guys didn't provide a means to call allocate() without
0059    * supplying a hint, in disagreement with the standard.
0060    */
0061 
0062   Type* allocate(std::size_t n,const void* hint=0)
0063   {
0064     std::allocator<Type>& a=*this;
0065     return a.allocate(n,hint);
0066   }
0067 #endif
0068 
0069 };
0070 
0071 /* Detects whether a given allocator belongs to a defective stdlib not
0072  * having the required member templates.
0073  * Note that it does not suffice to check the Boost.Config stdlib
0074  * macros, as the user might have passed a custom, compliant allocator.
0075  * The checks also considers partial_std_allocator_wrapper to be
0076  * a standard defective allocator.
0077  */
0078 
0079 #if defined(BOOST_NO_STD_ALLOCATOR)&&\
0080   (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
0081 
0082 template<typename Allocator>
0083 struct is_partial_std_allocator
0084 {
0085   BOOST_STATIC_CONSTANT(bool,
0086     value=
0087       (is_same<
0088         std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
0089         Allocator
0090       >::value)||
0091       (is_same<
0092         partial_std_allocator_wrapper<
0093           BOOST_DEDUCED_TYPENAME Allocator::value_type>,
0094         Allocator
0095       >::value));
0096 };
0097 
0098 #else
0099 
0100 template<typename Allocator>
0101 struct is_partial_std_allocator
0102 {
0103   BOOST_STATIC_CONSTANT(bool,value=false);
0104 };
0105 
0106 #endif
0107 
0108 /* rebind operations for defective std allocators */
0109 
0110 template<typename Allocator,typename Type>
0111 struct partial_std_allocator_rebind_to
0112 {
0113   typedef partial_std_allocator_wrapper<Type> type;
0114 };
0115 
0116 /* rebind operation in all other cases */
0117 
0118 template<typename Allocator>
0119 struct rebinder
0120 {
0121   template<typename Type>
0122   struct result
0123   {
0124 #ifdef BOOST_NO_CXX11_ALLOCATOR
0125       typedef typename Allocator::BOOST_NESTED_TEMPLATE
0126           rebind<Type>::other other;
0127 #else
0128       typedef typename std::allocator_traits<Allocator>::BOOST_NESTED_TEMPLATE
0129           rebind_alloc<Type> other;
0130 #endif
0131   };
0132 };
0133 
0134 template<typename Allocator,typename Type>
0135 struct compliant_allocator_rebind_to
0136 {
0137   typedef typename rebinder<Allocator>::
0138       BOOST_NESTED_TEMPLATE result<Type>::other type;
0139 };
0140 
0141 /* rebind front-end */
0142 
0143 template<typename Allocator,typename Type>
0144 struct rebind_to:
0145   boost::detail::if_true<
0146     is_partial_std_allocator<Allocator>::value
0147   >::template then<
0148     partial_std_allocator_rebind_to<Allocator,Type>,
0149     compliant_allocator_rebind_to<Allocator,Type>
0150   >::type
0151 {
0152 };
0153 
0154 /* allocator-independent versions of construct and destroy */
0155 
0156 template<typename Type>
0157 void construct(void* p,const Type& t)
0158 {
0159   new (p) Type(t);
0160 }
0161 
0162 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
0163 /* MSVC++ issues spurious warnings about unreferencend formal parameters
0164  * in destroy<Type> when Type is a class with trivial dtor.
0165  */
0166 
0167 #pragma warning(push)
0168 #pragma warning(disable:4100)
0169 #endif
0170 
0171 template<typename Type>
0172 void destroy(const Type* p)
0173 {
0174 
0175 #if BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590))
0176   const_cast<Type*>(p)->~Type();
0177 #else
0178   p->~Type();
0179 #endif
0180 
0181 }
0182 
0183 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
0184 #pragma warning(pop)
0185 #endif
0186 
0187 } /* namespace boost::detail::allocator */
0188 
0189 } /* namespace boost::detail */
0190 
0191 } /* namespace boost */
0192 
0193 #endif