allocator_traits.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* Copyright 2003-2018 Joaquin M Lopez Munoz.
  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)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_ALLOCATOR_TRAITS_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #if !defined(BOOST_NO_CXX11_ALLOCATOR)
  15. #include <memory>
  16. #else
  17. #include <boost/detail/workaround.hpp>
  18. #include <boost/move/core.hpp>
  19. #include <boost/move/utility_core.hpp>
  20. #include <boost/multi_index/detail/vartempl_support.hpp>
  21. #include <new>
  22. #endif
  23. namespace boost{
  24. namespace multi_index{
  25. namespace detail{
  26. /* poor man's replacement of std::allocator_traits */
  27. #if !defined(BOOST_NO_CXX11_ALLOCATOR)
  28. template<typename Allocator>
  29. struct allocator_traits:std::allocator_traits<Allocator>
  30. {
  31. /* wrap std::allocator_traits alias templates for use in C++03 codebase */
  32. typedef std::allocator_traits<Allocator> super;
  33. template<typename T>
  34. struct rebind_alloc
  35. {
  36. typedef typename super::template rebind_alloc<T> type;
  37. };
  38. template<typename T>
  39. struct rebind_traits
  40. {
  41. typedef typename super::template rebind_traits<T> type;
  42. };
  43. };
  44. #else
  45. /* not a full std::allocator_traits rewrite (not needed) */
  46. template<typename Allocator>
  47. struct allocator_traits
  48. {
  49. typedef Allocator allocator_type;
  50. typedef typename Allocator::value_type value_type;
  51. typedef typename Allocator::pointer pointer;
  52. typedef typename Allocator::const_pointer const_pointer;
  53. /* [const_]void_pointer not provided as boost::pointer_traits's
  54. * rebind_to has been seen to fail with things like
  55. * boost::interprocess::offset_ptr in relatively old environments.
  56. */
  57. typedef typename Allocator::difference_type difference_type;
  58. typedef typename Allocator::size_type size_type;
  59. template<typename T>
  60. struct rebind_alloc
  61. {
  62. typedef typename Allocator::template rebind<T>::other type;
  63. };
  64. template<typename T>
  65. struct rebind_traits
  66. {
  67. typedef allocator_traits<typename rebind_alloc<T>::type> type;
  68. };
  69. static pointer allocate(Allocator& a,size_type n){return a.allocate(n);}
  70. static pointer allocate(Allocator& a,size_type n,const_pointer p)
  71. /* should've been const_void_pointer p */
  72. {return a.allocate(n,p);}
  73. static void deallocate(Allocator& a,pointer p,size_type n)
  74. {a.deallocate(p,n);}
  75. template<typename T>
  76. static void construct(Allocator&,T* p,const T& x)
  77. {::new (static_cast<void*>(p)) T(x);}
  78. template<typename T>
  79. static void construct(Allocator&,T* p,BOOST_RV_REF(T) x)
  80. {::new (static_cast<void*>(p)) T(boost::move(x));}
  81. template<typename T,BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  82. static void construct(Allocator&,T* p,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  83. {
  84. vartempl_placement_new(p,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  85. }
  86. #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
  87. /* MSVC issues spurious warnings about unreferencend formal parameters in
  88. * destroy<T> when T is a class with trivial dtor.
  89. */
  90. #pragma warning(push)
  91. #pragma warning(disable:4100)
  92. #endif
  93. template<typename T>
  94. static void destroy(Allocator&,T* p){p->~T();}
  95. #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
  96. #pragma warning(pop)
  97. #endif
  98. static size_type max_size(Allocator& a)BOOST_NOEXCEPT{return a.max_size();}
  99. };
  100. #endif
  101. template<typename Allocator,typename T>
  102. struct rebind_alloc_for
  103. {
  104. typedef typename allocator_traits<Allocator>::
  105. template rebind_alloc<T>::type type;
  106. };
  107. } /* namespace multi_index::detail */
  108. } /* namespace multi_index */
  109. } /* namespace boost */
  110. #endif