|
20 | 20 | #include <new> |
21 | 21 | #include <vector> |
22 | 22 |
|
| 23 | +#include "sized_allocator.h" |
23 | 24 | #include "test_macros.h" |
24 | 25 |
|
25 | | -template <typename T, typename SIZE_TYPE = std::size_t, typename DIFF_TYPE = std::ptrdiff_t> |
26 | | -class sized_allocator { |
27 | | - template <typename U, typename Sz, typename Diff> |
28 | | - friend class sized_allocator; |
29 | | - |
30 | | -public: |
31 | | - using value_type = T; |
32 | | - using size_type = SIZE_TYPE; |
33 | | - using difference_type = DIFF_TYPE; |
34 | | - using propagate_on_container_swap = std::true_type; |
35 | | - |
36 | | - TEST_CONSTEXPR_CXX20 explicit sized_allocator(int d = 0) : data_(d) {} |
37 | | - |
38 | | - template <typename U, typename Sz, typename Diff> |
39 | | - TEST_CONSTEXPR_CXX20 sized_allocator(const sized_allocator<U, Sz, Diff>& a) TEST_NOEXCEPT : data_(a.data_) {} |
40 | | - |
41 | | - TEST_CONSTEXPR_CXX20 T* allocate(size_type n) { |
42 | | - if (n > max_size()) |
43 | | - TEST_THROW(std::bad_array_new_length()); |
44 | | - return std::allocator<T>().allocate(n); |
45 | | - } |
46 | | - |
47 | | - TEST_CONSTEXPR_CXX20 void deallocate(T* p, size_type n) TEST_NOEXCEPT { std::allocator<T>().deallocate(p, n); } |
48 | | - |
49 | | - TEST_CONSTEXPR size_type max_size() const TEST_NOEXCEPT { |
50 | | - return std::numeric_limits<size_type>::max() / sizeof(value_type); |
51 | | - } |
52 | | - |
53 | | -private: |
54 | | - int data_; |
55 | | - |
56 | | - TEST_CONSTEXPR friend bool operator==(const sized_allocator& a, const sized_allocator& b) { |
57 | | - return a.data_ == b.data_; |
58 | | - } |
59 | | - TEST_CONSTEXPR friend bool operator!=(const sized_allocator& a, const sized_allocator& b) { |
60 | | - return a.data_ != b.data_; |
61 | | - } |
62 | | -}; |
63 | | - |
64 | 26 | TEST_CONSTEXPR_CXX20 bool tests() { |
65 | 27 | // The following tests are typical ways to trigger reallocations where `std::max` is used to calculate the capacity. |
| 28 | + // The purpose of these tests is to ensure that the ambiguous internal calls to `std::max` have been fixed. |
66 | 29 | { |
67 | 30 | using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>; |
68 | 31 | std::vector<bool, Alloc> c(Alloc(1)); |
69 | 32 | c.resize(10); |
| 33 | + assert(c.size() == 10); |
| 34 | + assert(c.capacity() >= 10); |
70 | 35 | } |
71 | 36 | { |
72 | 37 | using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>; |
73 | 38 | std::vector<bool, Alloc> c(Alloc(1)); |
74 | 39 | c.assign(10, true); |
| 40 | + assert(c.size() == 10); |
| 41 | + assert(c.capacity() >= 10); |
75 | 42 | } |
76 | 43 | { |
77 | 44 | using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>; |
78 | 45 | std::vector<bool, Alloc> c(Alloc(1)); |
79 | 46 | c.insert(c.end(), true); |
| 47 | + assert(c.size() == 1); |
| 48 | + assert(c.capacity() >= 1); |
80 | 49 | } |
81 | 50 | { |
82 | 51 | using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>; |
83 | 52 | std::vector<bool, Alloc> c(Alloc(1)); |
84 | 53 | c.insert(c.end(), 10, true); |
| 54 | + assert(c.size() == 10); |
| 55 | + assert(c.capacity() >= 10); |
85 | 56 | } |
86 | 57 | { |
87 | 58 | using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>; |
88 | 59 | std::vector<bool, Alloc> c(Alloc(1)); |
89 | 60 | c.push_back(true); |
| 61 | + assert(c.size() == 1); |
| 62 | + assert(c.capacity() >= 1); |
90 | 63 | } |
91 | 64 | { |
92 | 65 | using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>; |
93 | 66 | std::vector<bool, Alloc> c(Alloc(1)); |
94 | 67 | c.resize(10, true); |
| 68 | + assert(c.size() == 10); |
| 69 | + assert(c.capacity() >= 10); |
95 | 70 | } |
96 | 71 | { |
97 | 72 | using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>; |
98 | 73 | std::vector<bool, Alloc> c(Alloc(1)); |
99 | 74 | c.resize(10); |
| 75 | + assert(c.size() == 10); |
| 76 | + assert(c.capacity() >= 10); |
100 | 77 | } |
101 | 78 | { |
102 | 79 | using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>; |
103 | 80 | std::vector<bool, Alloc> c(Alloc(1)); |
104 | 81 | c.resize(10); |
| 82 | + assert(c.size() == 10); |
| 83 | + assert(c.capacity() >= 10); |
105 | 84 | } |
106 | 85 | { |
107 | 86 | using Alloc = sized_allocator<bool, std::size_t, std::ptrdiff_t>; |
108 | 87 | std::vector<bool, Alloc> c(Alloc(1)); |
109 | 88 | c.resize(10); |
| 89 | + assert(c.size() == 10); |
| 90 | + assert(c.capacity() >= 10); |
110 | 91 | } |
111 | 92 |
|
112 | 93 | return true; |
|
0 commit comments