utilities.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2015.
  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. #ifndef BOOST_CONFIG_HPP
  16. # include <boost/config.hpp>
  17. #endif
  18. #
  19. #if defined(BOOST_HAS_PRAGMA_ONCE)
  20. # pragma once
  21. #endif
  22. #include <boost/interprocess/detail/config_begin.hpp>
  23. #include <boost/interprocess/detail/workaround.hpp>
  24. #include <boost/interprocess/interprocess_fwd.hpp>
  25. #include <boost/move/utility_core.hpp>
  26. #include <boost/interprocess/detail/min_max.hpp>
  27. #include <boost/interprocess/detail/type_traits.hpp>
  28. #include <boost/interprocess/detail/mpl.hpp>
  29. #include <boost/intrusive/pointer_traits.hpp>
  30. #include <boost/move/utility_core.hpp>
  31. #include <boost/static_assert.hpp>
  32. #include <boost/cstdint.hpp>
  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. //Rounds "orig_size" by excess to round_to bytes
  45. template<class SizeType>
  46. inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
  47. {
  48. return ((orig_size-1)/round_to+1)*round_to;
  49. }
  50. //Truncates "orig_size" to a multiple of "multiple" bytes.
  51. template<class SizeType>
  52. inline SizeType get_truncated_size(SizeType orig_size, SizeType multiple)
  53. {
  54. return orig_size/multiple*multiple;
  55. }
  56. //Rounds "orig_size" by excess to round_to bytes. round_to must be power of two
  57. template<class SizeType>
  58. inline SizeType get_rounded_size_po2(SizeType orig_size, SizeType round_to)
  59. {
  60. return ((orig_size-1)&(~(round_to-1))) + round_to;
  61. }
  62. //Truncates "orig_size" to a multiple of "multiple" bytes. multiple must be power of two
  63. template<class SizeType>
  64. inline SizeType get_truncated_size_po2(SizeType orig_size, SizeType multiple)
  65. {
  66. return (orig_size & (~(multiple-1)));
  67. }
  68. template <std::size_t OrigSize, std::size_t RoundTo>
  69. struct ct_rounded_size
  70. {
  71. BOOST_STATIC_ASSERT((RoundTo != 0));
  72. static const std::size_t intermediate_value = (OrigSize-1)/RoundTo+1;
  73. BOOST_STATIC_ASSERT(intermediate_value <= std::size_t(-1)/RoundTo);
  74. static const std::size_t value = intermediate_value*RoundTo;
  75. };
  76. // Gennaro Prota wrote this. Thanks!
  77. template <int p, int n = 4>
  78. struct ct_max_pow2_less
  79. {
  80. static const std::size_t c = 2*n < p;
  81. static const std::size_t value =
  82. c ? (ct_max_pow2_less< c*p, 2*c*n>::value) : n;
  83. };
  84. template <>
  85. struct ct_max_pow2_less<0, 0>
  86. {
  87. static const std::size_t value = 0;
  88. };
  89. } //namespace ipcdetail {
  90. //!Trait class to detect if an index is a node
  91. //!index. This allows more efficient operations
  92. //!when deallocating named objects.
  93. template <class Index>
  94. struct is_node_index
  95. {
  96. static const bool value = false;
  97. };
  98. //!Trait class to detect if an index is an intrusive
  99. //!index. This will embed the derivation hook in each
  100. //!allocation header, to provide memory for the intrusive
  101. //!container.
  102. template <class Index>
  103. struct is_intrusive_index
  104. {
  105. static const bool value = false;
  106. };
  107. template <typename T>
  108. BOOST_INTERPROCESS_FORCEINLINE T* addressof(T& v)
  109. {
  110. return reinterpret_cast<T*>(
  111. &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
  112. }
  113. template<class SizeType>
  114. struct sqrt_size_type_max
  115. {
  116. static const SizeType value = (SizeType(1) << (sizeof(SizeType)*(CHAR_BIT/2)))-1;
  117. };
  118. template<class SizeType>
  119. inline bool multiplication_overflows(SizeType a, SizeType b)
  120. {
  121. const SizeType sqrt_size_max = sqrt_size_type_max<SizeType>::value;
  122. return //Fast runtime check
  123. ( (a | b) > sqrt_size_max &&
  124. //Slow division check
  125. b && a > SizeType(-1)/b
  126. );
  127. }
  128. template<std::size_t SztSizeOfType, class SizeType>
  129. BOOST_INTERPROCESS_FORCEINLINE bool size_overflows(SizeType count)
  130. {
  131. //Compile time-check
  132. BOOST_STATIC_ASSERT(SztSizeOfType <= SizeType(-1));
  133. //Runtime check
  134. return multiplication_overflows(SizeType(SztSizeOfType), count);
  135. }
  136. template<class RawPointer, class OffsetType>
  137. class pointer_offset_caster;
  138. template<class T, class OffsetType>
  139. class pointer_offset_caster<T*, OffsetType>
  140. {
  141. public:
  142. BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(OffsetType offset)
  143. : m_offset(offset)
  144. {}
  145. BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(const volatile T *p)
  146. : m_offset(reinterpret_cast<OffsetType>(p))
  147. {}
  148. BOOST_INTERPROCESS_FORCEINLINE OffsetType offset() const
  149. { return m_offset; }
  150. BOOST_INTERPROCESS_FORCEINLINE T* pointer() const
  151. { return reinterpret_cast<T*>(m_offset); }
  152. private:
  153. OffsetType m_offset;
  154. };
  155. template<class SizeType>
  156. inline bool sum_overflows(SizeType a, SizeType b)
  157. { return SizeType(-1) - a < b; }
  158. //Anti-exception node eraser
  159. template<class Cont>
  160. class value_eraser
  161. {
  162. public:
  163. value_eraser(Cont & cont, typename Cont::iterator it)
  164. : m_cont(cont), m_index_it(it), m_erase(true){}
  165. ~value_eraser()
  166. { if(m_erase) m_cont.erase(m_index_it); }
  167. BOOST_INTERPROCESS_FORCEINLINE void release() { m_erase = false; }
  168. private:
  169. Cont &m_cont;
  170. typename Cont::iterator m_index_it;
  171. bool m_erase;
  172. };
  173. } //namespace interprocess {
  174. } //namespace boost {
  175. #include <boost/interprocess/detail/config_end.hpp>
  176. #endif //#ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP