Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:06

0001 /* Copyright 2003-2020 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 http://www.boost.org/libs/multi_index for library home page.
0007  */
0008 
0009 #ifndef BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP
0010 #define BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 
0018 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
0019 #include <boost/type_traits/is_empty.hpp>
0020 #include <memory>
0021 #else
0022 #include <boost/detail/workaround.hpp>
0023 #include <boost/move/core.hpp>
0024 #include <boost/move/utility_core.hpp>
0025 #include <boost/multi_index/detail/vartempl_support.hpp>
0026 #include <boost/type_traits/integral_constant.hpp>
0027 #include <boost/type_traits/is_empty.hpp>
0028 #include <new>
0029 #endif
0030 
0031 namespace boost{
0032 
0033 namespace multi_index{
0034 
0035 namespace detail{
0036 
0037 /* poor man's replacement of std::allocator_traits */
0038 
0039 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
0040 
0041 template<typename T> struct void_helper{typedef void type;};
0042 
0043 template<typename Allocator,typename=void>
0044 struct allocator_is_always_equal:boost::is_empty<Allocator>{};
0045 
0046 template<typename Allocator>
0047 struct allocator_is_always_equal<
0048   Allocator,
0049   typename void_helper<
0050     typename std::allocator_traits<Allocator>::is_always_equal
0051   >::type
0052 >:std::allocator_traits<Allocator>::is_always_equal{};
0053 
0054 template<typename Allocator>
0055 struct allocator_traits:std::allocator_traits<Allocator>
0056 {
0057   /* wrap std::allocator_traits alias templates for use in C++03 codebase */
0058 
0059   typedef std::allocator_traits<Allocator> super;
0060 
0061   /* pre-C++17 compatibilty */
0062 
0063   typedef allocator_is_always_equal<Allocator> is_always_equal;
0064 
0065   template<typename T>
0066   struct rebind_alloc
0067   {
0068     typedef typename super::template rebind_alloc<T> type;
0069   };
0070 
0071   template<typename T>
0072   struct rebind_traits
0073   {
0074     typedef typename super::template rebind_traits<T> type;
0075   };
0076 };
0077 
0078 #else
0079 
0080 /* not a full std::allocator_traits rewrite (not needed) */
0081 
0082 template<typename Allocator>
0083 struct allocator_traits
0084 {
0085   typedef Allocator                           allocator_type;
0086   typedef typename Allocator::value_type      value_type;
0087   typedef typename Allocator::pointer         pointer;
0088   typedef typename Allocator::const_pointer   const_pointer;
0089 
0090   /* [const_]void_pointer not provided as boost::pointer_traits's
0091    * rebind_to has been seen to fail with things like
0092    * boost::interprocess::offset_ptr in relatively old environments.
0093    */
0094 
0095   typedef typename Allocator::difference_type difference_type;
0096   typedef typename Allocator::size_type       size_type;
0097 
0098   typedef boost::false_type          propagate_on_container_copy_assignment;
0099   typedef boost::false_type          propagate_on_container_move_assignment;
0100   typedef boost::false_type          propagate_on_container_swap;
0101   typedef boost::is_empty<Allocator> is_always_equal;
0102 
0103   template<typename T>
0104   struct rebind_alloc
0105   {
0106     typedef typename Allocator::template rebind<T>::other type;
0107   };
0108 
0109   template<typename T>
0110   struct rebind_traits
0111   {
0112     typedef allocator_traits<typename rebind_alloc<T>::type> type;
0113   };
0114 
0115   static pointer   allocate(Allocator& a,size_type n){return a.allocate(n);}
0116   static pointer   allocate(Allocator& a,size_type n,const_pointer p)
0117                                    /* should've been const_void_pointer p */
0118                      {return a.allocate(n,p);} 
0119   static void      deallocate(Allocator& a,pointer p,size_type n)
0120                      {a.deallocate(p,n);}
0121   template<typename T>
0122   static void      construct(Allocator&,T* p,const T& x)
0123                      {::new (static_cast<void*>(p)) T(x);}
0124   template<typename T>
0125   static void      construct(Allocator&,T* p,BOOST_RV_REF(T) x)
0126                      {::new (static_cast<void*>(p)) T(boost::move(x));}
0127  
0128   template<typename T,BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
0129   static void construct(Allocator&,T* p,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
0130   {
0131     vartempl_placement_new(p,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
0132   }
0133 
0134 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
0135 /* MSVC issues spurious warnings about unreferencend formal parameters in
0136  * destroy<T> when T is a class with trivial dtor.
0137  */
0138 
0139 #pragma warning(push)
0140 #pragma warning(disable:4100)
0141 #endif
0142 
0143   template<typename T>
0144   static void destroy(Allocator&,T* p){p->~T();}
0145 
0146 #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
0147 #pragma warning(pop)
0148 #endif
0149 
0150   static size_type max_size(Allocator& a)BOOST_NOEXCEPT{return a.max_size();}
0151 
0152   static Allocator select_on_container_copy_construction(const Allocator& a)
0153   {
0154     return a;
0155   }
0156 };
0157 
0158 #endif
0159 
0160 template<typename Allocator,typename T>
0161 struct rebind_alloc_for
0162 {
0163   typedef typename allocator_traits<Allocator>::
0164     template rebind_alloc<T>::type               type;
0165 };
0166 
0167 } /* namespace multi_index::detail */
0168 
0169 } /* namespace multi_index */
0170 
0171 } /* namespace boost */
0172 
0173 #endif