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 + -
显示快捷键?