Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // (C) Copyright Ion Gaztanaga 2005-2012. Chris@16: // (C) Copyright Gennaro Prota 2003 - 2004. Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/interprocess for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: Chris@16: #ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP Chris@16: #define BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: # Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace interprocess { Chris@16: namespace ipcdetail { Chris@16: Chris@16: template Chris@16: inline T* to_raw_pointer(T* p) Chris@16: { return p; } Chris@16: Chris@16: template Chris@16: inline typename boost::intrusive::pointer_traits::element_type* Chris@16: to_raw_pointer(const Pointer &p) Chris@16: { return boost::interprocess::ipcdetail::to_raw_pointer(p.operator->()); } Chris@16: Chris@16: //Rounds "orig_size" by excess to round_to bytes Chris@16: template Chris@16: inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to) Chris@16: { Chris@16: return ((orig_size-1)/round_to+1)*round_to; Chris@16: } Chris@16: Chris@16: //Truncates "orig_size" to a multiple of "multiple" bytes. Chris@16: template Chris@16: inline SizeType get_truncated_size(SizeType orig_size, SizeType multiple) Chris@16: { Chris@16: return orig_size/multiple*multiple; Chris@16: } Chris@16: Chris@16: //Rounds "orig_size" by excess to round_to bytes. round_to must be power of two Chris@16: template Chris@16: inline SizeType get_rounded_size_po2(SizeType orig_size, SizeType round_to) Chris@16: { Chris@16: return ((orig_size-1)&(~(round_to-1))) + round_to; Chris@16: } Chris@16: Chris@16: //Truncates "orig_size" to a multiple of "multiple" bytes. multiple must be power of two Chris@16: template Chris@16: inline SizeType get_truncated_size_po2(SizeType orig_size, SizeType multiple) Chris@16: { Chris@16: return (orig_size & (~(multiple-1))); Chris@16: } Chris@16: Chris@16: template Chris@16: struct ct_rounded_size Chris@16: { Chris@16: BOOST_STATIC_ASSERT((RoundTo != 0)); Chris@16: static const std::size_t intermediate_value = (OrigSize-1)/RoundTo+1; Chris@16: BOOST_STATIC_ASSERT(intermediate_value <= std::size_t(-1)/RoundTo); Chris@16: static const std::size_t value = intermediate_value*RoundTo; Chris@16: }; Chris@16: Chris@16: // Gennaro Prota wrote this. Thanks! Chris@16: template Chris@16: struct ct_max_pow2_less Chris@16: { Chris@16: static const std::size_t c = 2*n < p; Chris@16: Chris@16: static const std::size_t value = Chris@16: c ? (ct_max_pow2_less< c*p, 2*c*n>::value) : n; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct ct_max_pow2_less<0, 0> Chris@16: { Chris@16: static const std::size_t value = 0; Chris@16: }; Chris@16: Chris@16: } //namespace ipcdetail { Chris@16: Chris@16: //!Trait class to detect if an index is a node Chris@16: //!index. This allows more efficient operations Chris@16: //!when deallocating named objects. Chris@16: template Chris@16: struct is_node_index Chris@16: { Chris@16: static const bool value = false; Chris@16: }; Chris@16: Chris@16: //!Trait class to detect if an index is an intrusive Chris@16: //!index. This will embed the derivation hook in each Chris@16: //!allocation header, to provide memory for the intrusive Chris@16: //!container. Chris@16: template Chris@16: struct is_intrusive_index Chris@16: { Chris@16: static const bool value = false; Chris@16: }; Chris@16: Chris@16: template T* Chris@16: addressof(T& v) Chris@16: { Chris@16: return reinterpret_cast( Chris@16: &const_cast(reinterpret_cast(v))); Chris@16: } Chris@16: Chris@16: template Chris@16: struct sqrt_size_type_max Chris@16: { Chris@16: static const SizeType value = (SizeType(1) << (sizeof(SizeType)*(CHAR_BIT/2)))-1; Chris@16: }; Chris@16: Chris@16: template Chris@16: inline bool multiplication_overflows(SizeType a, SizeType b) Chris@16: { Chris@16: const SizeType sqrt_size_max = sqrt_size_type_max::value; Chris@101: return //Fast runtime check Chris@16: ( (a | b) > sqrt_size_max && Chris@101: //Slow division check Chris@16: b && a > SizeType(-1)/b Chris@16: ); Chris@16: } Chris@16: Chris@16: template Chris@16: inline bool size_overflows(SizeType count) Chris@16: { Chris@16: //Compile time-check Chris@16: BOOST_STATIC_ASSERT(SztSizeOfType <= SizeType(-1)); Chris@16: //Runtime check Chris@16: return multiplication_overflows(SizeType(SztSizeOfType), count); Chris@16: } Chris@16: Chris@16: template Chris@16: class pointer_size_t_caster Chris@16: { Chris@16: public: Chris@101: BOOST_STATIC_ASSERT(sizeof(std::size_t) == sizeof(void*)); Chris@101: Chris@16: explicit pointer_size_t_caster(std::size_t sz) Chris@16: : m_ptr(reinterpret_cast(sz)) Chris@16: {} Chris@16: Chris@16: explicit pointer_size_t_caster(RawPointer p) Chris@16: : m_ptr(p) Chris@16: {} Chris@16: Chris@16: std::size_t size() const Chris@16: { return reinterpret_cast(m_ptr); } Chris@16: Chris@16: RawPointer pointer() const Chris@16: { return m_ptr; } Chris@16: Chris@16: private: Chris@16: RawPointer m_ptr; Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: inline bool sum_overflows(SizeType a, SizeType b) Chris@16: { return SizeType(-1) - a < b; } Chris@16: Chris@16: //Anti-exception node eraser Chris@16: template Chris@16: class value_eraser Chris@16: { Chris@16: public: Chris@16: value_eraser(Cont & cont, typename Cont::iterator it) Chris@16: : m_cont(cont), m_index_it(it), m_erase(true){} Chris@16: ~value_eraser() Chris@16: { if(m_erase) m_cont.erase(m_index_it); } Chris@16: Chris@16: void release() { m_erase = false; } Chris@16: Chris@16: private: Chris@16: Cont &m_cont; Chris@16: typename Cont::iterator m_index_it; Chris@16: bool m_erase; Chris@16: }; Chris@16: Chris@16: } //namespace interprocess { Chris@16: } //namespace boost { Chris@16: Chris@16: #include Chris@16: Chris@16: #endif //#ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP Chris@16: