utilities.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2012.
  4. // (C) Copyright Gennaro Prota 2003 - 2004.
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/libs/interprocess for documentation.
  11. //
  12. //////////////////////////////////////////////////////////////////////////////
  13. #ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP
  14. #define BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP
  15. #if (defined _MSC_VER) && (_MSC_VER >= 1200)
  16. # pragma once
  17. #endif
  18. #include <boost/interprocess/detail/config_begin.hpp>
  19. #include <boost/interprocess/detail/workaround.hpp>
  20. #include <boost/interprocess/interprocess_fwd.hpp>
  21. #include <boost/move/move.hpp>
  22. #include <boost/type_traits/has_trivial_destructor.hpp>
  23. #include <boost/interprocess/detail/min_max.hpp>
  24. #include <boost/interprocess/detail/type_traits.hpp>
  25. #include <boost/interprocess/detail/transform_iterator.hpp>
  26. #include <boost/interprocess/detail/mpl.hpp>
  27. #include <boost/interprocess/containers/version_type.hpp>
  28. #include <boost/intrusive/pointer_traits.hpp>
  29. #include <boost/move/move.hpp>
  30. #include <boost/static_assert.hpp>
  31. #include <utility>
  32. #include <algorithm>
  33. #include <climits>
  34. namespace boost {
  35. namespace interprocess {
  36. namespace ipcdetail {
  37. template <class T>
  38. inline T* to_raw_pointer(T* p)
  39. { return p; }
  40. template <class Pointer>
  41. inline typename boost::intrusive::pointer_traits<Pointer>::element_type*
  42. to_raw_pointer(const Pointer &p)
  43. { return boost::interprocess::ipcdetail::to_raw_pointer(p.operator->()); }
  44. //!To avoid ADL problems with swap
  45. template <class T>
  46. inline void do_swap(T& x, T& y)
  47. {
  48. using std::swap;
  49. swap(x, y);
  50. }
  51. //Rounds "orig_size" by excess to round_to bytes
  52. template<class SizeType>
  53. inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
  54. {
  55. return ((orig_size-1)/round_to+1)*round_to;
  56. }
  57. //Truncates "orig_size" to a multiple of "multiple" bytes.
  58. template<class SizeType>
  59. inline SizeType get_truncated_size(SizeType orig_size, SizeType multiple)
  60. {
  61. return orig_size/multiple*multiple;
  62. }
  63. //Rounds "orig_size" by excess to round_to bytes. round_to must be power of two
  64. template<class SizeType>
  65. inline SizeType get_rounded_size_po2(SizeType orig_size, SizeType round_to)
  66. {
  67. return ((orig_size-1)&(~(round_to-1))) + round_to;
  68. }
  69. //Truncates "orig_size" to a multiple of "multiple" bytes. multiple must be power of two
  70. template<class SizeType>
  71. inline SizeType get_truncated_size_po2(SizeType orig_size, SizeType multiple)
  72. {
  73. return (orig_size & (~(multiple-1)));
  74. }
  75. template <std::size_t OrigSize, std::size_t RoundTo>
  76. struct ct_rounded_size
  77. {
  78. BOOST_STATIC_ASSERT((RoundTo != 0));
  79. static const std::size_t intermediate_value = (OrigSize-1)/RoundTo+1;
  80. BOOST_STATIC_ASSERT(intermediate_value <= std::size_t(-1)/RoundTo);
  81. static const std::size_t value = intermediate_value*RoundTo;
  82. };
  83. // Gennaro Prota wrote this. Thanks!
  84. template <int p, int n = 4>
  85. struct ct_max_pow2_less
  86. {
  87. static const std::size_t c = 2*n < p;
  88. static const std::size_t value =
  89. c ? (ct_max_pow2_less< c*p, 2*c*n>::value) : n;
  90. };
  91. template <>
  92. struct ct_max_pow2_less<0, 0>
  93. {
  94. static const std::size_t value = 0;
  95. };
  96. } //namespace ipcdetail {
  97. //!Trait class to detect if an index is a node
  98. //!index. This allows more efficient operations
  99. //!when deallocating named objects.
  100. template <class Index>
  101. struct is_node_index
  102. {
  103. static const bool value = false;
  104. };
  105. //!Trait class to detect if an index is an intrusive
  106. //!index. This will embed the derivation hook in each
  107. //!allocation header, to provide memory for the intrusive
  108. //!container.
  109. template <class Index>
  110. struct is_intrusive_index
  111. {
  112. static const bool value = false;
  113. };
  114. template <typename T> T*
  115. addressof(T& v)
  116. {
  117. return reinterpret_cast<T*>(
  118. &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
  119. }
  120. template<class SizeType>
  121. struct sqrt_size_type_max
  122. {
  123. static const SizeType value = (SizeType(1) << (sizeof(SizeType)*(CHAR_BIT/2)))-1;
  124. };
  125. template<class SizeType>
  126. inline bool multiplication_overflows(SizeType a, SizeType b)
  127. {
  128. const SizeType sqrt_size_max = sqrt_size_type_max<SizeType>::value;
  129. return //Fast runtime check
  130. ( (a | b) > sqrt_size_max &&
  131. //Slow division check
  132. b && a > SizeType(-1)/b
  133. );
  134. }
  135. template<std::size_t SztSizeOfType, class SizeType>
  136. inline bool size_overflows(SizeType count)
  137. {
  138. //Compile time-check
  139. BOOST_STATIC_ASSERT(SztSizeOfType <= SizeType(-1));
  140. //Runtime check
  141. return multiplication_overflows(SizeType(SztSizeOfType), count);
  142. }
  143. template<class RawPointer>
  144. class pointer_size_t_caster
  145. {
  146. public:
  147. explicit pointer_size_t_caster(std::size_t sz)
  148. : m_ptr(reinterpret_cast<RawPointer>(sz))
  149. {}
  150. explicit pointer_size_t_caster(RawPointer p)
  151. : m_ptr(p)
  152. {}
  153. std::size_t size() const
  154. { return reinterpret_cast<std::size_t>(m_ptr); }
  155. RawPointer pointer() const
  156. { return m_ptr; }
  157. private:
  158. RawPointer m_ptr;
  159. };
  160. template<class SizeType>
  161. inline bool sum_overflows(SizeType a, SizeType b)
  162. { return SizeType(-1) - a < b; }
  163. //Anti-exception node eraser
  164. template<class Cont>
  165. class value_eraser
  166. {
  167. public:
  168. value_eraser(Cont & cont, typename Cont::iterator it)
  169. : m_cont(cont), m_index_it(it), m_erase(true){}
  170. ~value_eraser()
  171. { if(m_erase) m_cont.erase(m_index_it); }
  172. void release() { m_erase = false; }
  173. private:
  174. Cont &m_cont;
  175. typename Cont::iterator m_index_it;
  176. bool m_erase;
  177. };
  178. } //namespace interprocess {
  179. } //namespace boost {
  180. #include <boost/interprocess/detail/config_end.hpp>
  181. #endif //#ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP