Update of /cvsroot/boost/boost/boost/interprocess
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv22035

Modified Files:
        offset_ptr.hpp segment_manager.hpp shared_memory_object.hpp 
        windows_shared_memory.hpp 
Log Message:
New Interprocess version

Index: offset_ptr.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/offset_ptr.hpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- offset_ptr.hpp      23 Jun 2007 12:53:00 -0000      1.8
+++ offset_ptr.hpp      22 Jul 2007 14:06:03 -0000      1.9
@@ -325,6 +325,7 @@
 }  //namespace interprocess {
 
 /// @cond
+
 //!has_trivial_constructor<> == true_type specialization for optimizations
 template <class T>
 struct has_trivial_constructor< boost::interprocess::offset_ptr<T> > 

Index: segment_manager.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/segment_manager.hpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- segment_manager.hpp 23 Jun 2007 12:53:00 -0000      1.8
+++ segment_manager.hpp 22 Jul 2007 14:06:04 -0000      1.9
@@ -24,7 +24,7 @@
 #include <boost/interprocess/detail/iterators.hpp>
 
 #include <boost/interprocess/detail/mpl.hpp>
-#include <boost/interprocess/detail/basic_segment_manager.hpp>
+#include <boost/interprocess/detail/segment_manager_helper.hpp>
 #include <boost/interprocess/detail/named_proxy.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/offset_ptr.hpp>
