memory.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //
  2. // detail/memory.hpp
  3. // ~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_DETAIL_MEMORY_HPP
  11. #define BOOST_ASIO_DETAIL_MEMORY_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <cstddef>
  17. #include <cstdlib>
  18. #include <memory>
  19. #include <new>
  20. #include <boost/asio/detail/cstdint.hpp>
  21. #include <boost/asio/detail/throw_exception.hpp>
  22. #if !defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
  23. # include <boost/make_shared.hpp>
  24. # include <boost/shared_ptr.hpp>
  25. # include <boost/weak_ptr.hpp>
  26. #endif // !defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
  27. #if !defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
  28. # include <boost/utility/addressof.hpp>
  29. #endif // !defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
  30. #if !defined(BOOST_ASIO_HAS_STD_ALIGNED_ALLOC) \
  31. && defined(BOOST_ASIO_HAS_BOOST_ALIGN) \
  32. && defined(BOOST_ASIO_HAS_ALIGNOF)
  33. # include <boost/align/aligned_alloc.hpp>
  34. #endif // !defined(BOOST_ASIO_HAS_STD_ALIGNED_ALLOC)
  35. // && defined(BOOST_ASIO_HAS_BOOST_ALIGN)
  36. // && defined(BOOST_ASIO_HAS_ALIGNOF)
  37. namespace boost {
  38. namespace asio {
  39. namespace detail {
  40. #if defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
  41. using std::make_shared;
  42. using std::shared_ptr;
  43. using std::weak_ptr;
  44. #else // defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
  45. using boost::make_shared;
  46. using boost::shared_ptr;
  47. using boost::weak_ptr;
  48. #endif // defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
  49. #if defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
  50. using std::addressof;
  51. #else // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
  52. using boost::addressof;
  53. #endif // defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
  54. #if defined(BOOST_ASIO_HAS_STD_TO_ADDRESS)
  55. using std::to_address;
  56. #else // defined(BOOST_ASIO_HAS_STD_TO_ADDRESS)
  57. template <typename T>
  58. inline T* to_address(T* p) { return p; }
  59. template <typename T>
  60. inline const T* to_address(const T* p) { return p; }
  61. template <typename T>
  62. inline volatile T* to_address(volatile T* p) { return p; }
  63. template <typename T>
  64. inline const volatile T* to_address(const volatile T* p) { return p; }
  65. #endif // defined(BOOST_ASIO_HAS_STD_TO_ADDRESS)
  66. inline void* align(std::size_t alignment,
  67. std::size_t size, void*& ptr, std::size_t& space)
  68. {
  69. #if defined(BOOST_ASIO_HAS_STD_ALIGN)
  70. return std::align(alignment, size, ptr, space);
  71. #else // defined(BOOST_ASIO_HAS_STD_ALIGN)
  72. const uintptr_t intptr = reinterpret_cast<uintptr_t>(ptr);
  73. const uintptr_t aligned = (intptr - 1u + alignment) & -alignment;
  74. const std::size_t padding = aligned - intptr;
  75. if (size + padding > space)
  76. return 0;
  77. space -= padding;
  78. ptr = reinterpret_cast<void*>(aligned);
  79. return ptr;
  80. #endif // defined(BOOST_ASIO_HAS_STD_ALIGN)
  81. }
  82. } // namespace detail
  83. #if defined(BOOST_ASIO_HAS_CXX11_ALLOCATORS)
  84. using std::allocator_arg_t;
  85. # define BOOST_ASIO_USES_ALLOCATOR(t) \
  86. namespace std { \
  87. template <typename Allocator> \
  88. struct uses_allocator<t, Allocator> : true_type {}; \
  89. } \
  90. /**/
  91. # define BOOST_ASIO_REBIND_ALLOC(alloc, t) \
  92. typename std::allocator_traits<alloc>::template rebind_alloc<t>
  93. /**/
  94. #else // defined(BOOST_ASIO_HAS_CXX11_ALLOCATORS)
  95. struct allocator_arg_t {};
  96. # define BOOST_ASIO_USES_ALLOCATOR(t)
  97. # define BOOST_ASIO_REBIND_ALLOC(alloc, t) \
  98. typename alloc::template rebind<t>::other
  99. /**/
  100. #endif // defined(BOOST_ASIO_HAS_CXX11_ALLOCATORS)
  101. inline void* aligned_new(std::size_t align, std::size_t size)
  102. {
  103. #if defined(BOOST_ASIO_HAS_STD_ALIGNED_ALLOC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  104. align = (align < BOOST_ASIO_DEFAULT_ALIGN) ? BOOST_ASIO_DEFAULT_ALIGN : align;
  105. size = (size % align == 0) ? size : size + (align - size % align);
  106. void* ptr = std::aligned_alloc(align, size);
  107. if (!ptr)
  108. {
  109. std::bad_alloc ex;
  110. boost::asio::detail::throw_exception(ex);
  111. }
  112. return ptr;
  113. #elif defined(BOOST_ASIO_HAS_BOOST_ALIGN) && defined(BOOST_ASIO_HAS_ALIGNOF)
  114. align = (align < BOOST_ASIO_DEFAULT_ALIGN) ? BOOST_ASIO_DEFAULT_ALIGN : align;
  115. size = (size % align == 0) ? size : size + (align - size % align);
  116. void* ptr = boost::alignment::aligned_alloc(align, size);
  117. if (!ptr)
  118. {
  119. std::bad_alloc ex;
  120. boost::asio::detail::throw_exception(ex);
  121. }
  122. return ptr;
  123. #elif defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  124. align = (align < BOOST_ASIO_DEFAULT_ALIGN) ? BOOST_ASIO_DEFAULT_ALIGN : align;
  125. size = (size % align == 0) ? size : size + (align - size % align);
  126. void* ptr = _aligned_malloc(size, align);
  127. if (!ptr)
  128. {
  129. std::bad_alloc ex;
  130. boost::asio::detail::throw_exception(ex);
  131. }
  132. return ptr;
  133. #else // defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  134. (void)align;
  135. return ::operator new(size);
  136. #endif // defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  137. }
  138. inline void aligned_delete(void* ptr)
  139. {
  140. #if defined(BOOST_ASIO_HAS_STD_ALIGNED_ALLOC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  141. std::free(ptr);
  142. #elif defined(BOOST_ASIO_HAS_BOOST_ALIGN) && defined(BOOST_ASIO_HAS_ALIGNOF)
  143. boost::alignment::aligned_free(ptr);
  144. #elif defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  145. _aligned_free(ptr);
  146. #else // defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  147. ::operator delete(ptr);
  148. #endif // defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_HAS_ALIGNOF)
  149. }
  150. } // namespace asio
  151. } // namespace boost
  152. #endif // BOOST_ASIO_DETAIL_MEMORY_HPP