test_allocator.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #ifndef TEST_ALLOCATOR_H
  2. #define TEST_ALLOCATOR_H
  3. #include <cstddef>
  4. #include <type_traits>
  5. #include <cstdlib>
  6. #include <new>
  7. #include <climits>
  8. class test_alloc_base
  9. {
  10. protected:
  11. static int count;
  12. public:
  13. static int throw_after;
  14. };
  15. int test_alloc_base::count = 0;
  16. int test_alloc_base::throw_after = INT_MAX;
  17. template <class T>
  18. class test_allocator
  19. : public test_alloc_base
  20. {
  21. int data_;
  22. template <class U> friend class test_allocator;
  23. public:
  24. typedef unsigned size_type;
  25. typedef int difference_type;
  26. typedef T value_type;
  27. typedef value_type* pointer;
  28. typedef const value_type* const_pointer;
  29. typedef typename std::add_lvalue_reference<value_type>::type reference;
  30. typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
  31. template <class U> struct rebind {typedef test_allocator<U> other;};
  32. test_allocator() throw() : data_(-1) {}
  33. explicit test_allocator(int i) throw() : data_(i) {}
  34. test_allocator(const test_allocator& a) throw()
  35. : data_(a.data_) {}
  36. template <class U> test_allocator(const test_allocator<U>& a) throw()
  37. : data_(a.data_) {}
  38. ~test_allocator() throw() {data_ = 0;}
  39. pointer address(reference x) const {return &x;}
  40. const_pointer address(const_reference x) const {return &x;}
  41. pointer allocate(size_type n, const void* = 0)
  42. {
  43. if (count >= throw_after)
  44. throw std::bad_alloc();
  45. ++count;
  46. return (pointer)std::malloc(n * sizeof(T));
  47. }
  48. void deallocate(pointer p, size_type n)
  49. {std::free(p);}
  50. size_type max_size() const throw()
  51. {return UINT_MAX / sizeof(T);}
  52. void construct(pointer p, const T& val)
  53. {::new(p) T(val);}
  54. #ifdef _LIBCPP_MOVE
  55. void construct(pointer p, T&& val)
  56. {::new(p) T(std::move(val));}
  57. #endif
  58. void destroy(pointer p) {p->~T();}
  59. friend bool operator==(const test_allocator& x, const test_allocator& y)
  60. {return x.data_ == y.data_;}
  61. friend bool operator!=(const test_allocator& x, const test_allocator& y)
  62. {return !(x == y);}
  63. };
  64. template <class T>
  65. class other_allocator
  66. {
  67. int data_;
  68. template <class U> friend class other_allocator;
  69. public:
  70. typedef T value_type;
  71. other_allocator() : data_(-1) {}
  72. explicit other_allocator(int i) : data_(i) {}
  73. template <class U> other_allocator(const other_allocator<U>& a)
  74. : data_(a.data_) {}
  75. T* allocate(std::size_t n)
  76. {return (T*)std::malloc(n * sizeof(T));}
  77. void deallocate(T* p, std::size_t n)
  78. {std::free(p);}
  79. other_allocator select_on_container_copy_construction() const
  80. {return other_allocator(-2);}
  81. friend bool operator==(const other_allocator& x, const other_allocator& y)
  82. {return x.data_ == y.data_;}
  83. friend bool operator!=(const other_allocator& x, const other_allocator& y)
  84. {return !(x == y);}
  85. typedef std::true_type propagate_on_container_copy_assignment;
  86. typedef std::true_type propagate_on_container_move_assignment;
  87. typedef std::true_type propagate_on_container_swap;
  88. #ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
  89. std::size_t max_size() const
  90. {return UINT_MAX / sizeof(T);}
  91. #endif
  92. };
  93. #endif