default_allocator.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. Copyright 2019 Glen Joseph Fernandes
  3. ([email protected])
  4. Distributed under the Boost Software License, Version 1.0.
  5. (http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. #ifndef BOOST_CORE_DEFAULT_ALLOCATOR_HPP
  8. #define BOOST_CORE_DEFAULT_ALLOCATOR_HPP
  9. #include <boost/config.hpp>
  10. #include <new>
  11. namespace boost {
  12. #if defined(BOOST_NO_EXCEPTIONS)
  13. BOOST_NORETURN void throw_exception(const std::exception&);
  14. #endif
  15. namespace default_ {
  16. template<bool V>
  17. struct bool_constant {
  18. typedef bool value_type;
  19. typedef bool_constant type;
  20. static const bool value = V;
  21. operator bool() const BOOST_NOEXCEPT {
  22. return V;
  23. }
  24. bool operator()() const BOOST_NOEXCEPT {
  25. return V;
  26. }
  27. };
  28. template<bool V>
  29. const bool bool_constant<V>::value;
  30. template<class T>
  31. struct add_reference {
  32. typedef T& type;
  33. };
  34. template<>
  35. struct add_reference<void> {
  36. typedef void type;
  37. };
  38. template<>
  39. struct add_reference<const void> {
  40. typedef const void type;
  41. };
  42. template<class T>
  43. struct default_allocator {
  44. typedef T value_type;
  45. typedef T* pointer;
  46. typedef const T* const_pointer;
  47. typedef typename add_reference<T>::type reference;
  48. typedef typename add_reference<const T>::type const_reference;
  49. typedef std::size_t size_type;
  50. typedef std::ptrdiff_t difference_type;
  51. typedef bool_constant<true> propagate_on_container_move_assignment;
  52. typedef bool_constant<true> is_always_equal;
  53. template<class U>
  54. struct rebind {
  55. typedef default_allocator<U> other;
  56. };
  57. #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
  58. default_allocator() = default;
  59. #else
  60. BOOST_CONSTEXPR default_allocator() BOOST_NOEXCEPT { }
  61. #endif
  62. template<class U>
  63. BOOST_CONSTEXPR default_allocator(const default_allocator<U>&)
  64. BOOST_NOEXCEPT { }
  65. BOOST_CONSTEXPR std::size_t max_size() const BOOST_NOEXCEPT {
  66. return static_cast<std::size_t>(-1) / (2 < sizeof(T) ? sizeof(T) : 2);
  67. }
  68. #if !defined(BOOST_NO_EXCEPTIONS)
  69. T* allocate(std::size_t n) {
  70. if (n > max_size()) {
  71. throw std::bad_alloc();
  72. }
  73. return static_cast<T*>(::operator new(sizeof(T) * n));
  74. }
  75. void deallocate(T* p, std::size_t) {
  76. ::operator delete(p);
  77. }
  78. #else
  79. T* allocate(std::size_t n) {
  80. if (n > max_size()) {
  81. boost::throw_exception(std::bad_alloc());
  82. }
  83. void* p = ::operator new(sizeof(T) * n, std::nothrow);
  84. if (!p) {
  85. boost::throw_exception(std::bad_alloc());
  86. }
  87. return static_cast<T*>(p);
  88. }
  89. void deallocate(T* p, std::size_t) {
  90. ::operator delete(p, std::nothrow);
  91. }
  92. #endif
  93. #if defined(BOOST_NO_CXX11_ALLOCATOR)
  94. T* allocate(std::size_t n, const void*) {
  95. return allocate(n);
  96. }
  97. #endif
  98. #if (defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 60000) || \
  99. defined(BOOST_NO_CXX11_ALLOCATOR)
  100. template<class U, class V>
  101. void construct(U* p, const V& v) {
  102. ::new(p) U(v);
  103. }
  104. template<class U>
  105. void destroy(U* p) {
  106. p->~U();
  107. (void)p;
  108. }
  109. #endif
  110. };
  111. template<class T, class U>
  112. BOOST_CONSTEXPR inline bool
  113. operator==(const default_allocator<T>&,
  114. const default_allocator<U>&) BOOST_NOEXCEPT
  115. {
  116. return true;
  117. }
  118. template<class T, class U>
  119. BOOST_CONSTEXPR inline bool
  120. operator!=(const default_allocator<T>&,
  121. const default_allocator<U>&) BOOST_NOEXCEPT
  122. {
  123. return false;
  124. }
  125. } /* default_ */
  126. using default_::default_allocator;
  127. } /* boost */
  128. #endif