intersegment_ptr.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 1,042 行 · 第 1/3 页

HPP
1,042
字号
   //!Increments internal   //!offset   void inc_offset(std::ptrdiff_t bytes)   {      this->set_from_pointer(static_cast<char*>(this->get_pointer()) + bytes);   }   //!Decrements internal   //!offset   void dec_offset(std::ptrdiff_t bytes)   {      this->set_from_pointer(static_cast<char*>(this->get_pointer()) - bytes);   }   //////////////////////////////////////   //////////////////////////////////////   //////////////////////////////////////   flat_map_intersegment()      :  intersegment_base()   {}   ~flat_map_intersegment()   {}   private:   class segment_group_t   {      struct segment_data      {         void *addr;         std::size_t size;      };      vector<segment_data> m_segments;      multi_segment_services &m_ms_services;            public:      segment_group_t(multi_segment_services &ms_services)         :  m_ms_services(ms_services)      {}      void push_back(void *addr, std::size_t size)      {         segment_data d = { addr, size };         m_segments.push_back(d);      }      void pop_back()      {         assert(!m_segments.empty());         m_segments.erase(--m_segments.end());      }      void *address_of(std::size_t segment_id)      {         assert(segment_id < (std::size_t)m_segments.size());         return m_segments[segment_id].addr;      }      void clear_segments()      {  m_segments.clear();  }      std::size_t get_size() const      {  return m_segments.size();  }      multi_segment_services &get_multi_segment_services() const      {  return m_ms_services;   }      friend bool operator< (const segment_group_t&l, const segment_group_t &r)      {  return &l.m_ms_services < &r.m_ms_services;   }   };   struct segment_info_t   {      std::size_t size;      std::size_t id;      segment_group_t *group;      segment_info_t()         :  size(0), id(0), group(0)      {}   };   typedef set<segment_group_t>  segment_groups_t;   typedef boost::interprocess::flat_map      <const void *       ,segment_info_t      ,std::less<const void *> >          ptr_to_segment_info_t;   struct mappings_t : Mutex   {      //!Mutex to preserve integrity in multi-threaded      //!enviroments      typedef Mutex        mutex_type;      //!Maps base addresses and segment information       //!(size and segment group and id)*            ptr_to_segment_info_t      m_ptr_to_segment_info;      ~mappings_t()      {         //Check that all mappings have been erased         assert(m_ptr_to_segment_info.empty());      }   };   //Static members   static mappings_t       s_map;   static segment_groups_t s_groups;   public:   typedef segment_group_t*      segment_group_id;   //!Returns the segment and offset   //!of an address   static void get_segment_info_and_offset(const void *ptr, segment_info_t &segment, std::size_t &offset, void *&base)   {      //------------------------------------------------------------------      boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);      //------------------------------------------------------------------      base = 0;      if(s_map.m_ptr_to_segment_info.empty()){         segment = segment_info_t();         offset  = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);         return;      }      //Find the first base address greater than ptr      typename ptr_to_segment_info_t::iterator it          = s_map.m_ptr_to_segment_info.upper_bound(ptr);      if(it == s_map.m_ptr_to_segment_info.begin()){         segment = segment_info_t();         offset  = reinterpret_cast<const char*>(ptr) - static_cast<const char *>(0);      }      //Go to the previous one      --it;      char *      segment_base = const_cast<char*>(reinterpret_cast<const char*>(it->first));      std::size_t segment_size = it->second.size;            if(segment_base <= reinterpret_cast<const char*>(ptr) &&         (segment_base + segment_size) >= reinterpret_cast<const char*>(ptr)){         segment = it->second;         offset  = reinterpret_cast<const char*>(ptr) - segment_base;         base = segment_base;      }      else{         segment = segment_info_t();         offset  = reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);      }   }   //!Associates a segment defined by group/id with a base address and size.   //!Returns false if the group is not found or there is an error   static void insert_mapping(segment_group_id group_id, void *ptr, std::size_t size)   {      //------------------------------------------------------------------      boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);      //------------------------------------------------------------------      typedef typename ptr_to_segment_info_t::value_type value_type;      typedef typename ptr_to_segment_info_t::iterator   iterator;      typedef std::pair<iterator, bool>                  it_b_t;      segment_info_t info;      info.group = group_id;      info.size  = size;      info.id    = group_id->get_size();      it_b_t ret = s_map.m_ptr_to_segment_info.insert(value_type(ptr, info));      assert(ret.second);      value_eraser<ptr_to_segment_info_t> v_eraser(s_map.m_ptr_to_segment_info, ret.first);      group_id->push_back(ptr, size);      v_eraser.release();   }   static bool erase_last_mapping(segment_group_id group_id)   {      //------------------------------------------------------------------      boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);      //------------------------------------------------------------------      if(!group_id->get_size()){         return false;      }      else{         void *addr = group_id->address_of(group_id->get_size()-1);         group_id->pop_back();         std::size_t erased = s_map.m_ptr_to_segment_info.erase(addr);         (void)erased;         assert(erased);         return true;      }   }   static segment_group_id new_segment_group(multi_segment_services *services)   {      {  //------------------------------------------------------------------         boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);         //------------------------------------------------------------------         typedef typename segment_groups_t::iterator iterator;         std::pair<iterator, bool> ret =            s_groups.insert(segment_group_t(*services));         assert(ret.second);         return &*ret.first;      }         }   static bool delete_group(segment_group_id id)   {      {  //------------------------------------------------------------------         boost::interprocess::scoped_lock<typename mappings_t::mutex_type> lock(s_map);         //------------------------------------------------------------------         bool success = 1u == s_groups.erase(segment_group_t(*id));         if(success){            typedef typename ptr_to_segment_info_t::iterator ptr_to_segment_info_it;            ptr_to_segment_info_it it(s_map.m_ptr_to_segment_info.begin());            while(it != s_map.m_ptr_to_segment_info.end()){               if(it->second.group == id){                  it = s_map.m_ptr_to_segment_info.erase(it);               }               else{                  ++it;               }            }         }         return success;      }         }};//!Static map-segment_info associated with//!flat_map_intersegment<>template <class Mutex>typename flat_map_intersegment<Mutex>::mappings_t    flat_map_intersegment<Mutex>::s_map;//!Static segment group container associated with//!flat_map_intersegment<>template <class Mutex>typename flat_map_intersegment<Mutex>::segment_groups_t    flat_map_intersegment<Mutex>::s_groups;//!A smart pointer that can point to a pointee that resides in another memory //!memory mapped or shared memory segment.template <class T>class intersegment_ptr : public flat_map_intersegment<interprocess_mutex>{   typedef flat_map_intersegment<interprocess_mutex> PT;   typedef intersegment_ptr<T>                  self_t;   typedef PT                                      base_t;   void unspecified_bool_type_func() const {}   typedef void (self_t::*unspecified_bool_type)() const;   public:   typedef T *                                     pointer;   typedef typename detail::add_reference<T>::type reference;   typedef T                                       value_type;   typedef std::ptrdiff_t                          difference_type;   typedef std::random_access_iterator_tag         iterator_category;   public:   //Public Functions   //!Constructor from raw pointer (allows "0" pointer conversion).   //!Never throws.   intersegment_ptr(pointer ptr = 0)   {  base_t::set_from_pointer(ptr);   }   //!Constructor from other pointer.   //!Never throws.   template <class U>   intersegment_ptr(U *ptr){  base_t::set_from_pointer(pointer(ptr)); }   //!Constructor from other intersegment_ptr   //!Never throws   intersegment_ptr(const intersegment_ptr& ptr)    {  base_t::set_from_other(ptr);   }   //!Constructor from other intersegment_ptr. If pointers of pointee types are    //!convertible, intersegment_ptrs will be convertibles. Never throws.   template<class T2>   intersegment_ptr(const intersegment_ptr<T2> &ptr)    {  pointer p(ptr.get());   (void)p; base_t::set_from_other(ptr); }   //!Emulates static_cast operator.   //!Never throws.   template<class U>   intersegment_ptr(const intersegment_ptr<U> &r, detail::static_cast_tag)   {  base_t::set_from_pointer(static_cast<T*>(r.get())); }   //!Emulates const_cast operator.   //!Never throws.   template<class U>   intersegment_ptr(const intersegment_ptr<U> &r, detail::const_cast_tag)   {  base_t::set_from_pointer(const_cast<T*>(r.get())); }   //!Emulates dynamic_cast operator.   //!Never throws.   template<class U>   intersegment_ptr(const intersegment_ptr<U> &r, detail::dynamic_cast_tag)   {  base_t::set_from_pointer(dynamic_cast<T*>(r.get())); }   //!Emulates reinterpret_cast operator.   //!Never throws.   template<class U>   intersegment_ptr(const intersegment_ptr<U> &r, detail::reinterpret_cast_tag)   {  base_t::set_from_pointer(reinterpret_cast<T*>(r.get())); }   //!Obtains raw pointer from offset.   //!Never throws.   pointer get()const   {  return static_cast<pointer>(base_t::get_pointer());   }   //!Pointer-like -> operator. It can return 0 pointer.   //!Never throws.   pointer operator->() const              {  return self_t::get(); }   //!Dereferencing operator, if it is a null intersegment_ptr behavior    //!is undefined. Never throws.   reference operator* () const              {  return *(self_t::get());   }   //!Indexing operator.   //!Never throws.   reference operator[](std::ptrdiff_t idx) const      {  return self_t::get()[idx];  }   //!Assignment from pointer (saves extra conversion).   //!Never throws.   intersegment_ptr& operator= (pointer from)   {  base_t::set_from_pointer(from); return *this;  }   //!Assignment from other intersegment_ptr.   //!Never throws.   intersegment_ptr& operator= (const intersegment_ptr &ptr)   {  base_t::set_from_other(ptr);  return *this;  }   //!Assignment from related intersegment_ptr. If pointers of pointee types    //!are assignable, intersegment_ptrs will be assignable. Never throws.   template <class T2>   intersegment_ptr& operator= (const intersegment_ptr<T2> & ptr)   {        pointer p(ptr.get());   (void)p;       base_t::set_from_other(ptr); return *this;      }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?