14template <
typename T,
typename Allocator = std::allocator<T>>
class vector {
17 using allocator_type = Allocator;
18 using size_type = std::size_t;
19 using difference_type = std::ptrdiff_t;
20 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
22 typename std::allocator_traits<allocator_type>::const_pointer;
23 using reference =
decltype(*std::declval<pointer>());
24 using const_reference =
decltype(*std::declval<const_pointer>());
25 using iterator = pointer;
26 using const_iterator = const_pointer;
29 explicit vector(
const Allocator &allocator) noexcept
30 : allocator_(allocator) {}
32 explicit vector(size_type count,
const T &value,
33 const Allocator &alloc = Allocator())
35 change_capacity_impl_(count);
37 fill(data(), data() + size(), value);
40 explicit vector(size_type count,
const Allocator &alloc = Allocator())
42 change_capacity_impl_(count);
44 fill(data(), data() + size(), T{});
47 template <std::forward_iterator Iter>
48 constexpr vector(Iter first, Iter last,
const Allocator &alloc = Allocator())
50 change_capacity_impl_(rng::distance(first, last));
52 copy(first, last, begin());
55 vector(
const vector &other) : allocator_(other.get_allocator()) {
56 change_capacity_impl_(other.size());
58 copy(other.begin(), other.end(), begin());
61 vector(
const vector &other,
const Allocator &alloc) : allocator_(alloc) {
62 change_capacity_impl_(other.size());
64 copy(other.begin(), other.end(), begin());
68 requires(std::is_trivially_move_constructible_v<T>)
69 : allocator_(other.get_allocator()) {
71 other.data_ =
nullptr;
74 capacity_ = other.capacity_;
79 requires(std::is_trivially_move_constructible_v<T>)
82 other.data_ =
nullptr;
85 capacity_ = other.capacity_;
89 vector(std::initializer_list<T> init,
const Allocator &alloc = Allocator())
91 change_capacity_impl_(init.size());
93 copy(init.begin(), init.end(), begin());
97 assign(other.begin(), other.end());
101 template <std::forward_iterator Iter>
void assign(Iter first, Iter last) {
102 auto new_size = rng::distance(first, last);
105 copy(first, last, begin());
115 if (data() !=
nullptr) {
116 allocator_.deallocate(data(), capacity());
120 size_type size()
const noexcept {
return size_; }
122 bool empty()
const noexcept {
return size() == 0; }
124 size_type capacity()
const noexcept {
return capacity_; }
126 pointer data()
noexcept {
return data_; }
128 const_pointer data()
const noexcept {
return data_; }
130 allocator_type get_allocator()
const noexcept {
return allocator_; }
132 iterator begin()
noexcept {
return data_; }
134 iterator end()
noexcept {
return begin() + size(); }
136 const_iterator begin()
const noexcept {
return data_; }
138 const_iterator end()
const noexcept {
return begin() + size(); }
140 reference operator[](size_type pos) {
return *(begin() + pos); }
142 const_reference operator[](size_type pos)
const {
return *(begin() + pos); }
144 void reserve(size_type new_cap) {
145 if (new_cap > capacity()) {
146 pointer new_data = get_allocator().allocate(new_cap);
148 if (begin() != end()) {
150 copy(begin(), end(), new_data);
152 if (data_ !=
nullptr) {
153 get_allocator().deallocate(data_, capacity());
160 void push_back(
const T &value) {
161 if (size() + 1 > capacity()) {
162 size_type new_capacity = next_highest_power_of_two_impl_(capacity());
163 reserve(new_capacity);
166 data()[size()] = value;
170 void push_back(T &&value) {
171 if (size() + 1 > capacity()) {
172 size_type new_capacity = next_highest_power_of_two_impl_(capacity());
173 reserve(new_capacity);
176 data()[size()] = std::move(value);
180 bool try_push_back(
const T &value) {
181 if (size() + 1 <= capacity()) {
182 data()[size()] = value;
190 void resize(size_type count) {
191 if (count > capacity()) {
194 if (count > size()) {
204 void resize(size_type count,
const value_type &value) {
205 if (count > capacity()) {
208 if (count > size()) {
209 for (std::size_t i = 0; i < count - size(); i++) {
218 void change_capacity_impl_(size_type count) {
219 if (data_ !=
nullptr && capacity_ != count) {
220 allocator_.deallocate(data_, capacity());
222 size_ = capacity_ = count;
223 data_ = size_ ? allocator_.allocate(count) :
nullptr;
228 constexpr size_type next_highest_power_of_two_impl_(size_type n) {
234 if constexpr (
sizeof(size_type) > 2)
236 if constexpr (
sizeof(size_type) > 4)
242 pointer data_ =
nullptr;
244 size_type capacity_ = 0;
245 allocator_type allocator_;
Definition: vector.hpp:14