expand_bwd_test_allocator.hpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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_EXPAND_BWD_TEST_ALLOCATOR_HPP
  11. #define BOOST_INTERPROCESS_EXPAND_BWD_TEST_ALLOCATOR_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/interprocess/interprocess_fwd.hpp>
  18. #include <boost/interprocess/containers/allocation_type.hpp>
  19. #include <boost/assert.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. #include <memory>
  25. #include <cstddef>
  26. #include <cassert>
  27. #include <new>
  28. //!\file
  29. //!Describes an allocator to test expand capabilities
  30. namespace boost {
  31. namespace interprocess {
  32. namespace test {
  33. //This allocator just allows two allocations. The first one will return
  34. //mp_buffer + m_offset configured in the constructor. The second one
  35. //will return mp_buffer.
  36. template<class T>
  37. class expand_bwd_test_allocator
  38. {
  39. private:
  40. typedef expand_bwd_test_allocator<T> self_t;
  41. typedef void * aux_pointer_t;
  42. typedef const void * cvoid_ptr;
  43. template<class T2>
  44. expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator<T2>&);
  45. expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator&);
  46. public:
  47. typedef T value_type;
  48. typedef T * pointer;
  49. typedef const T * const_pointer;
  50. typedef typename ipcdetail::add_reference
  51. <value_type>::type reference;
  52. typedef typename ipcdetail::add_reference
  53. <const value_type>::type const_reference;
  54. typedef std::size_t size_type;
  55. typedef std::ptrdiff_t difference_type;
  56. typedef boost::interprocess::version_type<expand_bwd_test_allocator, 2> version;
  57. //Dummy multiallocation chain
  58. struct multiallocation_chain{};
  59. template<class T2>
  60. struct rebind
  61. { typedef expand_bwd_test_allocator<T2> other; };
  62. //!Constructor from the segment manager. Never throws
  63. expand_bwd_test_allocator(T *buf, size_type sz, difference_type offset)
  64. : mp_buffer(buf), m_size(sz)
  65. , m_offset(offset), m_allocations(0){ }
  66. //!Constructor from other expand_bwd_test_allocator. Never throws
  67. expand_bwd_test_allocator(const expand_bwd_test_allocator &other)
  68. : mp_buffer(other.mp_buffer), m_size(other.m_size)
  69. , m_offset(other.m_offset), m_allocations(0){ }
  70. //!Constructor from related expand_bwd_test_allocator. Never throws
  71. template<class T2>
  72. expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
  73. : mp_buffer(other.mp_buffer), m_size(other.m_size)
  74. , m_offset(other.m_offset), m_allocations(0){ }
  75. pointer address(reference value)
  76. { return pointer(addressof(value)); }
  77. const_pointer address(const_reference value) const
  78. { return const_pointer(addressof(value)); }
  79. pointer allocate(size_type , cvoid_ptr hint = 0)
  80. { (void)hint; return 0; }
  81. void deallocate(const pointer &, size_type)
  82. {}
  83. template<class Convertible>
  84. void construct(pointer ptr, const Convertible &value)
  85. { new((void*)ptr) value_type(value); }
  86. void destroy(pointer ptr)
  87. { (*ptr).~value_type(); }
  88. size_type max_size() const
  89. { return m_size; }
  90. friend void swap(self_t &alloc1, self_t &alloc2)
  91. {
  92. ::boost::adl_move_swap(alloc1.mp_buffer, alloc2.mp_buffer);
  93. ::boost::adl_move_swap(alloc1.m_size, alloc2.m_size);
  94. ::boost::adl_move_swap(alloc1.m_offset, alloc2.m_offset);
  95. }
  96. //Experimental version 2 expand_bwd_test_allocator functions
  97. pointer allocation_command(boost::interprocess::allocation_type command,
  98. size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
  99. {
  100. (void)reuse; (void)command;
  101. //This allocator only expands backwards!
  102. assert(m_allocations == 0 || (command & boost::interprocess::expand_bwd));
  103. prefer_in_recvd_out_size = limit_size;
  104. if(m_allocations == 0){
  105. if((m_offset + limit_size) > m_size){
  106. assert(0);
  107. }
  108. ++m_allocations;
  109. return mp_buffer + m_offset;
  110. }
  111. else if(m_allocations == 1){
  112. if(limit_size > m_size){
  113. assert(0);
  114. }
  115. ++m_allocations;
  116. return mp_buffer;
  117. }
  118. else{
  119. assert(0);
  120. throw std::bad_alloc();
  121. }
  122. }
  123. //!Returns maximum the number of objects the previously allocated memory
  124. //!pointed by p can hold.
  125. size_type size(const pointer &p) const
  126. { (void)p; return m_size; }
  127. //!Allocates just one object. Memory allocated with this function
  128. //!must be deallocated only with deallocate_one().
  129. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  130. pointer allocate_one()
  131. { return this->allocate(1); }
  132. //!Deallocates memory previously allocated with allocate_one().
  133. //!You should never use deallocate_one to deallocate memory allocated
  134. //!with other functions different from allocate_one(). Never throws
  135. void deallocate_one(const pointer &p)
  136. { return this->deallocate(p, 1); }
  137. pointer mp_buffer;
  138. size_type m_size;
  139. difference_type m_offset;
  140. char m_allocations;
  141. };
  142. //!Equality test for same type of expand_bwd_test_allocator
  143. template<class T> inline
  144. bool operator==(const expand_bwd_test_allocator<T> &,
  145. const expand_bwd_test_allocator<T> &)
  146. { return false; }
  147. //!Inequality test for same type of expand_bwd_test_allocator
  148. template<class T> inline
  149. bool operator!=(const expand_bwd_test_allocator<T> &,
  150. const expand_bwd_test_allocator<T> &)
  151. { return true; }
  152. } //namespace test {
  153. } //namespace interprocess {
  154. } //namespace boost {
  155. #include <boost/interprocess/detail/config_end.hpp>
  156. #endif //BOOST_INTERPROCESS_EXPAND_BWD_TEST_ALLOCATOR_HPP