#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iterator>
#include <cassert>
template<typename T>
void print(const std::vector<T>& v, const std::string& name = "") {
if (!name.empty()) std::cout << name << ": ";
std::cout << "[ ";
for (const auto& elem : v) std::cout << elem << " ";
std::cout << "]\n";
}
template<typename T>
void print_capacity_info(const std::vector<T>& v, const std::string& name = "") {
if (!name.empty()) std::cout << name << " - ";
std::cout << "size = " << v.size() << ", capacity = " << v.capacity() << ", empty = " << std::boolalpha << v.empty() << "\n";
}
int main() {
std::cout << "========== 1. Construction and initialization ==========\n";
std::vector<int> v1;
std::vector<int> v2(5, 10);
std::vector<int> v3 = {1, 2, 3, 4, 5};
std::vector<int> v4(v3);
std::vector<int> v5(std::move(v3));
std::vector<int> v6(v2.begin(), v2.end() - 2);
print(v2, "v2");
print(v5, "v5 (from move of v3)");
print(v6, "v6 (range construction)");
std::cout << "v3 after move: "; print(v3, "v3");
std::cout << "\n========== 2. Element access ==========\n";
std::vector<int> vec = {10, 20, 30, 40, 50};
print(vec, "original vec");
std::cout << "vec[0] = " << vec[0] << "\n";
try {
std::cout << "vec.at(4) = " << vec.at(4) << "\n";
} catch (const std::out_of_range& e) {
std::cout << "Caught exception: " << e.what() << "\n";
}
std::cout << "vec.front() = " << vec.front() << ", vec.back() = " << vec.back() << "\n";
int* data_ptr = vec.data();
std::cout << "First element via data(): " << *data_ptr << "\n";
std::cout << "\n========== 3. Iterators ==========\n";
std::vector<int> it_vec = {1,2,3,4,5};
std::cout << "Forward iteration: ";
for (auto it = it_vec.begin(); it != it_vec.end(); ++it) std::cout << *it << " ";
std::cout << "\n";
std::cout << "Const iteration: ";
for (auto it = it_vec.cbegin(); it != it_vec.cend(); ++it) std::cout << *it << " ";
std::cout << "\n";
std::cout << "Reverse iteration: ";
for (auto rit = it_vec.rbegin(); rit != it_vec.rend(); ++rit) std::cout << *rit << " ";
std::cout << "\n";
std::cout << "Range-based for: ";
for (int x : it_vec) std::cout << x << " ";
std::cout << "\n";
std::cout << "\n========== 4. Capacity-related ==========\n";
std::vector<double> cap_vec;
print_capacity_info(cap_vec, "initial empty vector");
cap_vec.reserve(10);
print_capacity_info(cap_vec, "after reserve(10)");
cap_vec.push_back(1.1);
cap_vec.push_back(2.2);
print_capacity_info(cap_vec, "after adding two elements");
cap_vec.shrink_to_fit();
print_capacity_info(cap_vec, "after shrink_to_fit");
cap_vec.resize(5, 3.3);
print_capacity_info(cap_vec, "after resize(5, 3.3)");
print(cap_vec, "contents");
cap_vec.resize(2);
print_capacity_info(cap_vec, "after resize(2)");
std::cout << "max_size: " << cap_vec.max_size() << "\n";
std::cout << "empty: " << std::boolalpha << cap_vec.empty() << "\n";
std::cout << "\n========== 5. Modifiers ==========\n";
std::vector<int> mod_vec;
mod_vec.assign(3, 7);
print(mod_vec, "assign(3,7)");
mod_vec.assign({10,20,30,40});
print(mod_vec, "assign({10,20,30,40})");
mod_vec.push_back(50);
print(mod_vec, "push_back(50)");
mod_vec.pop_back();
print(mod_vec, "pop_back()");
auto it = mod_vec.begin() + 2;
mod_vec.insert(it, 99);
print(mod_vec, "insert(pos, 99)");
mod_vec.insert(mod_vec.begin() + 3, 2, 88);
print(mod_vec, "insert(pos, 2, 88)");
std::vector<int> src = {1,2,3};
mod_vec.insert(mod_vec.end(), src.begin(), src.end());
print(mod_vec, "insert range {1,2,3}");
mod_vec.emplace(mod_vec.begin(), 100);
print(mod_vec, "emplace 100 at beginning");
mod_vec.emplace_back(200);
print(mod_vec, "emplace_back 200");
mod_vec.erase(mod_vec.begin() + 1);
print(mod_vec, "erase index 1");
mod_vec.erase(mod_vec.begin() + 2, mod_vec.begin() + 4);
print(mod_vec, "erase range [2,4)");
mod_vec.clear();
std::cout << "after clear size = " << mod_vec.size() << "\n";
std::vector<int> a = {1,2,3};
std::vector<int> b = {4,5,6,7};
a.swap(b);
print(a, "a after swap");
print(b, "b after swap");
std::cout << "\n========== 6. Comparison operations ==========\n";
std::vector<int> cmp1 = {1,2,3};
std::vector<int> cmp2 = {1,2,3};
std::vector<int> cmp3 = {1,2,4};
std::cout << std::boolalpha;
std::cout << "cmp1 == cmp2: " << (cmp1 == cmp2) << "\n";
std::cout << "cmp1 != cmp3: " << (cmp1 != cmp3) << "\n";
std::cout << "cmp1 < cmp3: " << (cmp1 < cmp3) << "\n";
std::cout << "\n========== 7. Algorithms with vector ==========\n";
std::vector<int> alg_vec = {5,2,8,1,9,3};
print(alg_vec, "original");
std::sort(alg_vec.begin(), alg_vec.end());
print(alg_vec, "after ascending sort");
std::reverse(alg_vec.begin(), alg_vec.end());
print(alg_vec, "after reverse");
auto find_it = std::find(alg_vec.begin(), alg_vec.end(), 8);
if (find_it != alg_vec.end())
std::cout << "Found element 8 at index: " << std::distance(alg_vec.begin(), find_it) << "\n";
int sum = std::accumulate(alg_vec.begin(), alg_vec.end(), 0);
std::cout << "sum of elements: " << sum << "\n";
alg_vec.erase(std::remove(alg_vec.begin(), alg_vec.end(), 5), alg_vec.end());
print(alg_vec, "after removing all 5s");
std::vector<int> dup_vec = {1,1,2,3,3,3,4};
std::sort(dup_vec.begin(), dup_vec.end());
auto last = std::unique(dup_vec.begin(), dup_vec.end());
dup_vec.erase(last, dup_vec.end());
print(dup_vec, "after removing duplicates");
std::cout << "\n========== 8. Other advanced features ==========\n";
std::vector<bool> bool_vec = {true, false, true};
std::cout << "vector<bool>: ";
for (bool b : bool_vec) std::cout << b << " ";
std::cout << "\n";
std::vector<int> demo = {10,20,30,40};
demo.insert(demo.begin() + 2, 25);
print(demo, "after inserting 25");
for (auto it = demo.begin(); it != demo.end(); ) {
if (*it % 2 == 0) it = demo.erase(it);
else ++it;
}
print(demo, "after removing even numbers");
struct Point { int x, y; Point(int a, int b) : x(a), y(b) {} };
std::vector<Point> points;
points.emplace_back(1, 2);
points.emplace_back(3, 4);
std::cout << "emplace_back constructing Point: ";
for (const auto& p : points) std::cout << "(" << p.x << "," << p.y << ") ";
std::cout << "\n";
std::vector<int> safe_vec = {1,2,3};
try {
safe_vec.reserve(1000000000000ULL);
} catch (const std::bad_alloc& e) {
std::cout << "Memory allocation exception: " << e.what() << "\n";
}
std::cout << "\nAll examples complete!\n";
return 0;
}