@@ -46,284 +46,238 @@
 namespace boost{
 namespace interprocess{
 
-/// @cond
-
-namespace detail{
-
-//Anti-exception node eraser
-template<class Cont>
-class value_eraser
+//!This object is the public base class of segment manager.
+//!This class only depends on the memory allocation algorithm
+//!and implements all the allocation features not related
+//!to named or unique objects.
+//!
+//!Storing a reference to segment_manager forces
+//!the holder class to be dependent on index types and character types.
+//!When such dependence is not desirable and only anonymous and raw
+//!allocations are needed, segment_manager_base is the correct answer.
+template<class MemoryAlgorithm>
+class segment_manager_base
+   :  private MemoryAlgorithm
 {
    public:
-   value_eraser(Cont & cont, typename Cont::iterator it) 
-      : m_cont(cont), m_index_it(it), m_erase(true){}
-   ~value_eraser()  
-   {  if(m_erase) m_cont.erase(m_index_it);  }
-
-   void release() {  m_erase = false;  }
-
-   private:
-   Cont                   &m_cont;
-   typename Cont::iterator m_index_it;
-   bool                    m_erase;
-};
-
-template<class CharT>
-struct intrusive_compare_key
-{
-   typedef CharT char_type;
-
-   intrusive_compare_key(const CharT *str, std::size_t len)
-      :  mp_str(str), m_len(len)
-   {}
-
-   const CharT *  mp_str;
-   std::size_t    m_len;
-};
+   typedef segment_manager_base<MemoryAlgorithm> segment_manager_base_type;
+   typedef typename MemoryAlgorithm::void_pointer  void_pointer;
+   typedef typename MemoryAlgorithm::mutex_family  mutex_family;
+   typedef MemoryAlgorithm memory_algorithm;
+   
+   /// @cond
+   
+   //Experimental. Don't use
+   typedef typename MemoryAlgorithm::multiallocation_iterator 
multiallocation_iterator;
 
-//!This struct indicates an anonymous object creation
-//!allocation
-template<instance_type type>
-class instance_t
-{
-   instance_t(){}
-};
+   /// @endcond
 
-template<class T>
-struct char_if_void
-{
-   typedef T type;
-};
+   //!This constant indicates the payload size
+   //!associated with each allocation of the memory algorithm
+   static const std::size_t PayloadPerAllocation = 
MemoryAlgorithm::PayloadPerAllocation;
 
-template<>
-struct char_if_void<void>
-{
-   typedef char type;
-};
+   //!Constructor of the segment_manager_base
+   //!
+   //!"size" is the size of the memory segment where
+   //!the basic segment manager is being constructed.
+   //!
+   //!"reserved_bytes" is the number of bytes 
+   //!after the end of the memory algorithm object itself
+   //!that the memory algorithm will exclude from
+   //!dynamic allocation
+   //!
+   //!Can throw
+   segment_manager_base(std::size_t size, std::size_t reserved_bytes)
+      :  MemoryAlgorithm(size, reserved_bytes)
+   {
+      assert((sizeof(segment_manager_base<MemoryAlgorithm>) == 
sizeof(MemoryAlgorithm)));
+   }
 
-typedef instance_t<anonymous_type>  anonymous_instance_t;
-typedef instance_t<unique_type>     unique_instance_t;
+   //!Returns the size of the memory
+   //!segment
+   std::size_t get_size() const
+   {  return MemoryAlgorithm::get_size();  }
 
-template<class Hook, class CharType>
-struct intrusive_value_type_impl
-   :  public Hook
-{
-   private:
-   //Non-copyable
-   intrusive_value_type_impl(const intrusive_value_type_impl &);
-   intrusive_value_type_impl& operator=(const intrusive_value_type_impl &);
+   //!Returns the number of free bytes of the memory
+   //!segment
+   std::size_t get_free_memory() const
+   {  return MemoryAlgorithm::get_free_memory();  }
 
-   public:
-   typedef CharType char_type;
+   //!Obtains the minimum size needed by
+   //!the segment manager
+   static std::size_t get_min_size (std::size_t size)
+   {  return MemoryAlgorithm::get_min_size(size);  }
 
-   intrusive_value_type_impl(){}
+   //!Allocates nbytes bytes. This function is only used in 
+   //!single-segment management. Never throws
+   void * allocate (std::size_t nbytes, std::nothrow_t)
+   {  return MemoryAlgorithm::allocate(nbytes);   }
 
-   enum  {  BlockHdrAlignment = detail::alignment_of<block_header>::value  };
+   /// @cond
 
-   block_header *get_block_header() const
+   //Experimental. Dont' use.
+   //!Allocates n_elements of
+   //!elem_size bytes. Throws bad_alloc on failure.
+   multiallocation_iterator allocate_many
+      (std::size_t elem_bytes, std::size_t min_elements, std::size_t 
preferred_elements, std::size_t &received_elements)
    {
-      return (block_header *)(detail::char_ptr_cast(this) +
-         get_rounded_size(sizeof(*this), BlockHdrAlignment));
+      multiallocation_iterator ret = 
MemoryAlgorithm::allocate_many(elem_bytes, min_elements, preferred_elements, 
received_elements);
+      if(!ret) throw bad_alloc();
+      return ret;
    }
 
-   bool operator <(const intrusive_value_type_impl<Hook, CharType> & other) 
const
-   {  return this->get_block_header()->template 
less<CharType>(*other.get_block_header());  }
-
-   bool operator ==(const intrusive_value_type_impl<Hook, CharType> & other) 
const
-   {  return this->get_block_header()->template 
equal<CharType>(*other.get_block_header());  }
-
-   static intrusive_value_type_impl *get_intrusive_value_type(block_header 
*hdr)
+   //!Allocates n_elements, each one of
+   //!element_lenghts[i]*sizeof_element bytes. Throws bad_alloc on failure.
+   multiallocation_iterator allocate_many
+      (const std::size_t *element_lenghts, std::size_t n_elements, std::size_t 
sizeof_element = 1)
    {
-      return (intrusive_value_type_impl *)(detail::char_ptr_cast(hdr) -
-         get_rounded_size(sizeof(intrusive_value_type_impl), 
BlockHdrAlignment));
+      multiallocation_iterator ret = 
MemoryAlgorithm::allocate_many(element_lenghts, n_elements, sizeof_element);
+      if(!ret) throw bad_alloc();
+      return ret;
    }
 
-   CharType *name() const
-   {  return get_block_header()->template name<CharType>(); }
-
-   std::size_t name_length() const
-   {  return get_block_header()->name_length(); }
-
-   void *value() const
-   {  return get_block_header()->value(); }
-};
-
-template<class CharType>
-class char_ptr_holder
-{
-   public:
-   char_ptr_holder(const CharType *name) 
-      : m_name(name)
-   {}
-
-   char_ptr_holder(const detail::anonymous_instance_t *) 
-      : m_name((CharType*)0)
-   {}
-
-   char_ptr_holder(const detail::unique_instance_t *) 
-      : m_name((CharType*)-1)
-   {}
-
-   operator const CharType *()
-   {  return m_name;  }
+   //!Allocates n_elements of
+   //!elem_size bytes. Returns a default constructed iterator on failure.
+   multiallocation_iterator allocate_many(std::size_t elem_size, std::size_t 
min_elements, std::size_t preferred_elements, std::size_t &received_elements, 
std::nothrow_t)
+   {  return MemoryAlgorithm::allocate_many(elem_size, min_elements, 
preferred_elements, received_elements); }
 
-   private:
-   const CharType *m_name;
-};
+   //!Allocates n_elements, each one of
+   //!element_lenghts[i]*sizeof_element bytes.
+   //!Returns a default constructed iterator on failure.
+   multiallocation_iterator allocate_many(const std::size_t *elem_sizes, 
std::size_t n_elements, std::size_t sizeof_element, std::nothrow_t)
+   {  return MemoryAlgorithm::allocate_many(elem_sizes, n_elements, 
sizeof_element); }
 
-//!The key of the the named allocation information index. Stores an offset 
pointer 
-//!to a null terminated string and the length of the string to speed up sorting
-template<class CharT, class VoidPointer>
-struct index_key
-{
-   typedef typename detail::
-      pointer_to_other<VoidPointer, const CharT>::type   const_char_ptr_t;
-   typedef CharT                                         char_type;
+   /// @endcond
 
-   private:
-   //Offset pointer to the object's name
-   const_char_ptr_t  mp_str;
-   //Length of the name buffer (null NOT included)
-   std::size_t       m_len;
-   public:
+   //!Allocates nbytes bytes. Throws boost::interprocess::bad_alloc
+   //!on failure
+   void * allocate(std::size_t nbytes)
+   {  
+      void * ret = MemoryAlgorithm::allocate(nbytes);
+      if(!ret)
+         throw bad_alloc();
+      return ret;
+   }
 
-   //!Constructor of the key
-   index_key (const char_type *name, std::size_t length)
-      : mp_str(name), m_len(length) {}
+   //!Allocates nbytes bytes. This function is only used in 
+   //!single-segment management. Never throws
+   void * allocate_aligned (std::size_t nbytes, std::size_t alignment, 
std::nothrow_t)
+   {  return MemoryAlgorithm::allocate_aligned(nbytes, alignment);   }
 
-   //!Less than function for index ordering
-   bool operator < (const index_key & right) const
-   {
-      return (m_len < right.m_len) || 
-               (m_len == right.m_len && 
-               std::char_traits<char_type>::compare 
-                  (detail::get_pointer(mp_str)
-                  ,detail::get_pointer(right.mp_str), m_len) < 0);
+   //!Allocates nbytes bytes. This function is only used in 
+   //!single-segment management. Throws bad_alloc when fails
+   void * allocate_aligned(std::size_t nbytes, std::size_t alignment)
+   {  
+      void * ret = MemoryAlgorithm::allocate_aligned(nbytes, alignment);
+      if(!ret)
+         throw bad_alloc();
+      return ret;
    }
 
-   //!Equal to function for index ordering
-   bool operator == (const index_key & right) const
+   template<class T>
+   std::pair<T *, bool>
+      allocation_command  (allocation_type command,   std::size_t limit_size,
+                           std::size_t preferred_size,std::size_t 
&received_size,
+                           T *reuse_ptr = 0)
    {
-      return   m_len == right.m_len && 
-               std::char_traits<char_type>::compare 
-                  (detail::get_pointer(mp_str),
-                   detail::get_pointer(right.mp_str), m_len) == 0;
+      std::pair<T *, bool> ret = MemoryAlgorithm::allocation_command
+         ( command | nothrow_allocation, limit_size, preferred_size, 
received_size
+         , reuse_ptr);
+      if(!(command & nothrow_allocation) && !ret.first)
+         throw bad_alloc();
+      return ret;
    }
 
-   void name(const CharT *name)
-   {  mp_str = name; }
-
-   void name_length(std::size_t len)
-   {  m_len = len; }
-
-   const CharT *name() const
-   {  return detail::get_pointer(mp_str); }
-
-   std::size_t name_length() const
-   {  return m_len; }
-};
-
-//!The index_data stores a pointer to a buffer and the element count needed
-//!to know how many destructors must be called when calling destroy
-template<class VoidPointer>
-struct index_data
-{
-   typedef VoidPointer void_ptr;
-   void_ptr    m_ptr;
-   index_data(void *ptr) : m_ptr(ptr){}
-
-   void *value() const
-   {  return (void*)detail::get_pointer(m_ptr);  }
-};
+   //!Deallocates the bytes allocated with allocate/allocate_many()
+   //!pointed by addr
+   void   deallocate          (void *addr)
+   {  MemoryAlgorithm::deallocate(addr);   }
 
-template<class MemoryAlgorithm>
-struct basic_segment_manager_type
-{  typedef basic_segment_manager<MemoryAlgorithm> type;   };
+   //!Increases managed memory in extra_size bytes more. This only works
+   //!with single-segment management*
+   void grow(std::size_t extra_size)
+   {  MemoryAlgorithm::grow(extra_size);   }
 
-template<class CharT, class MemoryAlgorithm>
-struct index_config
-{
-   typedef typename MemoryAlgorithm::void_pointer        void_pointer;
-   typedef CharT                                         char_type;
-   typedef detail::index_key<CharT, void_pointer>        key_type;
-   typedef detail::index_data<void_pointer>              mapped_type;
-   typedef typename basic_segment_manager_type
-      <MemoryAlgorithm>::type                            basic_segment_manager;
+   //!Returns the result of "all_memory_deallocated()" function
+   //!of the used memory algorithm
+   bool all_memory_deallocated()
+   {   return MemoryAlgorithm::all_memory_deallocated(); }
 
-   template<class HeaderBase>
-   struct intrusive_value_type
-   {  typedef detail::intrusive_value_type_impl<HeaderBase, CharT>  type; };
+   //!Returns the result of "check_sanity()" function
+   //!of the used memory algorithm
+   bool check_sanity()
+   {   return MemoryAlgorithm::check_sanity(); }
 
-   typedef intrusive_compare_key<CharT>            intrusive_compare_key_type;
-};
+   //!Writes to zero free memory (memory not yet allocated) of the memory 
algorithm
+   void zero_free_memory()
+   {   MemoryAlgorithm::zero_free_memory(); }
 
-template<class Iterator, bool intrusive>
-class iterator_value_adaptor
-{
-   typedef typename Iterator::value_type        iterator_val_t;
-   typedef typename iterator_val_t::char_type   char_type;
+   /// @cond
+   protected:
+   void * prot_anonymous_construct
+      (std::size_t num, bool dothrow, detail::in_place_interface &table)
+   {
+      typedef detail::block_header block_header_t;
+      block_header_t block_info (  table.size*num
+                                 , table.alignment
+                                 , anonymous_type
+                                 , 1
+                                 , 0);
 
-   public:
-   iterator_value_adaptor(const typename Iterator::value_type &val)
-      :  m_val(&val)
-   {}
+      //Allocate memory
+      void *ptr_struct = this->allocate(block_info.total_size(), 
std::nothrow_t());
 
-   const char_type *name() const
-   {  return m_val->name(); }
+      //Check if there is enough memory
+      if(!ptr_struct){
+         if(dothrow){
+            throw bad_alloc();
+         }
+         else{
+            return 0; 
+         }
+      }
 
-   std::size_t name_length() const
-   {  return m_val->name_length(); }
+      //Build scoped ptr to avoid leaks with constructor exception
+      detail::mem_algo_deallocator<MemoryAlgorithm> mem(ptr_struct, *this);
 
-   const void *value() const
-   {  return m_val->value(); }
+      //Now construct the header
+      block_header_t * hdr = new(ptr_struct) block_header_t(block_info);
+      void *ptr = hdr->value();
 
-   const typename Iterator::value_type *m_val;
-};
+      //Now call constructors
+      detail::array_construct(ptr, num, table);
 
+      //All constructors successful, we don't want erase memory
+      mem.release();
+      return ptr;
+   }
 
-template<class Iterator>
-class iterator_value_adaptor<Iterator, false>
-{
-   typedef typename Iterator::value_type        iterator_val_t;
-   typedef typename iterator_val_t::first_type  first_type;
-   typedef typename iterator_val_t::second_type second_type;
-   typedef typename first_type::char_type       char_type;
+   //!Calls the destructor and makes an anonymous deallocate
+   void prot_anonymous_destroy(const void *object, detail::in_place_interface 
&table)
+   {
 
-   public:
-   iterator_value_adaptor(const typename Iterator::value_type &val)
-      :  m_val(&val)
-   {}
+      //Get control data from associated with this object    
+      typedef detail::block_header block_header_t;
+      block_header_t *ctrl_data = 
block_header_t::block_header_from_value(object, table.size, table.alignment);
 
-   const char_type *name() const
-   {  return m_val->first.name(); }
+      //-------------------------------
+      //boost::interprocess::scoped_lock<rmutex> guard(m_header);
+      //-------------------------------
 
-   std::size_t name_length() const
-   {  return m_val->first.name_length(); }
+      if(ctrl_data->allocation_type() != anonymous_type){
+         //This is not an anonymous object, the pointer is wrong!
+         assert(0);
+      }
 
-   const void *value() const
-   {
-      return reinterpret_cast<block_header*>
-         (detail::get_pointer(m_val->second.m_ptr))->value();
+      //Call destructors and free memory
+      //Build scoped ptr to avoid leaks with destructor exception
+      std::size_t destroyed = 0;
+      table.destroy_n((void*)object, ctrl_data->m_value_bytes/table.size, 
destroyed);
+      this->deallocate(ctrl_data);
    }
-
-   const typename Iterator::value_type *m_val;
-};
-
-template<class Iterator, bool intrusive>
-struct iterator_transform
-   :  std::unary_function< typename Iterator::value_type
-                         , iterator_value_adaptor<Iterator, intrusive> >
-{
-   typedef iterator_value_adaptor<Iterator, intrusive> result_type;
-   
-   result_type operator()(const typename Iterator::value_type &arg) const
-   {  return result_type(arg); }
+   /// @endcond
 };
 
-}  //namespace detail{
-
-/// @endcond
-
 //These pointers are the ones the user will use to 
 //indicate previous allocation types
 static const detail::anonymous_instance_t   * anonymous_instance = 0;
@@ -340,26 +294,35 @@
 //!The second index contains the association for unique instances. The key will
 //!be the const char * returned from type_info.name() function for the unique
 //!type to be constructed.
+//!
+//!segment_manager<CharType, MemoryAlgorithm, IndexType> inherits publicly
+//!from segment_manager_base<MemoryAlgorithm> and inherits from it
+//!many public functions related to anonymous object and raw memory allocation.
+//!See segment_manager_base reference to know about those functions.
 template<class CharType
         ,class MemoryAlgorithm
         ,template<class IndexConfig> class IndexType>
 class segment_manager
-   :  private detail::basic_segment_manager<MemoryAlgorithm>
+   :  public segment_manager_base<MemoryAlgorithm>
 { 
    /// @cond
    //Non-copyable
    segment_manager();
    segment_manager(const segment_manager &);
    segment_manager &operator=(const segment_manager &);
-   typedef detail::basic_segment_manager<MemoryAlgorithm> Base;
+   typedef segment_manager_base<MemoryAlgorithm> Base;
    typedef detail::block_header block_header_t;
    /// @endcond
 
    public:
+   typedef MemoryAlgorithm                memory_algorithm;
    typedef typename Base::void_pointer    void_pointer;
    typedef CharType                       char_type;
+   typedef typename Base::multiallocation_iterator   multiallocation_iterator;
 
-   enum {   PayloadPerAllocation = Base::PayloadPerAllocation };
+   typedef segment_manager_base<MemoryAlgorithm>   segment_manager_base_type;
+
+   static const std::size_t PayloadPerAllocation = Base::PayloadPerAllocation;
 
    /// @cond
    private:
@@ -373,11 +336,11 @@
    typedef IndexType<index_config_named>                    named_index_t;
    typedef IndexType<index_config_unique>                   unique_index_t;
    typedef detail::char_ptr_holder<CharType>                char_ptr_holder_t;
-   typedef detail::iterator_transform
+   typedef detail::segment_manager_iterator_transform
       <typename named_index_t::const_iterator
       ,is_intrusive_index<index_type>::value>   named_transform;
 
-   typedef detail::iterator_transform
+   typedef detail::segment_manager_iterator_transform
       <typename unique_index_t::const_iterator
       ,is_intrusive_index<index_type>::value>   unique_transform;
    /// @endcond
@@ -389,28 +352,36 @@
    typedef transform_iterator
       <typename unique_index_t::const_iterator, unique_transform> 
const_unique_iterator;
 
+   /// @cond
+
    //!Constructor proxy object definition helper class
    template<class T>
    struct construct_proxy
    {
-      typedef detail::named_proxy<segment_manager, T, true>   type;
+      typedef detail::named_proxy<segment_manager, T, false>   type;
    };
 
    //!Constructor proxy object definition helper class
    template<class T>
    struct construct_iter_proxy
    {
-      typedef detail::named_proxy<segment_manager, T, false>   type;
+      typedef detail::named_proxy<segment_manager, T, true>   type;
    };
 
-   //!Constructor. Can throw
+   /// @endcond
+
+   //!Constructor of the segment manager
+   //!"size" is the size of the memory segment where
+   //!the segment manager is being constructed.
+   //!Can throw
    segment_manager(std::size_t size)
       :  Base(size, priv_get_reserved_bytes())
       ,  m_header(static_cast<Base*>(get_this_pointer()))
    {  (void) anonymous_instance;   (void) unique_instance;   }
 
-   //!Tries to find a previous named allocation address. Returns a memory
-   //!buffer and the object count.
+   //!Tries to find a previous named allocation. Returns the address
+   //!and the object count. On failure the first member of the
+   //!returned pair is 0.
    template <class T>
    std::pair<T*, std::size_t> find  (const CharType* name)
    {  
@@ -429,6 +400,9 @@
       return std::pair<T*, std::size_t>(static_cast<T*>(ret), size);
    }
 
+   //!Tries to find a previous unique allocation. Returns the address
+   //!and the object count. On failure the first member of the
+   //!returned pair is 0.
    template <class T>
    std::pair<T*, std::size_t> find (const detail::unique_instance_t* name)
    {
@@ -469,7 +443,7 @@
    template <class T>
    typename construct_iter_proxy<T>::type     
       construct_it(char_ptr_holder_t name)
-   {  return construct_iter_proxy<T>::type (this, name, false, true);  }
+   {  return typename construct_iter_proxy<T>::type (this, name, false, true); 
 }
 
    //!Returns throwing "search or construct from iterators"
    //!proxy object
@@ -499,8 +473,8 @@
    void atomic_func(Func &f)
    {  boost::interprocess::scoped_lock<rmutex> guard(m_header);  f();  }
 
-   //!Calls the destructor and makes an unique
-   //!deallocate
+   //!Destroys a previously created unique instance.
+   //!Returns false if the object was not present.
    template <class T>
    bool destroy(const detail::unique_instance_t *)
    {
@@ -509,6 +483,8 @@
          (typeid(T).name(), m_header.m_unique_index, dtor, is_intrusive_t());
    }
 
+   //!Destroys the named object with
+   //!the given name. Returns false if that object can't be found.
    template <class T>
    bool destroy(const CharType *name)
    {
@@ -517,41 +493,34 @@
                (name, m_header.m_named_index, dtor, is_intrusive_t());
    }
 
+   //!Destroys an anonymous, unique or named object
+   //!using it's address
    template <class T>
-   bool destroy_ptr(const T *p)
+   void destroy_ptr(const T *p)
    {
       //If T is void transform it to char
       typedef typename detail::char_if_void<T>::type data_t;
       detail::placement_destroy<data_t> dtor;
-      return priv_destroy_ptr(p, dtor);
+      priv_destroy_ptr(p, dtor);
    }
 
    //!Returns the name of an object created with construct/find_or_construct
    //!functions. Does not throw
    template<class T>
-   const CharType *get_name(const T *ptr)
-   {
-      //Get header
-      block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr);
-      CharType *name = static_cast<CharType*>(ctrl_data->template 
name<CharType>());
-   
-      //Sanity checks
-      assert(ctrl_data->sizeof_char() == sizeof(CharType));
-      assert(ctrl_data->m_num_char == 
std::char_traits<CharType>::length(name));
+   static const CharType *get_instance_name(const T *ptr)
+   { return 
priv_get_instance_name(block_header_t::block_header_from_value(ptr));  }
 
-      return name;
-   }
+   //!Returns the length of an object created with construct/find_or_construct
+   //!functions. Does not throw.
+   template<class T>
+   static std::size_t get_instance_length(const T *ptr)
+   {  return 
priv_get_instance_length(block_header_t::block_header_from_value(ptr), 
sizeof(T));  }
 
    //!Returns is the the name of an object created with 
construct/find_or_construct
    //!functions. Does not throw
    template<class T>
-   detail::instance_type get_type(const T *ptr)
-   {
-      //Get header
-      block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr);
-      assert((detail::instance_type)ctrl_data->allocation_type() < 
detail::max_allocation_type);
-      return (detail::instance_type)ctrl_data->allocation_type();
-   }
+   static instance_type get_instance_type(const T *ptr)
+   {  return 
priv_get_instance_type(block_header_t::block_header_from_value(ptr));  }
 
    //!Preallocates needed index resources to optimize the 
    //!creation of "num" named objects in the managed memory segment.
@@ -575,6 +544,17 @@
       m_header.m_unique_index.reserve(num);
    }
 
+   //!Calls shrink_to_fit in both named and unique object indexes
+   //!to try to free unused memory from those indexes.
+   void shrink_to_fit_indexes()
+   {  
+      //-------------------------------
+      boost::interprocess::scoped_lock<rmutex> guard(m_header);
+      //-------------------------------
+      m_header.m_named_index.shrink_to_fit();  
+      m_header.m_unique_index.shrink_to_fit();  
+   }
+
    //!Returns the number of named objects stored in
    //!the segment.
    std::size_t get_num_named_objects()
@@ -595,77 +575,13 @@
       return m_header.m_unique_index.size();  
    }
 
-   //!Returns the size of the memory
-   //!segment
-   std::size_t get_size() const
-   {  return Base::get_size();  }
-
-   //!Returns the number of free bytes of the memory
-   //!segment
-   std::size_t get_free_memory() const
-   {  return Base::get_free_memory();  }
-
    //!Obtains the minimum size needed by the
    //!segment manager
    static std::size_t get_min_size()
    {  return Base::get_min_size(priv_get_reserved_bytes());  }
 
-   //!Allocates nbytes bytes. Throws boost::interprocess::bad_alloc
-   //!when it can allocate
-   void * allocate(std::size_t nbytes)
-   {  return Base::allocate(nbytes);   }
-
-   //!Allocates nbytes bytes. This function is only used in 
-   //!single-segment management. Never throws
-   void * allocate (std::size_t nbytes, std::nothrow_t nothrow)
-   {  return Base::allocate(nbytes, nothrow);   }
-
-   //!Allocates aligned bytes, returns 0 if there is not more memory.
-   //!Alignment must be power of 2
-   void* allocate_aligned     (std::size_t nbytes, std::size_t alignment)
-   {  return Base::allocate_aligned(nbytes, alignment);  }
-
-   //!Allocates aligned bytes, throws bad_alloc when
-   //!it can allocate. Alignment must be power of 2
-   void* allocate_aligned     (std::size_t nbytes, std::size_t alignment, 
std::nothrow_t nothrow)
-   {  return Base::allocate_aligned(nbytes, alignment, nothrow);  }
-
-   std::pair<void *, bool>
-      allocation_command  (allocation_type command,   std::size_t limit_size,
-                           std::size_t preferred_size,std::size_t 
&received_size,
-                           void *reuse_ptr = 0, std::size_t backwards_multiple 
= 1)
-   {  
-      return Base::allocation_command
-         (command, limit_size, preferred_size, received_size, reuse_ptr, 
backwards_multiple);
-   }
-
-   //!Deallocates the bytes allocated with allocate/allocate_at_least()
-   //!pointed by addr
-   void   deallocate          (void *addr)
-   {  Base::deallocate(addr);   }
-
-   //!Increases managed memory in extra_size bytes more. This only works
-   //!with single-segment management
-   void grow(std::size_t extra_size)
-   {  Base::grow(extra_size);   }
-
-   //!Returns the result of "all_memory_deallocated()" function
-   //!of the used memory algorithm
-   bool all_memory_deallocated()
-   {   return Base::all_memory_deallocated(); }
-
-   //!Returns the result of "check_sanity()" function
-   //!of the used memory algorithm
-   bool check_sanity()
-   {   return Base::check_sanity(); }
-
-   //!Writes to zero free memory (memory not yet allocated) of
-   //!the memory algorithm
-   void zero_free_memory()
-   {   Base::zero_free_memory(); }
-
    //!Returns a constant iterator to the beginning of the information about
-   //the named allocations performed in this segment manager
+   //!the named allocations performed in this segment manager
    const_named_iterator named_begin() const
    {
       return make_transform_iterator
@@ -673,7 +589,7 @@
    }
 
    //!Returns a constant iterator to the end of the information about
-   //the named allocations performed in this segment manager
+   //!the named allocations performed in this segment manager
    const_named_iterator named_end() const
    {
       return make_transform_iterator
@@ -681,7 +597,7 @@
    }
 
    //!Returns a constant iterator to the beginning of the information about
-   //the unique allocations performed in this segment manager
+   //!the unique allocations performed in this segment manager
    const_unique_iterator unique_begin() const
    {
       return make_transform_iterator
@@ -689,7 +605,7 @@
    }
 
    //!Returns a constant iterator to the end of the information about
-   //the unique allocations performed in this segment manager
+   //!the unique allocations performed in this segment manager
    const_unique_iterator unique_end() const
    {
       return make_transform_iterator
@@ -732,40 +648,72 @@
       }
       else if(name == reinterpret_cast<const CharType*>(-1)){
          ret = this->priv_generic_named_construct<char>
-            (detail::unique_type, table.type_name, num, try2find, dothrow, 
table, m_header.m_unique_index, is_intrusive_t());
+            (unique_type, table.type_name, num, try2find, dothrow, table, 
m_header.m_unique_index, is_intrusive_t());
       }
       else{
          ret = this->priv_generic_named_construct<CharType>
-            (detail::named_type, name, num, try2find, dothrow, table, 
m_header.m_named_index, is_intrusive_t());
+            (named_type, name, num, try2find, dothrow, table, 
m_header.m_named_index, is_intrusive_t());
       }
       return ret;
    }
 
-   bool priv_destroy_ptr(const void *ptr, detail::in_place_interface &dtor)
+   void priv_destroy_ptr(const void *ptr, detail::in_place_interface &dtor)
    {
       block_header_t *ctrl_data = block_header_t::block_header_from_value(ptr, 
dtor.size, dtor.alignment);
       switch(ctrl_data->allocation_type()){
-         case detail::anonymous_type:
-            return this->prot_anonymous_destroy(ptr, dtor);
+         case anonymous_type:
+            this->prot_anonymous_destroy(ptr, dtor);
          break;
 
-         case detail::named_type:
-            return this->priv_generic_named_destroy<CharType>
+         case named_type:
+            this->priv_generic_named_destroy<CharType>
                (ctrl_data, m_header.m_named_index, dtor, is_node_index_t());
          break;
 
-         case detail::unique_type:
-            return this->priv_generic_named_destroy<char>
+         case unique_type:
+            this->priv_generic_named_destroy<char>
                (ctrl_data, m_header.m_unique_index, dtor, is_node_index_t());
          break;
 
          default:
             //This type is unknown, bad pointer passed to this function!
             assert(0);
-            return false;
          break;
       }
-      return false;
+   }
+
+   //!Returns the name of an object created with construct/find_or_construct
+   //!functions. Does not throw
+   static const CharType *priv_get_instance_name(block_header_t *ctrl_data)
+   {
+      allocation_type type = ctrl_data->allocation_type();
+      if(type != named_type){
+         assert((type == anonymous_type && ctrl_data->m_num_char == 0) ||
+                (type == unique_type    && ctrl_data->m_num_char != 0) );
+         return 0;
+      }
+      CharType *name = static_cast<CharType*>(ctrl_data->template 
name<CharType>());
+   
+      //Sanity checks
+      assert(ctrl_data->sizeof_char() == sizeof(CharType));
+      assert(ctrl_data->m_num_char == 
std::char_traits<CharType>::length(name));
+      return name;
+   }
+
+   static std::size_t priv_get_instance_length(block_header_t *ctrl_data, 
std::size_t sizeofvalue)
+   {
+      //Get header
+      assert((ctrl_data->value_bytes() %sizeofvalue) == 0);
+      return ctrl_data->value_bytes()/sizeofvalue;
+   }
+
+   //!Returns is the the name of an object created with 
construct/find_or_construct
+   //!functions. Does not throw
+   static instance_type priv_get_instance_type(block_header_t *ctrl_data)
+   {
+      //Get header
+      assert((instance_type)ctrl_data->allocation_type() < 
max_allocation_type);
+      return (instance_type)ctrl_data->allocation_type();
    }
 
    static std::size_t priv_get_reserved_bytes()
@@ -1113,8 +1061,8 @@
       
       //Avoid constructions if constructor is trivial
       //Build scoped ptr to avoid leaks with constructor exception
-      detail::mem_algo_deallocator<MemoryAlgorithm> mem
-         (buffer_ptr, this->memory_algorithm());
+      detail::mem_algo_deallocator<segment_manager_base_type> mem
+         (buffer_ptr, *static_cast<segment_manager_base_type*>(this));
 
       //Construct array, this can throw
       detail::array_construct(ptr, num, table);
@@ -1241,8 +1189,8 @@
       it->second.m_ptr  = hdr;
 
       //Build scoped ptr to avoid leaks with constructor exception
-      detail::mem_algo_deallocator<MemoryAlgorithm> mem
-         (buffer_ptr, this->memory_algorithm());
+      detail::mem_algo_deallocator<segment_manager_base_type> mem
+         (buffer_ptr, *static_cast<segment_manager_base_type*>(this));
 
       //Construct array, this can throw
       detail::array_construct(ptr, num, table);

Index: shared_memory_object.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/shared_memory_object.hpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- shared_memory_object.hpp    23 Jun 2007 12:53:00 -0000      1.5
+++ shared_memory_object.hpp    22 Jul 2007 14:06:04 -0000      1.6
@@ -13,9 +13,8 @@
 
 #include <boost/interprocess/detail/config_begin.hpp>
 #include <boost/interprocess/detail/workaround.hpp>
-#include <boost/interprocess/detail/creation_tags.hpp>
+#include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/exceptions.hpp>
-//#include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/move.hpp>
 #include <boost/interprocess/interprocess_fwd.hpp>
 #include <boost/interprocess/exceptions.hpp>
@@ -34,15 +33,14 @@
 #  include<boost/interprocess/detail/os_file_functions.hpp>
 #endif
 
-/*!\file
-   Describes a shared memory object management class.
-*/
+//!\file
+//!Describes a shared memory object management class.
 
 namespace boost {
 namespace interprocess {
 
-/*!A class that wraps a shared memory mapping that can be used to
-   create mapped regions from the mapped files*/
+//!A class that wraps a shared memory mapping that can be used to
+//!create mapped regions from the mapped files
 class shared_memory_object
 {
    /// @cond
@@ -58,19 +56,19 @@
 
    //!Creates a shared memory object with name "name" and mode "mode", with 
the access mode "mode"
    //!If the file previously exists, throws an error.*/
-   shared_memory_object(detail::create_only_t, const char *name, mode_t mode)
-   {  this->priv_open_or_create(DoCreate, name, mode);  }
+   shared_memory_object(create_only_t, const char *name, mode_t mode)
+   {  this->priv_open_or_create(detail::DoCreate, name, mode);  }
 
    //!Tries to create a shared memory object with name "name" and mode "mode", 
with the
    //!access mode "mode". If the file previously exists, it tries to open it 
with mode "mode".
    //!Otherwise throws an error.
-   shared_memory_object(detail::open_or_create_t, const char *name, mode_t 
mode)
-   {  this->priv_open_or_create(DoCreateOrOpen, name, mode);  }
+   shared_memory_object(open_or_create_t, const char *name, mode_t mode)
+   {  this->priv_open_or_create(detail::DoCreateOrOpen, name, mode);  }
 
    //!Tries to open a shared memory object with name "name", with the access 
mode "mode". 
    //!If the file does not previously exist, it throws an error.
-   shared_memory_object(detail::open_only_t, const char *name, mode_t mode)
-   {  this->priv_open_or_create(DoOpen, name, mode);  }
+   shared_memory_object(open_only_t, const char *name, mode_t mode)
+   {  this->priv_open_or_create(detail::DoOpen, name, mode);  }
 
    //!Moves the ownership of "moved"'s shared memory object to *this. 
    //!After the call, "moved" does not represent any shared memory object. 
@@ -134,7 +132,7 @@
    void priv_close();
 
    //!Closes a previously opened file mapping. Never throws.
-   bool priv_open_or_create(create_enum_t type, const char *filename, mode_t 
mode);
+   bool priv_open_or_create(detail::create_enum_t type, const char *filename, 
mode_t mode);
 
    file_handle_t  m_handle;
    mode_t         m_mode;
@@ -169,7 +167,7 @@
 #if !defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
 
 inline bool shared_memory_object::priv_open_or_create
-   (create_enum_t type, const char *filename, mode_t mode)
+   (detail::create_enum_t type, const char *filename, mode_t mode)
 {
    m_filename = filename;
 
@@ -203,13 +201,13 @@
    }
 
    switch(type){
-      case DoOpen:
+      case detail::DoOpen:
          m_handle = detail::open_existing_file(shmfile.c_str(), mode, true);
       break;
-      case DoCreate:
+      case detail::DoCreate:
          m_handle = detail::create_new_file(shmfile.c_str(), mode, true);
       break;
-      case DoCreateOrOpen:
+      case detail::DoCreateOrOpen:
          m_handle = detail::create_or_open_file(shmfile.c_str(), mode, true);
       break;
       default:
@@ -272,7 +270,7 @@
 #else //!defined(BOOST_INTERPROCESS_POSIX_SHARED_MEMORY_OBJECTS)
 
 inline bool shared_memory_object::priv_open_or_create
-   (create_enum_t type, 
+   (detail::create_enum_t type, 
     const char *filename,
     mode_t mode)
 {
@@ -298,13 +296,13 @@
    }
 
    switch(type){
-      case DoOpen:
+      case detail::DoOpen:
          //No addition
       break;
-      case DoCreate:
+      case detail::DoCreate:
          oflag |= (O_CREAT | O_EXCL);
       break;
-      case DoCreateOrOpen:
+      case detail::DoCreateOrOpen:
          oflag |= O_CREAT;
       break;
       default:

Index: windows_shared_memory.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/interprocess/windows_shared_memory.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- windows_shared_memory.hpp   23 Jun 2007 12:53:54 -0000      1.4
+++ windows_shared_memory.hpp   22 Jul 2007 14:06:04 -0000      1.5
@@ -15,9 +15,11 @@
 #include <boost/interprocess/detail/workaround.hpp>
 #include <boost/detail/workaround.hpp>
 
-#if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
+#if !defined(BOOST_WINDOWS) || defined(BOOST_DISABLE_WIN32)
+#error "This header can only be used in Windows operating systems"
+#endif
 
-#include <boost/interprocess/detail/creation_tags.hpp>
+#include <boost/interprocess/creation_tags.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/os_file_functions.hpp>
@@ -28,24 +30,23 @@
 #include <boost/cstdint.hpp>
 #include <string>
 
-/*!\file
-   Describes a class representing a native windows shared memory.
-*/
+//!\file
+//!Describes a class representing a native windows shared memory.
 
 namespace boost {
 namespace interprocess {
 
-/*!A class that wraps the native Windows shared memory
-   that is implemented as a file mapping of the paging file.
-   Unlike shared_memory_object, windows_shared_memory has
-   no kernel persistence and the shared memory is destroyed
-   when all processes destroy all their windows_shared_memory
-   objects and mapped regions for the same shared memory
-   or the processes end/crash.
-   
-   Warning: Windows native shared memory and interprocess portable
-   shared memory can't communicate between them.
-   */
+//!A class that wraps the native Windows shared memory
+//!that is implemented as a file mapping of the paging file.
+//!Unlike shared_memory_object, windows_shared_memory has
+//!no kernel persistence and the shared memory is destroyed
+//!when all processes destroy all their windows_shared_memory
+//!objects and mapped regions for the same shared memory
+//!or the processes end/crash.
+//!
+//!Warning: Windows native shared memory and interprocess portable
+//!shared memory (boost::interprocess::shared_memory_object)
+//!can't communicate between them.
 class windows_shared_memory
 {
    /// @cond
@@ -61,19 +62,19 @@
    //!Creates a new native shared memory with name "name" and mode "mode",
    //!with the access mode "mode".
    //!If the file previously exists, throws an error.
-   windows_shared_memory(detail::create_only_t, const char *name, mode_t mode, 
std::size_t size)
-   {  this->priv_open_or_create(DoCreate, name, mode, size);  }
+   windows_shared_memory(create_only_t, const char *name, mode_t mode, 
std::size_t size)
+   {  this->priv_open_or_create(detail::DoCreate, name, mode, size);  }
 
    //!Tries to create a shared memory object with name "name" and mode "mode", 
with the
    //!access mode "mode". If the file previously exists, it tries to open it 
with mode "mode".
    //!Otherwise throws an error.
-   windows_shared_memory(detail::open_or_create_t, const char *name, mode_t 
mode, std::size_t size)
-   {  this->priv_open_or_create(DoCreateOrOpen, name, mode, size);  }
+   windows_shared_memory(open_or_create_t, const char *name, mode_t mode, 
std::size_t size)
+   {  this->priv_open_or_create(detail::DoCreateOrOpen, name, mode, size);  }
 
    //!Tries to open a shared memory object with name "name", with the access 
mode "mode". 
    //!If the file does not previously exist, it throws an error.
-   windows_shared_memory(detail::open_only_t, const char *name, mode_t mode)
-   {  this->priv_open_or_create(DoOpen, name, mode, 0);  }
+   windows_shared_memory(open_only_t, const char *name, mode_t mode)
+   {  this->priv_open_or_create(detail::DoOpen, name, mode, 0);  }
 
    //!Moves the ownership of "moved"'s shared memory object to *this. 
    //!After the call, "moved" does not represent any shared memory object. 
@@ -132,7 +133,7 @@
    void priv_close();
 
    //!Closes a previously opened file mapping. Never throws.
-   bool priv_open_or_create(create_enum_t type, const char *filename, mode_t 
mode, std::size_t size);
+   bool priv_open_or_create(detail::create_enum_t type, const char *filename, 
mode_t mode, std::size_t size);
 
    void *         m_handle;
    mode_t         m_mode;
@@ -164,7 +165,7 @@
 {  return m_mode; }
 
 inline bool windows_shared_memory::priv_open_or_create
-   (create_enum_t type, const char *filename, mode_t mode, std::size_t size)
+   (detail::create_enum_t type, const char *filename, mode_t mode, std::size_t 
size)
 {
    m_name = filename;
 
@@ -194,12 +195,12 @@
    }
 
    switch(type){
-      case DoOpen:
+      case detail::DoOpen:
          m_handle = winapi::open_file_mapping
             (map_access, filename);
       break;
-      case DoCreate:
-      case DoCreateOrOpen:
+      case detail::DoCreate:
+      case detail::DoCreateOrOpen:
       {
          __int64 s = size;
          unsigned long high_size(s >> 32), low_size((boost::uint32_t)s);
@@ -214,7 +215,7 @@
          }
    }
 
-   if(!m_handle || (type == DoCreate && winapi::get_last_error() == 
winapi::error_already_exists)){
+   if(!m_handle || (type == detail::DoCreate && winapi::get_last_error() == 
winapi::error_already_exists)){
       error_info err = system_error_code();
       this->priv_close();
       throw interprocess_exception(err);
@@ -235,10 +236,6 @@
 }  //namespace interprocess {
 }  //namespace boost {
 
-#else
-#error "This header can only be used in Windows operating systems"
-#endif
-
 #include <boost/interprocess/detail/config_end.hpp>
 
 #endif   //BOOST_INTERPROCESS_WINDOWS_SHARED_MEMORY_HPP


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs

Reply via email to