01_modern_cpp.cpp

Download
cpp 213 lines 5.8 KB
  1/*
  2 * Modern C++ Features Demo (C++17/C++20)
  3 *
  4 * Demonstrates:
  5 * - Structured bindings (C++17)
  6 * - std::optional, std::variant, std::any
  7 * - if constexpr
  8 * - Fold expressions
  9 * - std::filesystem
 10 * - C++20 concepts
 11 *
 12 * Compile: g++ -std=c++20 -Wall -Wextra 01_modern_cpp.cpp -o modern_cpp
 13 */
 14
 15#include <iostream>
 16#include <optional>
 17#include <variant>
 18#include <any>
 19#include <vector>
 20#include <map>
 21#include <filesystem>
 22#include <string>
 23#include <concepts>
 24
 25namespace fs = std::filesystem;
 26
 27// ============ C++20 Concepts ============
 28template<typename T>
 29concept Numeric = std::integral<T> || std::floating_point<T>;
 30
 31template<Numeric T>
 32T add(T a, T b) {
 33    return a + b;
 34}
 35
 36// ============ Structured Bindings ============
 37void demo_structured_bindings() {
 38    std::cout << "\n=== Structured Bindings (C++17) ===\n";
 39
 40    // Tuple decomposition
 41    auto tuple = std::make_tuple(42, "hello", 3.14);
 42    auto [num, str, pi] = tuple;
 43    std::cout << "Tuple: " << num << ", " << str << ", " << pi << "\n";
 44
 45    // Map iteration
 46    std::map<std::string, int> scores = {{"Alice", 95}, {"Bob", 87}};
 47    for (const auto& [name, score] : scores) {
 48        std::cout << name << ": " << score << "\n";
 49    }
 50
 51    // Pair decomposition
 52    std::pair<int, std::string> pair = {100, "perfect"};
 53    auto [value, description] = pair;
 54    std::cout << "Pair: " << value << " = " << description << "\n";
 55}
 56
 57// ============ std::optional ============
 58std::optional<int> safe_divide(int a, int b) {
 59    if (b == 0) return std::nullopt;
 60    return a / b;
 61}
 62
 63void demo_optional() {
 64    std::cout << "\n=== std::optional ===\n";
 65
 66    auto result1 = safe_divide(10, 2);
 67    if (result1.has_value()) {
 68        std::cout << "10 / 2 = " << result1.value() << "\n";
 69    }
 70
 71    auto result2 = safe_divide(10, 0);
 72    std::cout << "10 / 0 = " << result2.value_or(-1) << " (using default)\n";
 73
 74    // Optional chaining with transform (C++23 style shown with manual check)
 75    std::optional<std::string> name = "Alice";
 76    if (name) {
 77        std::cout << "Name length: " << name->length() << "\n";
 78    }
 79}
 80
 81// ============ std::variant ============
 82void demo_variant() {
 83    std::cout << "\n=== std::variant ===\n";
 84
 85    std::variant<int, double, std::string> var;
 86
 87    var = 42;
 88    std::cout << "Variant holds int: " << std::get<int>(var) << "\n";
 89
 90    var = 3.14;
 91    std::cout << "Variant holds double: " << std::get<double>(var) << "\n";
 92
 93    var = "hello";
 94    std::cout << "Variant holds string: " << std::get<std::string>(var) << "\n";
 95
 96    // Visitor pattern
 97    std::visit([](auto&& arg) {
 98        using T = std::decay_t<decltype(arg)>;
 99        if constexpr (std::is_same_v<T, int>)
100            std::cout << "Visiting int: " << arg << "\n";
101        else if constexpr (std::is_same_v<T, double>)
102            std::cout << "Visiting double: " << arg << "\n";
103        else if constexpr (std::is_same_v<T, std::string>)
104            std::cout << "Visiting string: " << arg << "\n";
105    }, var);
106}
107
108// ============ std::any ============
109void demo_any() {
110    std::cout << "\n=== std::any ===\n";
111
112    std::any a = 42;
113    std::cout << "Any holds: " << std::any_cast<int>(a) << "\n";
114
115    a = 3.14;
116    std::cout << "Any holds: " << std::any_cast<double>(a) << "\n";
117
118    a = std::string("hello");
119    std::cout << "Any holds: " << std::any_cast<std::string>(a) << "\n";
120
121    if (a.has_value()) {
122        std::cout << "Any has a value of type: " << a.type().name() << "\n";
123    }
124}
125
126// ============ if constexpr ============
127template<typename T>
128void print_type(T value) {
129    if constexpr (std::is_integral_v<T>) {
130        std::cout << "Integer: " << value << "\n";
131    } else if constexpr (std::is_floating_point_v<T>) {
132        std::cout << "Float: " << value << "\n";
133    } else {
134        std::cout << "Other: " << value << "\n";
135    }
136}
137
138void demo_if_constexpr() {
139    std::cout << "\n=== if constexpr ===\n";
140    print_type(42);
141    print_type(3.14);
142    print_type("hello");
143}
144
145// ============ Fold Expressions ============
146template<typename... Args>
147auto sum(Args... args) {
148    return (args + ...);  // Unary right fold
149}
150
151template<typename... Args>
152void print_all(Args... args) {
153    ((std::cout << args << " "), ...);  // Binary left fold
154    std::cout << "\n";
155}
156
157void demo_fold_expressions() {
158    std::cout << "\n=== Fold Expressions ===\n";
159    std::cout << "Sum: " << sum(1, 2, 3, 4, 5) << "\n";
160    std::cout << "Print all: ";
161    print_all(1, "hello", 3.14, "world");
162}
163
164// ============ std::filesystem ============
165void demo_filesystem() {
166    std::cout << "\n=== std::filesystem ===\n";
167
168    fs::path current = fs::current_path();
169    std::cout << "Current directory: " << current << "\n";
170
171    // Create temporary directory and file
172    fs::path temp_dir = fs::temp_directory_path() / "cpp_demo";
173    if (!fs::exists(temp_dir)) {
174        fs::create_directory(temp_dir);
175        std::cout << "Created: " << temp_dir << "\n";
176    }
177
178    fs::path temp_file = temp_dir / "test.txt";
179    std::cout << "File exists: " << fs::exists(temp_file) << "\n";
180    std::cout << "Is directory: " << fs::is_directory(temp_dir) << "\n";
181
182    // Cleanup
183    if (fs::exists(temp_dir)) {
184        fs::remove_all(temp_dir);
185    }
186}
187
188// ============ C++20 Concepts Example ============
189void demo_concepts() {
190    std::cout << "\n=== C++20 Concepts ===\n";
191    std::cout << "add(10, 20) = " << add(10, 20) << "\n";
192    std::cout << "add(3.5, 1.5) = " << add(3.5, 1.5) << "\n";
193    // add("hello", "world");  // Compile error: doesn't satisfy Numeric
194}
195
196// ============ Main ============
197int main() {
198    std::cout << "Modern C++ Features Demo\n";
199    std::cout << "========================\n";
200
201    demo_structured_bindings();
202    demo_optional();
203    demo_variant();
204    demo_any();
205    demo_if_constexpr();
206    demo_fold_expressions();
207    demo_filesystem();
208    demo_concepts();
209
210    std::cout << "\nAll demos completed!\n";
211    return 0;
212}