utilities.hpp
来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 890 行 · 第 1/2 页
HPP
890 行
////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2005-2008.// (C) Copyright Gennaro Prota 2003 - 2004.//// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/interprocess for documentation.////////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP#define BOOST_INTERPROCESS_DETAIL_UTILITIES_HPP#if (defined _MSC_VER) && (_MSC_VER >= 1200)# pragma once#endif#include <boost/interprocess/detail/config_begin.hpp>#include <boost/interprocess/detail/workaround.hpp>#include <boost/interprocess/interprocess_fwd.hpp>#include <boost/interprocess/detail/move.hpp>#include <boost/type_traits/has_trivial_destructor.hpp>#include <boost/interprocess/detail/min_max.hpp>#include <boost/interprocess/detail/type_traits.hpp>#include <boost/interprocess/detail/iterators.hpp>#include <boost/interprocess/detail/version_type.hpp>#ifndef BOOST_INTERPROCESS_PERFECT_FORWARDING#include <boost/interprocess/detail/preprocessor.hpp>#endif#include <utility>#include <algorithm>namespace boost {namespace interprocess { namespace detail {template<class SmartPtr>struct smart_ptr_type{ typedef typename SmartPtr::value_type value_type; typedef value_type *pointer; static pointer get (const SmartPtr &smartptr) { return smartptr.get();}};template<class T>struct smart_ptr_type<T*>{ typedef T value_type; typedef value_type *pointer; static pointer get (pointer ptr) { return ptr;}};//!Overload for smart pointers to avoid ADL problems with get_pointertemplate<class Ptr>inline typename smart_ptr_type<Ptr>::pointerget_pointer(const Ptr &ptr){ return smart_ptr_type<Ptr>::get(ptr); }//!To avoid ADL problems with swaptemplate <class T>inline void do_swap(T& x, T& y){ using std::swap; swap(x, y);}//!A deleter for scoped_ptr that deallocates the memory//!allocated for an object using a STL allocator.template <class Allocator>struct scoped_ptr_dealloc_functor{ typedef typename Allocator::pointer pointer; typedef detail::integral_constant<unsigned, boost::interprocess::detail:: version<Allocator>::value> alloc_version; typedef detail::integral_constant<unsigned, 1> allocator_v1; typedef detail::integral_constant<unsigned, 2> allocator_v2; private: void priv_deallocate(const typename Allocator::pointer &p, allocator_v1) { m_alloc.deallocate(p, 1); } void priv_deallocate(const typename Allocator::pointer &p, allocator_v2) { m_alloc.deallocate_one(p); } public: Allocator& m_alloc; scoped_ptr_dealloc_functor(Allocator& a) : m_alloc(a) {} void operator()(pointer ptr) { if (ptr) priv_deallocate(ptr, alloc_version()); }};//!A deleter for scoped_ptr that deallocates the memory//!allocated for an object using a STL allocator.template <class Allocator>struct scoped_deallocator{ typedef typename Allocator::pointer pointer; typedef detail::integral_constant<unsigned, boost::interprocess::detail:: version<Allocator>::value> alloc_version; typedef detail::integral_constant<unsigned, 1> allocator_v1; typedef detail::integral_constant<unsigned, 2> allocator_v2; private: void priv_deallocate(allocator_v1) { m_alloc.deallocate(m_ptr, 1); } void priv_deallocate(allocator_v2) { m_alloc.deallocate_one(m_ptr); } scoped_deallocator(const scoped_deallocator &); scoped_deallocator& operator=(const scoped_deallocator &); public: pointer m_ptr; Allocator& m_alloc; scoped_deallocator(pointer p, Allocator& a) : m_ptr(p), m_alloc(a) {} ~scoped_deallocator() { if (m_ptr)priv_deallocate(alloc_version()); } #ifdef BOOST_INTERPROCESS_RVALUE_REFERENCE scoped_deallocator(scoped_deallocator &&o) : m_ptr(o.m_ptr), m_alloc(o.m_alloc) { #else scoped_deallocator(moved_object<scoped_deallocator> mo) : m_ptr(mo.get().m_ptr), m_alloc(mo.get().m_alloc) { scoped_deallocator &o = mo.get(); #endif o.release(); } pointer get() const { return m_ptr; } void release() { m_ptr = 0; }};} //namespace detail {template <class Allocator>struct is_movable<boost::interprocess::detail::scoped_deallocator<Allocator> >{ static const bool value = true;};namespace detail {//!A deleter for scoped_ptr that deallocates the memory//!allocated for an array of objects using a STL allocator.template <class Allocator>struct scoped_array_deallocator{ typedef typename Allocator::pointer pointer; typedef typename Allocator::size_type size_type; scoped_array_deallocator(pointer p, Allocator& a, size_type length) : m_ptr(p), m_alloc(a), m_length(length) {} ~scoped_array_deallocator() { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); } void release() { m_ptr = 0; } private: pointer m_ptr; Allocator& m_alloc; size_type m_length;};template <class Allocator>struct null_scoped_array_deallocator{ typedef typename Allocator::pointer pointer; typedef typename Allocator::size_type size_type; null_scoped_array_deallocator(pointer, Allocator&, size_type) {} void release() {}};//!A deleter for scoped_ptr that destroys//!an object using a STL allocator.template <class Allocator>struct scoped_destructor_n{ typedef typename Allocator::pointer pointer; typedef typename Allocator::value_type value_type; typedef typename Allocator::size_type size_type; pointer m_p; size_type m_n; scoped_destructor_n(pointer p, size_type n) : m_p(p), m_n(n) {} void release() { m_p = 0; } void increment_size(size_type inc) { m_n += inc; } ~scoped_destructor_n() { if(!m_p) return; value_type *raw_ptr = detail::get_pointer(m_p); for(std::size_t i = 0; i < m_n; ++i, ++raw_ptr) raw_ptr->~value_type(); }};//!A deleter for scoped_ptr that destroys//!an object using a STL allocator.template <class Allocator>struct null_scoped_destructor_n{ typedef typename Allocator::pointer pointer; typedef typename Allocator::size_type size_type; null_scoped_destructor_n(pointer, size_type) {} void increment_size(size_type) {} void release() {}};template <class A>class allocator_destroyer{ typedef typename A::value_type value_type; typedef detail::integral_constant<unsigned, boost::interprocess::detail:: version<A>::value> alloc_version; typedef detail::integral_constant<unsigned, 1> allocator_v1; typedef detail::integral_constant<unsigned, 2> allocator_v2; private: A & a_; private: void priv_deallocate(const typename A::pointer &p, allocator_v1) { a_.deallocate(p, 1); } void priv_deallocate(const typename A::pointer &p, allocator_v2) { a_.deallocate_one(p); } public: allocator_destroyer(A &a) : a_(a) {} void operator()(const typename A::pointer &p) { detail::get_pointer(p)->~value_type(); priv_deallocate(p, alloc_version()); }};template <class A>class allocator_destroyer_and_chain_builder{ typedef typename A::value_type value_type; typedef typename A::multiallocation_iterator multiallocation_iterator; typedef typename A::multiallocation_chain multiallocation_chain; A & a_; multiallocation_chain &c_; public: allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c) : a_(a), c_(c) {} void operator()(const typename A::pointer &p) { value_type *vp = detail::get_pointer(p); vp->~value_type(); c_.push_back(vp); }};template <class A>class allocator_multialloc_chain_node_deallocator{ typedef typename A::value_type value_type; typedef typename A::multiallocation_iterator multiallocation_iterator; typedef typename A::multiallocation_chain multiallocation_chain; typedef allocator_destroyer_and_chain_builder<A> chain_builder; A & a_; multiallocation_chain c_; public: allocator_multialloc_chain_node_deallocator(A &a) : a_(a), c_() {} chain_builder get_chain_builder() { return chain_builder(a_, c_); } ~allocator_multialloc_chain_node_deallocator() { multiallocation_iterator it(c_.get_it()); if(it != multiallocation_iterator()) a_.deallocate_individual(it); }};template <class A>class allocator_multialloc_chain_array_deallocator{ typedef typename A::value_type value_type; typedef typename A::multiallocation_iterator multiallocation_iterator; typedef typename A::multiallocation_chain multiallocation_chain; typedef allocator_destroyer_and_chain_builder<A> chain_builder; A & a_; multiallocation_chain c_; public: allocator_multialloc_chain_array_deallocator(A &a) : a_(a), c_() {} chain_builder get_chain_builder() { return chain_builder(a_, c_); } ~allocator_multialloc_chain_array_deallocator() { multiallocation_iterator it(c_.get_it()); if(it != multiallocation_iterator()) a_.deallocate_many(it); }};//!A class used for exception-safe multi-allocation + construction.template <class Allocator>struct multiallocation_destroy_dealloc{ typedef typename Allocator::multiallocation_iterator multiallocation_iterator; typedef typename Allocator::value_type value_type; multiallocation_iterator m_itbeg; Allocator& m_alloc; multiallocation_destroy_dealloc(multiallocation_iterator itbeg, Allocator& a) : m_itbeg(itbeg), m_alloc(a) {} ~multiallocation_destroy_dealloc() { multiallocation_iterator endit; while(m_itbeg != endit){ detail::get_pointer(&*m_itbeg)->~value_type(); m_alloc.deallocate(&*m_itbeg, 1); ++m_itbeg; } } void next() { ++m_itbeg; } void release() { m_itbeg = multiallocation_iterator(); }};//Rounds "orig_size" by excess to round_to bytesinline std::size_t get_rounded_size(std::size_t orig_size, std::size_t round_to){ return ((orig_size-1)/round_to+1)*round_to;}//Truncates "orig_size" to a multiple of "multiple" bytes.inline std::size_t get_truncated_size(std::size_t orig_size, std::size_t multiple){ return orig_size/multiple*multiple;}//Rounds "orig_size" by excess to round_to bytes. round_to must be power of twoinline std::size_t get_rounded_size_po2(std::size_t orig_size, std::size_t round_to){ return ((orig_size-1)&(~(round_to-1))) + round_to;}//Truncates "orig_size" to a multiple of "multiple" bytes. multiple must be power of twoinline std::size_t get_truncated_size_po2(std::size_t orig_size, std::size_t multiple){ return (orig_size & (~(multiple-1)));}template <std::size_t OrigSize, std::size_t RoundTo>struct ct_rounded_size{ enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };};template <std::size_t Value1, std::size_t Value2>struct ct_min{ enum { value = (Value1 < Value2)? Value1 : Value2 };};template <std::size_t Value1, std::size_t Value2>struct ct_max{ enum { value = (Value1 > Value2)? Value1 : Value2 };};// Gennaro Prota wrote this. Thanks!template <int p, int n = 4>struct ct_max_pow2_less{ enum { c = 2*n < p }; static const std::size_t value = c ? (ct_max_pow2_less< c*p, 2*c*n>::value) : n;};template <>struct ct_max_pow2_less<0, 0>{ static const std::size_t value = 0;};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?