16#include <initializer_list>
148 template<
typename InputIt>
149 requires std::input_iterator<InputIt>
150 constexpr Vector(InputIt first, InputIt last);
172 constexpr Vector(std::initializer_list<T> init_list);
220 template<
typename InputIt>
221 requires std::input_iterator<InputIt>
224 constexpr void assign(InputIt first, InputIt last);
231 constexpr void assign(std::initializer_list<T> init_list);
309 [[nodiscard]] constexpr auto
data() noexcept ->
pointer;
352 [[nodiscard]] constexpr auto
end() noexcept ->
iterator;
432 [[nodiscard]] constexpr auto
empty() const ->
bool;
439 [[nodiscard]] constexpr auto
size() const noexcept ->
size_type;
476 constexpr
void clear();
521 template<typename InputIt>
522 requires std::input_iterator<InputIt>
548 template<typename... Args>
558 template<typename... Args>
612 constexpr
void push_back(const T& value);
654 constexpr
void swap(
Vector<T>& other) noexcept;
687 void destroy_elements();
692 void clear_allocation();
727 for (
size_t i = 0; i < count; i++)
734 template<
typename InputIt>
735 requires std::input_iterator<InputIt>
747 for (
const auto& item : other)
781 for (
const auto& item : other)
797 m_data = other.m_data;
798 m_capacity = other.m_capacity;
799 m_size = other.m_size;
801 other.m_data =
nullptr;
802 other.m_capacity = 0;
817 for (
auto const& item : init_list)
833 for (
size_t i = 0; i < count; i++)
840 template<
typename InputIt>
841 requires std::input_iterator<InputIt>
846 const auto count =
static_cast<size_type>(std::distance(first, last));
853 while (first != last)
868 for (
auto const& item : init_list)
885 throw std::out_of_range(
"Pos argument outside of container range");
897 throw std::out_of_range(
"Pos argument outside of container range");
936 return m_data[m_size - 1];
943 return m_data[m_size - 1];
982 return m_data + m_size;
989 return m_data + m_size;
996 return m_data + m_size;
1005 template<
typename T>
1011 template<
typename T>
1017 template<
typename T>
1023 template<
typename T>
1029 template<
typename T>
1035 template<
typename T>
1041 template<
typename T>
1047 template<
typename T>
1050 return std::allocator_traits<allocator_type>::max_size(
get_allocator());
1053 template<
typename T>
1059 reallocate(new_cap);
1063 template<
typename T>
1069 template<
typename T>
1072 if (m_capacity > m_size)
1078 template<
typename T>
1085 template<
typename T>
1088 return insert(pos, 1, value);
1091 template<
typename T>
1094 return insert(pos, 1, std::move(value));
1097 template<
typename T>
1100 iterator new_pos{ insert_make_space_for_new_elems(pos, count) };
1104 for (
size_t i = 0; i < count; i++)
1106 std::allocator_traits<allocator_type>::construct(m_allocator, new_iter, value);
1113 template<
typename T>
1114 template<
typename InputIt>
1115 requires std::input_iterator<InputIt>
1118 const auto count =
static_cast<size_type>(std::distance(first, last));
1119 iterator new_pos{ insert_make_space_for_new_elems(pos, count) };
1123 while (first != last)
1125 std::allocator_traits<allocator_type>::construct(m_allocator, new_iter, *first);
1133 template<
typename T>
1136 const size_type count = init_list.size();
1137 iterator new_pos{ insert_make_space_for_new_elems(pos, count) };
1141 for (
const auto& value : init_list)
1143 std::allocator_traits<allocator_type>::construct(m_allocator, new_iter, value);
1150 template<
typename T>
1151 template<
typename... Args>
1154 iterator new_pos{ insert_make_space_for_new_elems(pos, 1) };
1157 std::allocator_traits<allocator_type>::construct(m_allocator, new_pos, std::forward<Args>(args)...);
1162 template<
typename T>
1163 template<
typename... Args>
1173 if (m_size >= m_capacity)
1175 reallocate(calc_new_capacity());
1177 std::allocator_traits<allocator_type>::construct(m_allocator,
end(), std::forward<Args>(args)...);
1181 return m_data[m_size - 1];
1184 template<
typename T>
1187 return erase(pos, pos + 1);
1190 template<
typename T>
1193 return erase(pos, pos + 1);
1196 template<
typename T>
1202 template<
typename T>
1207 const size_type count{ offset_last - offset_first };
1210 while (first != last)
1212 std::allocator_traits<allocator_type>::destroy(m_allocator, first);
1218 std::move(
begin() + offset_last,
end(),
begin() + offset_first);
1221 return begin() + offset_first;
1224 template<
typename T>
1227 if (m_size >= m_capacity)
1229 reallocate(calc_new_capacity());
1232 std::allocator_traits<allocator_type>::construct(m_allocator,
end(), value);
1236 template<
typename T>
1240 if (m_size >= m_capacity)
1242 reallocate(calc_new_capacity());
1245 std::allocator_traits<allocator_type>::construct(m_allocator,
end(), std::move(value));
1249 template<
typename T>
1254 std::allocator_traits<allocator_type>::destroy(m_allocator,
end());
1259 template<
typename T>
1265 template<
typename T>
1270 throw std::length_error(
"Capacity required by new vector would exceed maximum allowed size");
1273 if (count == m_size)
1281 while (m_size > count)
1290 while (m_size < count)
1297 template<
typename T>
1300 std::swap(*
this, other);
1303 template<
typename T>
1304 inline auto Vector<T>::calc_new_capacity() -> size_type
1306 return m_capacity == 0 ? 1 : m_capacity * 2;
1309 template<
typename T>
1310 auto Vector<T>::insert_make_space_for_new_elems(const_iterator pos, size_type count) -> iterator
1314 if (size() + count > capacity())
1317 const size_type new_capacity = m_capacity + count;
1318 pointer new_data = allocator_type().allocate(new_capacity);
1321 iterator iter{ begin() };
1322 iterator new_iter = new_data;
1327 std::allocator_traits<allocator_type>::construct(m_allocator, new_iter, std::move(*iter));
1334 for (
size_t i = 0; i < count; i++)
1340 while (iter != end())
1342 std::allocator_traits<allocator_type>::construct(m_allocator, new_iter, std::move(*iter));
1349 m_capacity = new_capacity;
1356 iterator iter{
const_cast<iterator
>(pos) };
1360 std::move(iter, end(), iter + count);
1368 template<
typename T>
1369 void Vector<T>::reallocate(size_type new_cap)
1377 if (new_cap > max_size())
1379 throw std::length_error(
"Pos argument outside of container range");
1382 pointer new_data = allocator_type().allocate(new_cap);
1383 for (
size_t i = 0; i < m_size; i++)
1386 std::allocator_traits<allocator_type>::construct(m_allocator, new_data + i, std::move_if_noexcept(m_data[i]));
1390 m_capacity = new_cap;
1394 template<
typename T>
1395 void Vector<T>::destroy_elements()
1397 iterator iter{ begin() };
1398 while (iter != end())
1400 std::allocator_traits<allocator_type>::destroy(m_allocator, iter);
1405 template<
typename T>
1406 void Vector<T>::clear_allocation()
1411 std::allocator_traits<allocator_type>::deallocate(m_allocator, m_data, m_capacity);
1423 template<
typename T>
1426 vector1.swap(vector2);
1437 template<
typename T>
1440 for (
size_t i = 0; i < vector.size(); i++)
1442 out << vector[i] <<
' ';
1457 template<
typename T>
1460 if (vector1.size() != vector2.size())
1465 auto vector1_iter = vector1.cbegin();
1466 auto vector2_iter = vector2.cbegin();
1469 while (vector1_iter != vector1.cend())
1471 if (*vector1_iter != *vector2_iter)
1492 template<
typename T>
1495 auto vector1_iter = vector1.
cbegin();
1496 auto vector2_iter = vector2.
cbegin();
1498 while (vector1_iter != vector1.
cend() && vector2_iter != vector2.
cend())
1500 if (*vector1_iter < *vector2_iter)
1502 return std::strong_ordering::less;
1504 if (*vector1_iter > *vector2_iter)
1506 return std::strong_ordering::greater;
1513 if (vector1.
size() < vector2.
size())
1515 return std::strong_ordering::less;
1517 if (vector1.
size() > vector2.
size())
1519 return std::strong_ordering::greater;
1522 return std::strong_ordering::equivalent;
constexpr auto operator==(const Array< T, N > &lhs, const Array< T, N > &rhs) noexcept(noexcept(*lhs.begin()== *rhs.begin())) -> bool
The relational operator compares two Array objects.
constexpr auto operator<=>(const Array< T, N > &lhs, const Array< T, N > &rhs) noexcept(noexcept(*lhs.begin()== *rhs.begin())) -> std::compare_three_way_result_t< T >
The relational operator compares two Array objects.
void swap(Array< T, N > &lhs, Array< T, N > &rhs) noexcept(noexcept(lhs.swap(rhs)))
Exchanges content of two Array containers.
auto operator<<(std::ostream &out, const Array< T, N > &array) -> std::ostream &
Overloads operator to print all elements of Array.
Implements Vector class template for dynamic size container.
constexpr auto erase(iterator pos) -> iterator
Erases specified element from the container.
constexpr auto front() -> reference
Returns reference to first Arary element.
T value_type
Alias for data type used in class.
std::reverse_iterator< iterator > reverse_iterator
Alias for reverse_iterator to data type used in class.
constexpr void clear()
Erases all elements of the container Does not affect container capacity.
constexpr auto capacity() -> size_type
Returns the number of elements allocated for container.
constexpr auto emplace(const_iterator pos, Args &&... args) -> iterator
Insert new element into the container before pos.
constexpr auto crend() const noexcept -> const_reverse_iterator
Returns const_reverse_iterator past the last element of reversed underlaying data structure.
constexpr auto crbegin() const noexcept -> const_reverse_iterator
Returns const_reverse_iterator to the first element of reversed underlaying data structure.
constexpr auto at(size_type pos) -> reference
Returns a reference to Vector element at pos index. If pos is outside of container range,...
constexpr auto cbegin() const noexcept -> const_iterator
Returns const_iterator to first element.
constexpr void shrink_to_fit()
Request to remove of unused capacity.
constexpr auto cend() const noexcept -> const_iterator
Returns const_iterator past last element of underlaying data structure.
constexpr auto max_size() const noexcept -> size_type
Returns maximum number of elements container can hold.
std::ptrdiff_t difference_type
Alias for pointer difference type.
constexpr Vector()
Construct a new Vector object.
const T * const_pointer
Alias for const pointer to data type used in class.
std::size_t size_type
Alias for size type used in class.
constexpr auto begin() noexcept -> iterator
Returns iterator to first element.
constexpr auto get_allocator() const -> allocator_type
Get the allocator object.
constexpr auto back() -> reference
Returns reference to last Arary element.
constexpr auto empty() const -> bool
Checks if container has elements.
std::reverse_iterator< const_iterator > const_reverse_iterator
Alias for const reverse_iterator to data type used in class.
constexpr void push_back(const T &value)
Appends a copy of value at the end of the container.
const T * const_iterator
Alias for const iterator to data type used in class.
T & reference
Alias for reference to data type used in class.
T * pointer
Alias for pointer to data type used in class.
~Vector()
Destroy the Vector object.
constexpr void pop_back()
Removes the last element of the container.
constexpr auto data() noexcept -> pointer
Returns pointer to underlying data container.
constexpr void swap(Vector< T > &other) noexcept
Exchanges content of current container with other container.
constexpr auto rbegin() -> reverse_iterator
Returns reverse_iterator to the first element of reversed underlaying data structure.
constexpr auto size() const noexcept -> size_type
Returns number of elements in container.
constexpr auto operator=(const Vector< T > &other) -> Vector< T > &
Assign Vector object using copy assignment.
constexpr void reserve(size_type new_cap)
Increase the capacity of the container.
constexpr auto operator[](size_type pos) -> reference
Returns a reference to Vector element at pos index. If pos is outside of container range,...
constexpr auto emplace_back(Args &&... args) -> reference
Appends a copy of value at the end of the container.
constexpr auto end() noexcept -> iterator
Returns iterator past last element of underlaying data structure.
std::allocator< value_type > allocator_type
Alias for memory allocator.
constexpr void resize(size_type count)
Resizez the container to contain count elements if count is equal to current size,...
constexpr auto insert(const_iterator pos, const T &value) -> iterator
Insert a copy of value before pos.
constexpr void assign(size_type count, const T &value)
Function assign count , elements of value to Vector object.
T * iterator
Alias for iterator to data type used in class.
constexpr auto rend() -> reverse_iterator
Returns reverse_iterator past the last element of reversed underlaying data structure.
const T & const_reference
Alias for const reference to data type used in class.