new_allocator.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2014-2015. 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/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #ifndef BOOST_CONTAINER_NEW_ALLOCATOR_HPP
  11. #define BOOST_CONTAINER_NEW_ALLOCATOR_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #if defined(BOOST_HAS_PRAGMA_ONCE)
  16. # pragma once
  17. #endif
  18. #include <boost/container/detail/config_begin.hpp>
  19. #include <boost/container/detail/workaround.hpp>
  20. #include <boost/container/throw_exception.hpp>
  21. #include <cstddef>
  22. //!\file
  23. namespace boost {
  24. namespace container {
  25. /// @cond
  26. template<bool Value>
  27. struct new_allocator_bool
  28. { static const bool value = Value; };
  29. template<class T>
  30. class new_allocator;
  31. /// @endcond
  32. //! Specialization of new_allocator for void types
  33. template<>
  34. class new_allocator<void>
  35. {
  36. public:
  37. typedef void value_type;
  38. typedef void * pointer;
  39. typedef const void* const_pointer;
  40. //!A integral constant of type bool with value true
  41. typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
  42. //!A integral constant of type bool with value true
  43. typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
  44. // reference-to-void members are impossible
  45. //!Obtains an new_allocator that allocates
  46. //!objects of type T2
  47. template<class T2>
  48. struct rebind
  49. {
  50. typedef new_allocator< T2> other;
  51. };
  52. //!Default constructor
  53. //!Never throws
  54. new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
  55. {}
  56. //!Constructor from other new_allocator.
  57. //!Never throws
  58. new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  59. {}
  60. //!Copy assignment operator from other new_allocator.
  61. //!Never throws
  62. new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  63. {
  64. return *this;
  65. }
  66. //!Constructor from related new_allocator.
  67. //!Never throws
  68. template<class T2>
  69. new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
  70. {}
  71. //!Swaps two allocators, does nothing
  72. //!because this new_allocator is stateless
  73. friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  74. {}
  75. //!An new_allocator always compares to true, as memory allocated with one
  76. //!instance can be deallocated by another instance
  77. friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  78. { return true; }
  79. //!An new_allocator always compares to false, as memory allocated with one
  80. //!instance can be deallocated by another instance
  81. friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  82. { return false; }
  83. };
  84. //! This class is a reduced STL-compatible allocator that allocates memory using operator new
  85. template<class T>
  86. class new_allocator
  87. {
  88. public:
  89. typedef T value_type;
  90. typedef T * pointer;
  91. typedef const T * const_pointer;
  92. typedef T & reference;
  93. typedef const T & const_reference;
  94. typedef std::size_t size_type;
  95. typedef std::ptrdiff_t difference_type;
  96. //!A integral constant of type bool with value true
  97. typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
  98. //!A integral constant of type bool with value true
  99. typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
  100. //!Obtains an new_allocator that allocates
  101. //!objects of type T2
  102. template<class T2>
  103. struct rebind
  104. {
  105. typedef new_allocator<T2> other;
  106. };
  107. //!Default constructor
  108. //!Never throws
  109. inline new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
  110. {}
  111. //!Constructor from other new_allocator.
  112. //!Never throws
  113. inline new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  114. {}
  115. //!Copy assignment operator from other new_allocator.
  116. //!Never throws
  117. inline new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  118. { return *this; }
  119. //!Constructor from related new_allocator.
  120. //!Never throws
  121. template<class T2>
  122. inline new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
  123. {}
  124. //!Allocates memory for an array of count elements.
  125. //!Throws bad_alloc if there is no enough memory
  126. pointer allocate(size_type count)
  127. {
  128. const std::size_t max_count = std::size_t(-1)/(2*sizeof(T));
  129. if(BOOST_UNLIKELY(count > max_count))
  130. throw_bad_alloc();
  131. return static_cast<T*>(::operator new(count*sizeof(T)));
  132. }
  133. //!Deallocates previously allocated memory.
  134. //!Never throws
  135. void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
  136. {
  137. (void)n;
  138. # if __cpp_sized_deallocation
  139. ::operator delete((void*)ptr, n * sizeof(T));
  140. #else
  141. ::operator delete((void*)ptr);
  142. # endif
  143. }
  144. //!Returns the maximum number of elements that could be allocated.
  145. //!Never throws
  146. inline size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
  147. { return std::size_t(-1)/(2*sizeof(T)); }
  148. //!Swaps two allocators, does nothing
  149. //!because this new_allocator is stateless
  150. inline friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  151. {}
  152. //!An new_allocator always compares to true, as memory allocated with one
  153. //!instance can be deallocated by another instance
  154. inline friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  155. { return true; }
  156. //!An new_allocator always compares to false, as memory allocated with one
  157. //!instance can be deallocated by another instance
  158. inline friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
  159. { return false; }
  160. };
  161. } //namespace container {
  162. } //namespace boost {
  163. #include <boost/container/detail/config_end.hpp>
  164. #endif //BOOST_CONTAINER_NEW_ALLOCATOR_HPP