allocator_traits.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* Copyright 2003-2020 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 <boost/type_traits/integral_constant.hpp>
  22. #include <new>
  23. #endif
  24. namespace boost{
  25. namespace multi_index{
  26. namespace detail{
  27. /* poor man's replacement of std::allocator_traits */
  28. #if !defined(BOOST_NO_CXX11_ALLOCATOR)
  29. template<typename Allocator>
  30. struct allocator_traits:std::allocator_traits<Allocator>
  31. {
  32. /* wrap std::allocator_traits alias templates for use in C++03 codebase */
  33. typedef std::allocator_traits<Allocator> super;
  34. template<typename T>
  35. struct rebind_alloc
  36. {
  37. typedef typename super::template rebind_alloc<T> type;
  38. };
  39. template<typename T>
  40. struct rebind_traits
  41. {
  42. typedef typename super::template rebind_traits<T> type;
  43. };
  44. };
  45. #else
  46. /* not a full std::allocator_traits rewrite (not needed) */
  47. template<typename Allocator>
  48. struct allocator_traits
  49. {
  50. typedef Allocator allocator_type;
  51. typedef typename Allocator::value_type value_type;
  52. typedef typename Allocator::pointer pointer;
  53. typedef typename Allocator::const_pointer const_pointer;
  54. /* [const_]void_pointer not provided as boost::pointer_traits's
  55. * rebind_to has been seen to fail with things like
  56. * boost::interprocess::offset_ptr in relatively old environments.
  57. */
  58. typedef typename Allocator::difference_type difference_type;
  59. typedef typename Allocator::size_type size_type;
  60. typedef boost::false_type propagate_on_container_copy_assignment;
  61. typedef boost::false_type propagate_on_container_move_assignment;
  62. typedef boost::false_type propagate_on_container_swap;
  63. template<typename T>
  64. struct rebind_alloc
  65. {
  66. typedef typename Allocator::template rebind<T>::other type;
  67. };
  68. template<typename T>
  69. struct rebind_traits
  70. {
  71. typedef allocator_traits<typename rebind_alloc<T>::type> type;
  72. };
  73. static pointer allocate(Allocator& a,size_type n){return a.allocate(n);}
  74. static pointer allocate(Allocator& a,size_type n,const_pointer p)
  75. /* should've been const_void_pointer p */
  76. {return a.allocate(n,p);}
  77. static void deallocate(Allocator& a,pointer p,size_type n)
  78. {a.deallocate(p,n);}
  79. template<typename T>
  80. static void construct(Allocator&,T* p,const T& x)
  81. {::new (static_cast<void*>(p)) T(x);}
  82. template<typename T>
  83. static void construct(Allocator&,T* p,BOOST_RV_REF(T) x)
  84. {::new (static_cast<void*>(p)) T(boost::move(x));}
  85. template<typename T,BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
  86. static void construct(Allocator&,T* p,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
  87. {
  88. vartempl_placement_new(p,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
  89. }
  90. #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
  91. /* MSVC issues spurious warnings about unreferencend formal parameters in
  92. * destroy<T> when T is a class with trivial dtor.
  93. */
  94. #pragma warning(push)
  95. #pragma warning(disable:4100)
  96. #endif
  97. template<typename T>
  98. static void destroy(Allocator&,T* p){p->~T();}
  99. #if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
  100. #pragma warning(pop)
  101. #endif
  102. static size_type max_size(Allocator& a)BOOST_NOEXCEPT{return a.max_size();}
  103. static Allocator select_on_container_copy_construction(const Allocator& a)
  104. {
  105. return a;
  106. }
  107. };
  108. #endif
  109. template<typename Allocator,typename T>
  110. struct rebind_alloc_for
  111. {
  112. typedef typename allocator_traits<Allocator>::
  113. template rebind_alloc<T>::type type;
  114. };
  115. } /* namespace multi_index::detail */
  116. } /* namespace multi_index */
  117. } /* namespace boost */
  118. #endif