/Src/Dependencies/Boost/boost/interprocess/allocators/allocator.hpp

http://hadesmem.googlecode.com/ · C++ Header · 305 lines · 151 code · 55 blank · 99 comment · 5 complexity · f2d1a2518f1fdb93c8f52c45bba141eb MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2009. 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_HPP
  11. #define BOOST_INTERPROCESS_ALLOCATOR_HPP
  12. #if (defined _MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif
  15. #include <boost/interprocess/detail/config_begin.hpp>
  16. #include <boost/interprocess/detail/workaround.hpp>
  17. #include <boost/pointer_to_other.hpp>
  18. #include <boost/interprocess/interprocess_fwd.hpp>
  19. #include <boost/interprocess/containers/allocation_type.hpp>
  20. #include <boost/interprocess/containers/container/detail/multiallocation_chain.hpp>
  21. #include <boost/interprocess/allocators/detail/allocator_common.hpp>
  22. #include <boost/interprocess/detail/utilities.hpp>
  23. #include <boost/interprocess/containers/version_type.hpp>
  24. #include <boost/interprocess/exceptions.hpp>
  25. #include <boost/assert.hpp>
  26. #include <boost/utility/addressof.hpp>
  27. #include <boost/interprocess/detail/type_traits.hpp>
  28. #include <memory>
  29. #include <algorithm>
  30. #include <cstddef>
  31. #include <stdexcept>
  32. //!\file
  33. //!Describes an allocator that allocates portions of fixed size
  34. //!memory buffer (shared memory, mapped file...)
  35. namespace boost {
  36. namespace interprocess {
  37. //!An STL compatible allocator that uses a segment manager as
  38. //!memory source. The internal pointer type will of the same type (raw, smart) as
  39. //!"typename SegmentManager::void_pointer" type. This allows
  40. //!placing the allocator in shared memory, memory mapped-files, etc...
  41. template<class T, class SegmentManager>
  42. class allocator
  43. {
  44. public:
  45. //Segment manager
  46. typedef SegmentManager segment_manager;
  47. typedef typename SegmentManager::void_pointer void_pointer;
  48. /// @cond
  49. private:
  50. //Self type
  51. typedef allocator<T, SegmentManager> self_t;
  52. //Pointer to void
  53. typedef typename segment_manager::void_pointer aux_pointer_t;
  54. //Typedef to const void pointer
  55. typedef typename
  56. boost::pointer_to_other
  57. <aux_pointer_t, const void>::type cvoid_ptr;
  58. //Pointer to the allocator
  59. typedef typename boost::pointer_to_other
  60. <cvoid_ptr, segment_manager>::type alloc_ptr_t;
  61. //Not assignable from related allocator
  62. template<class T2, class SegmentManager2>
  63. allocator& operator=(const allocator<T2, SegmentManager2>&);
  64. //Not assignable from other allocator
  65. allocator& operator=(const allocator&);
  66. //Pointer to the allocator
  67. alloc_ptr_t mp_mngr;
  68. /// @endcond
  69. public:
  70. typedef T value_type;
  71. typedef typename boost::pointer_to_other
  72. <cvoid_ptr, T>::type pointer;
  73. typedef typename boost::
  74. pointer_to_other<pointer, const T>::type const_pointer;
  75. typedef typename detail::add_reference
  76. <value_type>::type reference;
  77. typedef typename detail::add_reference
  78. <const value_type>::type const_reference;
  79. typedef std::size_t size_type;
  80. typedef std::ptrdiff_t difference_type;
  81. typedef boost::interprocess::version_type<allocator, 2> version;
  82. /// @cond
  83. //Experimental. Don't use.
  84. typedef boost::container::containers_detail::transform_multiallocation_chain
  85. <typename SegmentManager::multiallocation_chain, T>multiallocation_chain;
  86. /// @endcond
  87. //!Obtains an allocator that allocates
  88. //!objects of type T2
  89. template<class T2>
  90. struct rebind
  91. {
  92. typedef allocator<T2, SegmentManager> other;
  93. };
  94. //!Returns the segment manager.
  95. //!Never throws
  96. segment_manager* get_segment_manager()const
  97. { return detail::get_pointer(mp_mngr); }
  98. //!Constructor from the segment manager.
  99. //!Never throws
  100. allocator(segment_manager *segment_mngr)
  101. : mp_mngr(segment_mngr) { }
  102. //!Constructor from other allocator.
  103. //!Never throws
  104. allocator(const allocator &other)
  105. : mp_mngr(other.get_segment_manager()){ }
  106. //!Constructor from related allocator.
  107. //!Never throws
  108. template<class T2>
  109. allocator(const allocator<T2, SegmentManager> &other)
  110. : mp_mngr(other.get_segment_manager()){}
  111. //!Allocates memory for an array of count elements.
  112. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  113. pointer allocate(size_type count, cvoid_ptr hint = 0)
  114. {
  115. (void)hint;
  116. if(count > this->max_size())
  117. throw bad_alloc();
  118. return pointer(static_cast<value_type*>(mp_mngr->allocate(count*sizeof(T))));
  119. }
  120. //!Deallocates memory previously allocated.
  121. //!Never throws
  122. void deallocate(const pointer &ptr, size_type)
  123. { mp_mngr->deallocate((void*)detail::get_pointer(ptr)); }
  124. //!Returns the number of elements that could be allocated.
  125. //!Never throws
  126. size_type max_size() const
  127. { return mp_mngr->get_size()/sizeof(T); }
  128. //!Swap segment manager. Does not throw. If each allocator is placed in
  129. //!different memory segments, the result is undefined.
  130. friend void swap(self_t &alloc1, self_t &alloc2)
  131. { detail::do_swap(alloc1.mp_mngr, alloc2.mp_mngr); }
  132. //!Returns maximum the number of objects the previously allocated memory
  133. //!pointed by p can hold. This size only works for memory allocated with
  134. //!allocate, allocation_command and allocate_many.
  135. size_type size(const pointer &p) const
  136. {
  137. return (size_type)mp_mngr->size(detail::get_pointer(p))/sizeof(T);
  138. }
  139. std::pair<pointer, bool>
  140. allocation_command(boost::interprocess::allocation_type command,
  141. size_type limit_size,
  142. size_type preferred_size,
  143. size_type &received_size, const pointer &reuse = 0)
  144. {
  145. return mp_mngr->allocation_command
  146. (command, limit_size, preferred_size, received_size, detail::get_pointer(reuse));
  147. }
  148. //!Allocates many elements of size elem_size in a contiguous block
  149. //!of memory. The minimum number to be allocated is min_elements,
  150. //!the preferred and maximum number is
  151. //!preferred_elements. The number of actually allocated elements is
  152. //!will be assigned to received_size. The elements must be deallocated
  153. //!with deallocate(...)
  154. multiallocation_chain allocate_many
  155. (size_type elem_size, std::size_t num_elements)
  156. {
  157. return multiallocation_chain(mp_mngr->allocate_many(sizeof(T)*elem_size, num_elements));
  158. }
  159. //!Allocates n_elements elements, each one of size elem_sizes[i]in a
  160. //!contiguous block
  161. //!of memory. The elements must be deallocated
  162. multiallocation_chain allocate_many
  163. (const size_type *elem_sizes, size_type n_elements)
  164. {
  165. multiallocation_chain(mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T)));
  166. }
  167. //!Allocates many elements of size elem_size in a contiguous block
  168. //!of memory. The minimum number to be allocated is min_elements,
  169. //!the preferred and maximum number is
  170. //!preferred_elements. The number of actually allocated elements is
  171. //!will be assigned to received_size. The elements must be deallocated
  172. //!with deallocate(...)
  173. void deallocate_many(multiallocation_chain chain)
  174. {
  175. return mp_mngr->deallocate_many(chain.extract_multiallocation_chain());
  176. }
  177. //!Allocates just one object. Memory allocated with this function
  178. //!must be deallocated only with deallocate_one().
  179. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  180. pointer allocate_one()
  181. { return this->allocate(1); }
  182. //!Allocates many elements of size == 1 in a contiguous block
  183. //!of memory. The minimum number to be allocated is min_elements,
  184. //!the preferred and maximum number is
  185. //!preferred_elements. The number of actually allocated elements is
  186. //!will be assigned to received_size. Memory allocated with this function
  187. //!must be deallocated only with deallocate_one().
  188. multiallocation_chain allocate_individual
  189. (std::size_t num_elements)
  190. { return this->allocate_many(1, num_elements); }
  191. //!Deallocates memory previously allocated with allocate_one().
  192. //!You should never use deallocate_one to deallocate memory allocated
  193. //!with other functions different from allocate_one(). Never throws
  194. void deallocate_one(const pointer &p)
  195. { return this->deallocate(p, 1); }
  196. //!Allocates many elements of size == 1 in a contiguous block
  197. //!of memory. The minimum number to be allocated is min_elements,
  198. //!the preferred and maximum number is
  199. //!preferred_elements. The number of actually allocated elements is
  200. //!will be assigned to received_size. Memory allocated with this function
  201. //!must be deallocated only with deallocate_one().
  202. void deallocate_individual(multiallocation_chain chain)
  203. { return this->deallocate_many(boost::interprocess::move(chain)); }
  204. //!Returns address of mutable object.
  205. //!Never throws
  206. pointer address(reference value) const
  207. { return pointer(boost::addressof(value)); }
  208. //!Returns address of non mutable object.
  209. //!Never throws
  210. const_pointer address(const_reference value) const
  211. { return const_pointer(boost::addressof(value)); }
  212. //!Copy construct an object
  213. //!Throws if T's copy constructor throws
  214. void construct(const pointer &ptr, const_reference v)
  215. { new((void*)detail::get_pointer(ptr)) value_type(v); }
  216. //!Default construct an object.
  217. //!Throws if T's default constructor throws
  218. void construct(const pointer &ptr)
  219. { new((void*)detail::get_pointer(ptr)) value_type; }
  220. //!Destroys object. Throws if object's
  221. //!destructor throws
  222. void destroy(const pointer &ptr)
  223. { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
  224. };
  225. //!Equality test for same type
  226. //!of allocator
  227. template<class T, class SegmentManager> inline
  228. bool operator==(const allocator<T , SegmentManager> &alloc1,
  229. const allocator<T, SegmentManager> &alloc2)
  230. { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); }
  231. //!Inequality test for same type
  232. //!of allocator
  233. template<class T, class SegmentManager> inline
  234. bool operator!=(const allocator<T, SegmentManager> &alloc1,
  235. const allocator<T, SegmentManager> &alloc2)
  236. { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); }
  237. } //namespace interprocess {
  238. /// @cond
  239. template<class T>
  240. struct has_trivial_destructor;
  241. template<class T, class SegmentManager>
  242. struct has_trivial_destructor
  243. <boost::interprocess::allocator <T, SegmentManager> >
  244. {
  245. enum { value = true };
  246. };
  247. /// @endcond
  248. } //namespace boost {
  249. #include <boost/interprocess/detail/config_end.hpp>
  250. #endif //BOOST_INTERPROCESS_ALLOCATOR_HPP