Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
concepts_example.cpp
Go to the documentation of this file.
1
18
19#include <functional>
20#include <iostream>
21#include <memory>
22#include <string>
23#include <system_error>
24#include <vector>
25
26using namespace kcenon::network::concepts;
27
28// ============================================================================
29// Example 1: Using ByteBuffer concept
30// ============================================================================
31
36template<ByteBuffer Buffer>
37void send_buffer(const Buffer& buffer) {
38 std::cout << "Sending " << buffer.size() << " bytes from buffer\n";
39 // Access is compile-time guaranteed
40 const void* ptr = buffer.data();
41 (void)ptr; // Suppress unused warning in example
42}
43
45 std::cout << "=== ByteBuffer Concept ===\n";
46
47 // Works with std::vector<uint8_t>
48 std::vector<uint8_t> vec_buffer = {1, 2, 3, 4, 5};
49 send_buffer(vec_buffer);
50
51 // Works with std::string
52 std::string str_buffer = "Hello, Network!";
53 send_buffer(str_buffer);
54
55 // Works with std::array
56 std::array<uint8_t, 4> arr_buffer = {0xDE, 0xAD, 0xBE, 0xEF};
57 send_buffer(arr_buffer);
58
59 // The following would NOT compile (good!):
60 // int x = 42;
61 // send_buffer(x); // Error: 'int' does not satisfy 'ByteBuffer'
62
63 std::cout << "\n";
64}
65
66// ============================================================================
67// Example 2: Using MutableByteBuffer concept
68// ============================================================================
69
74template<MutableByteBuffer Buffer>
75void receive_into(Buffer& buffer, std::size_t expected_size) {
76 buffer.resize(expected_size);
77 std::cout << "Buffer resized to " << buffer.size() << " bytes\n";
78 // Fill with dummy data
79 for (std::size_t i = 0; i < buffer.size(); ++i) {
80 static_cast<uint8_t*>(buffer.data())[i] = static_cast<uint8_t>(i % 256);
81 }
82}
83
85 std::cout << "=== MutableByteBuffer Concept ===\n";
86
87 std::vector<uint8_t> buffer;
88 receive_into(buffer, 100);
89 std::cout << "Received data, first byte: " << static_cast<int>(buffer[0]) << "\n";
90
91 // std::array does NOT satisfy MutableByteBuffer (no resize)
92 // std::array<uint8_t, 10> arr;
93 // receive_into(arr, 5); // Error: no resize() method
94
95 std::cout << "\n";
96}
97
98// ============================================================================
99// Example 3: Using callback concepts
100// ============================================================================
101
106public:
111 template<DataReceiveHandler Handler>
112 void on_data(Handler&& handler) {
113 data_handler_ = std::forward<Handler>(handler);
114 std::cout << "Data handler registered\n";
115 }
116
121 template<ErrorHandler Handler>
122 void on_error(Handler&& handler) {
123 error_handler_ = std::forward<Handler>(handler);
124 std::cout << "Error handler registered\n";
125 }
126
131 template<ConnectionHandler Handler>
132 void on_connect(Handler&& handler) {
133 connect_handler_ = std::forward<Handler>(handler);
134 std::cout << "Connect handler registered\n";
135 }
136
141 template<RetryCallback Handler>
142 void on_retry(Handler&& handler) {
143 retry_handler_ = std::forward<Handler>(handler);
144 std::cout << "Retry handler registered\n";
145 }
146
147 // Simulate events for demonstration
149 std::cout << "\nSimulating events:\n";
150
151 if (connect_handler_) {
152 std::cout << " -> Connection event: ";
154 }
155
156 if (data_handler_) {
157 std::vector<uint8_t> data = {72, 101, 108, 108, 111}; // "Hello"
158 std::cout << " -> Data event: ";
159 data_handler_(data);
160 }
161
162 if (retry_handler_) {
163 std::cout << " -> Retry event: ";
165 }
166
167 if (error_handler_) {
168 std::cout << " -> Error event: ";
169 error_handler_(std::make_error_code(std::errc::connection_refused));
170 }
171 }
172
173private:
174 std::function<void(const std::vector<uint8_t>&)> data_handler_;
175 std::function<void(std::error_code)> error_handler_;
176 std::function<void()> connect_handler_;
177 std::function<void(std::size_t)> retry_handler_;
178};
179
181 std::cout << "=== Callback Concepts ===\n";
182
183 ConceptClient client;
184
185 // Lambda callbacks - all types are validated at compile time
186 client.on_data([](const std::vector<uint8_t>& data) {
187 std::cout << "Received " << data.size() << " bytes\n";
188 });
189
190 client.on_error([](std::error_code ec) {
191 std::cout << "Error: " << ec.message() << "\n";
192 });
193
194 client.on_connect([]() {
195 std::cout << "Connected!\n";
196 });
197
198 client.on_retry([](std::size_t attempt) {
199 std::cout << "Retry attempt #" << attempt << "\n";
200 });
201
202 client.simulate_events();
203
204 // Invalid callbacks would fail at compile time:
205 // client.on_data([](int x) {}); // Wrong parameter type
206 // client.on_error([](std::string s) {}); // Wrong parameter type
207 // client.on_connect([](int x) {}); // Handler should take no args
208
209 std::cout << "\n";
210}
211
212// ============================================================================
213// Example 4: Using NetworkClient concept
214// ============================================================================
215
220public:
221 bool is_connected() const { return connected_; }
222
223 void send_packet(std::vector<uint8_t> data) {
224 std::cout << "Mock: sent " << data.size() << " bytes\n";
225 }
226
227 void stop_client() {
228 connected_ = false;
229 std::cout << "Mock: client stopped\n";
230 }
231
232 void connect() {
233 connected_ = true;
234 std::cout << "Mock: client connected\n";
235 }
236
237private:
238 bool connected_ = false;
239};
240
245template<NetworkClient Client>
246void use_client(Client& client, const std::string& message) {
247 if (!client.is_connected()) {
248 std::cout << "Client not connected, cannot send\n";
249 return;
250 }
251
252 std::vector<uint8_t> data(message.begin(), message.end());
253 client.send_packet(std::move(data));
254}
255
257 std::cout << "=== NetworkClient Concept ===\n";
258
259 MockNetworkClient client;
260
261 // Try to send before connecting
262 use_client(client, "Hello");
263
264 // Connect and send
265 client.connect();
266 use_client(client, "Hello, World!");
267
268 // Stop client
269 client.stop_client();
270
271 std::cout << "\n";
272}
273
274// ============================================================================
275// Example 5: Using DataTransformer concept
276// ============================================================================
277
282public:
283 explicit XorTransformer(uint8_t key) : key_(key) {}
284
285 bool transform(std::vector<uint8_t>& data) {
286 for (auto& byte : data) {
287 byte ^= key_;
288 }
289 return true;
290 }
291
292 bool reverse_transform(std::vector<uint8_t>& data) {
293 // XOR is its own inverse
294 return transform(data);
295 }
296
297private:
298 uint8_t key_;
299};
300
305template<ReversibleDataTransformer T>
306void process_bidirectional(T& transformer, std::vector<uint8_t>& data) {
307 std::cout << "Original: ";
308 for (auto b : data) std::cout << static_cast<char>(b);
309 std::cout << "\n";
310
311 transformer.transform(data);
312 std::cout << "Transformed: ";
313 for (auto b : data) std::cout << std::hex << static_cast<int>(b) << " ";
314 std::cout << std::dec << "\n";
315
316 transformer.reverse_transform(data);
317 std::cout << "Restored: ";
318 for (auto b : data) std::cout << static_cast<char>(b);
319 std::cout << "\n";
320}
321
323 std::cout << "=== DataTransformer Concept ===\n";
324
325 XorTransformer xor_transform(0x42);
326 std::vector<uint8_t> data = {'H', 'e', 'l', 'l', 'o'};
327
328 process_bidirectional(xor_transform, data);
329
330 std::cout << "\n";
331}
332
333// ============================================================================
334// Example 6: Using Duration concept
335// ============================================================================
336
341template<Duration D>
342void set_timeout(D duration) {
343 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);
344 std::cout << "Timeout set to " << ms.count() << " milliseconds\n";
345}
346
348 std::cout << "=== Duration Concept ===\n";
349
350 set_timeout(std::chrono::seconds(30));
351 set_timeout(std::chrono::milliseconds(500));
352 set_timeout(std::chrono::microseconds(100000));
353
354 // Invalid: raw integers don't satisfy Duration
355 // set_timeout(5); // Error: 'int' does not satisfy 'Duration'
356
357 std::cout << "\n";
358}
359
360// ============================================================================
361// Example 7: Compile-time error demonstration (commented out)
362// ============================================================================
363
364/*
365 * Uncomment any of these to see the improved error messages with concepts:
366 *
367 * void demonstrate_compile_errors() {
368 * // Error: 'int' does not satisfy 'ByteBuffer'
369 * // because it lacks data() and size() methods
370 * send_buffer(42);
371 *
372 * // Error: 'std::array<uint8_t, 10>' does not satisfy 'MutableByteBuffer'
373 * // because it lacks resize() method
374 * std::array<uint8_t, 10> arr;
375 * receive_into(arr, 5);
376 *
377 * // Error: lambda does not satisfy 'DataReceiveHandler'
378 * // because it's not invocable with const std::vector<uint8_t>&
379 * ConceptClient client;
380 * client.on_data([](int x) {});
381 *
382 * // Error: 'int' does not satisfy 'Duration'
383 * // because it lacks rep and period type members
384 * set_timeout(100);
385 * }
386 */
387
388// ============================================================================
389// Main
390// ============================================================================
391
392int main() {
393 std::cout << "==============================================\n";
394 std::cout << "Network System - C++20 Concepts Example\n";
395 std::cout << "==============================================\n\n";
396
403
404 std::cout << "==============================================\n";
405 std::cout << "All examples completed successfully!\n";
406 std::cout << "==============================================\n";
407
408 return 0;
409}
A client class demonstrating concept-constrained callbacks.
std::function< void(const std::vector< uint8_t > &)> data_handler_
void on_error(Handler &&handler)
Set error handler.
void on_retry(Handler &&handler)
Set retry callback.
std::function< void()> connect_handler_
std::function< void(std::size_t)> retry_handler_
std::function< void(std::error_code)> error_handler_
void on_connect(Handler &&handler)
Set connection handler.
void on_data(Handler &&handler)
Set data receive handler.
A mock client satisfying NetworkClient concept.
void send_packet(std::vector< uint8_t > data)
A simple XOR "encryption" transformer.
bool transform(std::vector< uint8_t > &data)
bool reverse_transform(std::vector< uint8_t > &data)
XorTransformer(uint8_t key)
Unified header for all C++20 concepts in network_system.
void send_buffer(const Buffer &buffer)
Send data from any buffer type satisfying ByteBuffer concept.
void set_timeout(D duration)
Set a timeout using any duration type.
void demonstrate_network_client()
void demonstrate_mutable_buffer()
void demonstrate_transformer()
void demonstrate_callbacks()
void demonstrate_duration()
void demonstrate_byte_buffer()
void receive_into(Buffer &buffer, std::size_t expected_size)
Receive data into a resizable buffer.
void process_bidirectional(T &transformer, std::vector< uint8_t > &data)
Apply a reversible transformer to data.
int main()
void use_client(Client &client, const std::string &message)
Generic function that works with any NetworkClient.
C++20 concepts for compile-time type validation in network_system.