heap_allocator_v1.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP
  11. #define BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP
  12. #if defined (_MSC_VER)
  13. # pragma once
  14. #endif
  15. #include <boost/interprocess/detail/config_begin.hpp>
  16. #include <boost/interprocess/detail/workaround.hpp>
  17. #include <boost/intrusive/pointer_traits.hpp>
  18. #include <boost/interprocess/interprocess_fwd.hpp>
  19. #include <boost/interprocess/containers/allocation_type.hpp>
  20. #include <boost/interprocess/detail/utilities.hpp>
  21. #include <boost/interprocess/containers/version_type.hpp>
  22. #include <boost/interprocess/exceptions.hpp>
  23. #include <boost/move/adl_move_swap.hpp>
  24. //!\file
  25. //!Describes an heap_allocator_v1 that allocates portions of fixed size
  26. //!memory buffer (shared memory, mapped file...)
  27. namespace boost {
  28. namespace interprocess {
  29. namespace test {
  30. //!An STL compatible heap_allocator_v1 that uses a segment manager as
  31. //!memory source. The internal pointer type will of the same type (raw, smart) as
  32. //!"typename SegmentManager::void_pointer" type. This allows
  33. //!placing the heap_allocator_v1 in shared memory, memory mapped-files, etc...*/
  34. template<class T, class SegmentManager>
  35. class heap_allocator_v1
  36. {
  37. private:
  38. typedef heap_allocator_v1<T, SegmentManager> self_t;
  39. typedef SegmentManager segment_manager;
  40. typedef typename segment_manager::void_pointer aux_pointer_t;
  41. typedef typename boost::intrusive::
  42. pointer_traits<aux_pointer_t>::template
  43. rebind_pointer<const void>::type cvoid_ptr;
  44. typedef typename boost::intrusive::
  45. pointer_traits<cvoid_ptr>::template
  46. rebind_pointer<segment_manager>::type alloc_ptr_t;
  47. template<class T2, class SegmentManager2>
  48. heap_allocator_v1& operator=(const heap_allocator_v1<T2, SegmentManager2>&);
  49. heap_allocator_v1& operator=(const heap_allocator_v1&);
  50. alloc_ptr_t mp_mngr;
  51. public:
  52. typedef T value_type;
  53. typedef typename boost::intrusive::
  54. pointer_traits<cvoid_ptr>::template
  55. rebind_pointer<T>::type pointer;
  56. typedef typename boost::intrusive::
  57. pointer_traits<cvoid_ptr>::template
  58. rebind_pointer<const T>::type const_pointer;
  59. typedef typename ipcdetail::add_reference
  60. <value_type>::type reference;
  61. typedef typename ipcdetail::add_reference
  62. <const value_type>::type const_reference;
  63. typedef typename SegmentManager::size_type size_type;
  64. typedef typename SegmentManager::difference_type difference_type;
  65. //!Obtains an heap_allocator_v1 of other type
  66. template<class T2>
  67. struct rebind
  68. {
  69. typedef heap_allocator_v1<T2, SegmentManager> other;
  70. };
  71. //!Returns the segment manager. Never throws
  72. segment_manager* get_segment_manager()const
  73. { return ipcdetail::to_raw_pointer(mp_mngr); }
  74. //!Returns address of mutable object. Never throws
  75. pointer address(reference value) const
  76. { return pointer(addressof(value)); }
  77. //!Returns address of non mutable object. Never throws
  78. const_pointer address(const_reference value) const
  79. { return const_pointer(addressof(value)); }
  80. //!Constructor from the segment manager. Never throws
  81. heap_allocator_v1(segment_manager *segment_mngr)
  82. : mp_mngr(segment_mngr) { }
  83. //!Constructor from other heap_allocator_v1. Never throws
  84. heap_allocator_v1(const heap_allocator_v1 &other)
  85. : mp_mngr(other.get_segment_manager()){ }
  86. //!Constructor from related heap_allocator_v1. Never throws
  87. template<class T2>
  88. heap_allocator_v1(const heap_allocator_v1<T2, SegmentManager> &other)
  89. : mp_mngr(other.get_segment_manager()){}
  90. //!Allocates memory for an array of count elements.
  91. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  92. pointer allocate(size_type count, cvoid_ptr hint = 0)
  93. {
  94. (void)hint;
  95. char *raw_mem = ::new char[sizeof(value_type)*count];
  96. return boost::intrusive::pointer_traits<pointer>::pointer_to(reinterpret_cast<value_type &>(*raw_mem));
  97. }
  98. //!Deallocates memory previously allocated. Never throws
  99. void deallocate(const pointer &ptr, size_type)
  100. {
  101. char *ptr_raw = (char*)ipcdetail::to_raw_pointer(ptr);
  102. ::delete[] ptr_raw;
  103. }
  104. //!Construct object, calling constructor.
  105. //!Throws if T(const T&) throws
  106. void construct(const pointer &ptr, const_reference value)
  107. { new((void*)ipcdetail::to_raw_pointer(ptr)) value_type(value); }
  108. //!Destroys object. Throws if object's destructor throws
  109. void destroy(const pointer &ptr)
  110. { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
  111. //!Returns the number of elements that could be allocated. Never throws
  112. size_type max_size() const
  113. { return mp_mngr->get_size(); }
  114. //!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in
  115. //!different memory segments, the result is undefined.
  116. friend void swap(self_t &alloc1, self_t &alloc2)
  117. { ::boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
  118. };
  119. //!Equality test for same type of heap_allocator_v1
  120. template<class T, class SegmentManager> inline
  121. bool operator==(const heap_allocator_v1<T , SegmentManager> &alloc1,
  122. const heap_allocator_v1<T, SegmentManager> &alloc2)
  123. { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
  124. //!Inequality test for same type of heap_allocator_v1
  125. template<class T, class SegmentManager> inline
  126. bool operator!=(const heap_allocator_v1<T, SegmentManager> &alloc1,
  127. const heap_allocator_v1<T, SegmentManager> &alloc2)
  128. { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
  129. } //namespace test {
  130. } //namespace interprocess {
  131. } //namespace boost {
  132. #include <boost/interprocess/detail/config_end.hpp>
  133. #endif //BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP