allocator_v1.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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_ALLOCATOR_V1_HPP
  11. #define BOOST_INTERPROCESS_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/exceptions.hpp>
  22. #include <boost/move/adl_move_swap.hpp>
  23. #include <boost/static_assert.hpp>
  24. //!\file
  25. //!Describes an 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 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 allocator_v1 in shared memory, memory mapped-files, etc...*/
  34. template<class T, class SegmentManager>
  35. class allocator_v1
  36. {
  37. private:
  38. typedef 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. allocator_v1& operator=(const allocator_v1<T2, SegmentManager2>&);
  49. allocator_v1& operator=(const 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 segment_manager::size_type size_type;
  64. typedef typename segment_manager::difference_type difference_type;
  65. //!Obtains an allocator_v1 of other type
  66. template<class T2>
  67. struct rebind
  68. {
  69. typedef 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. /*
  75. //!Returns address of mutable object. Never throws
  76. pointer address(reference value) const
  77. { return pointer(addressof(value)); }
  78. //!Returns address of non mutable object. Never throws
  79. const_pointer address(const_reference value) const
  80. { return const_pointer(addressof(value)); }
  81. */
  82. //!Constructor from the segment manager. Never throws
  83. allocator_v1(segment_manager *segment_mngr)
  84. : mp_mngr(segment_mngr) { }
  85. //!Constructor from other allocator_v1. Never throws
  86. allocator_v1(const allocator_v1 &other)
  87. : mp_mngr(other.get_segment_manager()){ }
  88. //!Constructor from related allocator_v1. Never throws
  89. template<class T2>
  90. allocator_v1(const allocator_v1<T2, SegmentManager> &other)
  91. : mp_mngr(other.get_segment_manager()){}
  92. //!Allocates memory for an array of count elements.
  93. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  94. pointer allocate(size_type count, cvoid_ptr hint = 0)
  95. {
  96. if(size_overflows<sizeof(T)>(count)){
  97. throw bad_alloc();
  98. }
  99. (void)hint; return pointer(static_cast<T*>(mp_mngr->allocate(count*sizeof(T))));
  100. }
  101. //!Deallocates memory previously allocated. Never throws
  102. void deallocate(const pointer &ptr, size_type)
  103. { mp_mngr->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); }
  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 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 allocator_v1
  120. template<class T, class SegmentManager> inline
  121. bool operator==(const allocator_v1<T , SegmentManager> &alloc1,
  122. const allocator_v1<T, SegmentManager> &alloc2)
  123. { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
  124. //!Inequality test for same type of allocator_v1
  125. template<class T, class SegmentManager> inline
  126. bool operator!=(const allocator_v1<T, SegmentManager> &alloc1,
  127. const 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_ALLOCATOR_V1_HPP