diff --git a/code/examples/chapter07/03_circular_buffer/CMakeLists.txt b/code/examples/chapter08/08_circular_buffer/CMakeLists.txt similarity index 90% rename from code/examples/chapter07/03_circular_buffer/CMakeLists.txt rename to code/examples/chapter08/08_circular_buffer/CMakeLists.txt index 9dd22ddc3..8d90e36d0 100644 --- a/code/examples/chapter07/03_circular_buffer/CMakeLists.txt +++ b/code/examples/chapter08/08_circular_buffer/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.20) -project(chapter07_03_circular_buffer CXX) +project(chapter08_08_circular_buffer CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/code/examples/chapter07/03_circular_buffer/README.md b/code/examples/chapter08/08_circular_buffer/README.md similarity index 100% rename from code/examples/chapter07/03_circular_buffer/README.md rename to code/examples/chapter08/08_circular_buffer/README.md diff --git a/code/examples/chapter07/03_circular_buffer/atomic_ring_buffer.h b/code/examples/chapter08/08_circular_buffer/atomic_ring_buffer.h similarity index 85% rename from code/examples/chapter07/03_circular_buffer/atomic_ring_buffer.h rename to code/examples/chapter08/08_circular_buffer/atomic_ring_buffer.h index 51f609752..89d7d866d 100644 --- a/code/examples/chapter07/03_circular_buffer/atomic_ring_buffer.h +++ b/code/examples/chapter08/08_circular_buffer/atomic_ring_buffer.h @@ -1,69 +1,68 @@ -// atomic_ring_buffer.h - 线程安全的循环缓冲区实现 -#pragma once -#include -#include -#include - -template -class AtomicRingBuffer { -public: - AtomicRingBuffer() : head_(0), tail_(0) {} - - bool push(const T& value) { - std::size_t head = head_.load(std::memory_order_relaxed); - std::size_t next_head = (head + 1) % Capacity; - std::size_t tail = tail_.load(std::memory_order_acquire); - - if (next_head == tail) { - return false; // 缓冲区满了 - } - - buffer_[head] = value; - head_.store(next_head, std::memory_order_release); - return true; - } - - bool pop(T& out) { - std::size_t tail = tail_.load(std::memory_order_relaxed); - std::size_t head = head_.load(std::memory_order_acquire); - - if (tail == head) { - return false; // 没数据 - } - - out = buffer_[tail]; - std::size_t next_tail = (tail + 1) % Capacity; - tail_.store(next_tail, std::memory_order_release); - return true; - } - - bool empty() const { - std::size_t head = head_.load(std::memory_order_acquire); - std::size_t tail = tail_.load(std::memory_order_acquire); - return head == tail; - } - - bool full() const { - std::size_t head = head_.load(std::memory_order_acquire); - std::size_t tail = tail_.load(std::memory_order_acquire); - return (head + 1) % Capacity == tail; - } - - std::size_t size() const { - std::size_t head = head_.load(std::memory_order_acquire); - std::size_t tail = tail_.load(std::memory_order_acquire); - if (head >= tail) { - return head - tail; - } - return Capacity - (tail - head); - } - - std::size_t capacity() const { - return Capacity - 1; // 实际可用容量 - } - -private: - std::array buffer_; - std::atomic head_; - std::atomic tail_; -}; +// atomic_ring_buffer.h - 线程安全的循环缓冲区实现 +#pragma once +#include +#include +#include + +template class AtomicRingBuffer { + public: + AtomicRingBuffer() : head_(0), tail_(0) {} + + bool push(const T& value) { + std::size_t head = head_.load(std::memory_order_relaxed); + std::size_t next_head = (head + 1) % Capacity; + std::size_t tail = tail_.load(std::memory_order_acquire); + + if (next_head == tail) { + return false; // 缓冲区满了 + } + + buffer_[head] = value; + head_.store(next_head, std::memory_order_release); + return true; + } + + bool pop(T& out) { + std::size_t tail = tail_.load(std::memory_order_relaxed); + std::size_t head = head_.load(std::memory_order_acquire); + + if (tail == head) { + return false; // 没数据 + } + + out = buffer_[tail]; + std::size_t next_tail = (tail + 1) % Capacity; + tail_.store(next_tail, std::memory_order_release); + return true; + } + + bool empty() const { + std::size_t head = head_.load(std::memory_order_acquire); + std::size_t tail = tail_.load(std::memory_order_acquire); + return head == tail; + } + + bool full() const { + std::size_t head = head_.load(std::memory_order_acquire); + std::size_t tail = tail_.load(std::memory_order_acquire); + return (head + 1) % Capacity == tail; + } + + std::size_t size() const { + std::size_t head = head_.load(std::memory_order_acquire); + std::size_t tail = tail_.load(std::memory_order_acquire); + if (head >= tail) { + return head - tail; + } + return Capacity - (tail - head); + } + + std::size_t capacity() const { + return Capacity - 1; // 实际可用容量 + } + + private: + std::array buffer_; + std::atomic head_; + std::atomic tail_; +}; diff --git a/code/examples/chapter07/03_circular_buffer/basic_example.cpp b/code/examples/chapter08/08_circular_buffer/basic_example.cpp similarity index 96% rename from code/examples/chapter07/03_circular_buffer/basic_example.cpp rename to code/examples/chapter08/08_circular_buffer/basic_example.cpp index a8e7fe4ec..9aef0050b 100644 --- a/code/examples/chapter07/03_circular_buffer/basic_example.cpp +++ b/code/examples/chapter08/08_circular_buffer/basic_example.cpp @@ -1,50 +1,50 @@ -// basic_example.cpp - 循环缓冲区基本用法演示 -#include "ring_buffer.h" -#include - -int main() { - // 创建一个容量为 16 的循环缓冲区(实际可用 15) - RingBuffer buffer; - - std::cout << "Ring Buffer Demo\n"; - std::cout << "Capacity: " << buffer.capacity() << "\n\n"; - - // 测试:填充和读取 - std::cout << "=== Pushing 10 elements ===\n"; - for (int i = 0; i < 10; ++i) { - if (buffer.push(i)) { - std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n'; - } - } - - std::cout << "\n=== Popping 5 elements ===\n"; - for (int i = 0; i < 5; ++i) { - int value; - if (buffer.pop(value)) { - std::cout << "Popped: " << value << ", size: " << buffer.size() << '\n'; - } - } - - std::cout << "\n=== Pushing 8 more elements ===\n"; - for (int i = 10; i < 18; ++i) { - if (buffer.push(i)) { - std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n'; - } else { - std::cout << "Failed to push: " << i << " (buffer full)\n"; - } - } - - std::cout << "\n=== Remaining contents ===\n"; - while (!buffer.empty()) { - int value; - buffer.pop(value); - std::cout << value << ' '; - } - std::cout << "\n"; - - std::cout << "\nFinal size: " << buffer.size() << '\n'; - std::cout << "Empty: " << (buffer.empty() ? "yes" : "no") << '\n'; - std::cout << "Full: " << (buffer.full() ? "yes" : "no") << '\n'; - - return 0; -} +// basic_example.cpp - 循环缓冲区基本用法演示 +#include "ring_buffer.h" +#include + +int main() { + // 创建一个容量为 16 的循环缓冲区(实际可用 15) + RingBuffer buffer; + + std::cout << "Ring Buffer Demo\n"; + std::cout << "Capacity: " << buffer.capacity() << "\n\n"; + + // 测试:填充和读取 + std::cout << "=== Pushing 10 elements ===\n"; + for (int i = 0; i < 10; ++i) { + if (buffer.push(i)) { + std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n'; + } + } + + std::cout << "\n=== Popping 5 elements ===\n"; + for (int i = 0; i < 5; ++i) { + int value; + if (buffer.pop(value)) { + std::cout << "Popped: " << value << ", size: " << buffer.size() << '\n'; + } + } + + std::cout << "\n=== Pushing 8 more elements ===\n"; + for (int i = 10; i < 18; ++i) { + if (buffer.push(i)) { + std::cout << "Pushed: " << i << ", size: " << buffer.size() << '\n'; + } else { + std::cout << "Failed to push: " << i << " (buffer full)\n"; + } + } + + std::cout << "\n=== Remaining contents ===\n"; + while (!buffer.empty()) { + int value; + buffer.pop(value); + std::cout << value << ' '; + } + std::cout << "\n"; + + std::cout << "\nFinal size: " << buffer.size() << '\n'; + std::cout << "Empty: " << (buffer.empty() ? "yes" : "no") << '\n'; + std::cout << "Full: " << (buffer.full() ? "yes" : "no") << '\n'; + + return 0; +} diff --git a/code/examples/chapter07/03_circular_buffer/ring_buffer.h b/code/examples/chapter08/08_circular_buffer/ring_buffer.h similarity index 60% rename from code/examples/chapter07/03_circular_buffer/ring_buffer.h rename to code/examples/chapter08/08_circular_buffer/ring_buffer.h index 2b6e760e5..9f0f71f15 100644 --- a/code/examples/chapter07/03_circular_buffer/ring_buffer.h +++ b/code/examples/chapter08/08_circular_buffer/ring_buffer.h @@ -1,56 +1,49 @@ -// ring_buffer.h - 简单的循环缓冲区实现 -#pragma once -#include -#include - -template -class RingBuffer { -public: - bool push(const T& value) { - if (full()) { - return false; // 缓冲区满了 - } - - buffer_[head_] = value; - head_ = (head_ + 1) % Capacity; - return true; - } - - bool pop(T& out) { - if (empty()) { - return false; // 没数据 - } - - out = buffer_[tail_]; - tail_ = (tail_ + 1) % Capacity; - return true; - } - - bool empty() const { - return head_ == tail_; - } - - bool full() const { - return (head_ + 1) % Capacity == tail_; - } - - std::size_t size() const { - if (head_ >= tail_) { - return head_ - tail_; - } - return Capacity - (tail_ - head_); - } - - std::size_t capacity() const { - return Capacity - 1; // 实际可用容量 - } - - void clear() { - head_ = tail_ = 0; - } - -private: - std::array buffer_{}; - std::size_t head_ = 0; - std::size_t tail_ = 0; -}; +// ring_buffer.h - 简单的循环缓冲区实现 +#pragma once +#include +#include + +template class RingBuffer { + public: + bool push(const T& value) { + if (full()) { + return false; // 缓冲区满了 + } + + buffer_[head_] = value; + head_ = (head_ + 1) % Capacity; + return true; + } + + bool pop(T& out) { + if (empty()) { + return false; // 没数据 + } + + out = buffer_[tail_]; + tail_ = (tail_ + 1) % Capacity; + return true; + } + + bool empty() const { return head_ == tail_; } + + bool full() const { return (head_ + 1) % Capacity == tail_; } + + std::size_t size() const { + if (head_ >= tail_) { + return head_ - tail_; + } + return Capacity - (tail_ - head_); + } + + std::size_t capacity() const { + return Capacity - 1; // 实际可用容量 + } + + void clear() { head_ = tail_ = 0; } + + private: + std::array buffer_{}; + std::size_t head_ = 0; + std::size_t tail_ = 0; +}; diff --git a/code/examples/chapter07/03_circular_buffer/thread_safe_example.cpp b/code/examples/chapter08/08_circular_buffer/thread_safe_example.cpp similarity index 96% rename from code/examples/chapter07/03_circular_buffer/thread_safe_example.cpp rename to code/examples/chapter08/08_circular_buffer/thread_safe_example.cpp index 043a3e04b..7c4a42cd1 100644 --- a/code/examples/chapter07/03_circular_buffer/thread_safe_example.cpp +++ b/code/examples/chapter08/08_circular_buffer/thread_safe_example.cpp @@ -1,88 +1,88 @@ -// thread_safe_example.cpp - 多线程安全的循环缓冲区演示 -#include "atomic_ring_buffer.h" -#include -#include -#include -#include - -// 多生产者-多消费者测试 -const int PRODUCER_COUNT = 2; -const int CONSUMER_COUNT = 2; -const int ITEMS_PER_PRODUCER = 100; - -AtomicRingBuffer shared_buffer; - -// 生产者线程 -void producer(int id) { - for (int i = 0; i < ITEMS_PER_PRODUCER; ++i) { - int value = id * 1000 + i; - while (!shared_buffer.push(value)) { - // 缓冲区满,等待 - std::this_thread::yield(); - } - // 模拟生产时间 - std::this_thread::sleep_for(std::chrono::microseconds(rand() % 100)); - } - std::cout << "Producer " << id << " finished.\n"; -} - -// 消费者线程 -void consumer(int id) { - int consumed = 0; - int value; - while (consumed < (PRODUCER_COUNT * ITEMS_PER_PRODUCER) / CONSUMER_COUNT) { - if (shared_buffer.pop(value)) { - ++consumed; - // std::cout << "Consumer " << id << " got: " << value << '\n'; - } else { - // 缓冲区空,等待 - std::this_thread::yield(); - } - } - std::cout << "Consumer " << id << " consumed " << consumed << " items.\n"; -} - -int main() { - std::cout << "=== Thread-Safe Ring Buffer Demo ===\n\n"; - - std::vector producers; - std::vector consumers; - - auto start = std::chrono::steady_clock::now(); - - // 启动消费者 - for (int i = 0; i < CONSUMER_COUNT; ++i) { - consumers.emplace_back(consumer, i); - } - - // 启动生产者 - for (int i = 0; i < PRODUCER_COUNT; ++i) { - producers.emplace_back(producer, i); - } - - // 等待所有生产者完成 - for (auto& p : producers) { - p.join(); - } - - // 等待所有消费者完成 - for (auto& c : consumers) { - c.join(); - } - - auto end = std::chrono::steady_clock::now(); - auto duration = std::chrono::duration_cast(end - start); - - std::cout << "\n=== Test Completed ===\n"; - std::cout << "Time taken: " << duration.count() << " ms\n"; - std::cout << "Final buffer size: " << shared_buffer.size() << '\n'; - std::cout << "Buffer empty: " << (shared_buffer.empty() ? "yes" : "no") << '\n'; - - std::cout << "\nKey points:\n"; - std::cout << "- Uses atomic operations for lock-free synchronization\n"; - std::cout << "- Memory ordering ensures correct visibility across threads\n"; - std::cout << "- Suitable for single-producer single-consumer scenarios\n"; - std::cout << "- For multiple producers/consumers, consider external locking\n"; - - return 0; -} +// thread_safe_example.cpp - 多线程安全的循环缓冲区演示 +#include "atomic_ring_buffer.h" +#include +#include +#include +#include + +// 多生产者-多消费者测试 +const int PRODUCER_COUNT = 2; +const int CONSUMER_COUNT = 2; +const int ITEMS_PER_PRODUCER = 100; + +AtomicRingBuffer shared_buffer; + +// 生产者线程 +void producer(int id) { + for (int i = 0; i < ITEMS_PER_PRODUCER; ++i) { + int value = id * 1000 + i; + while (!shared_buffer.push(value)) { + // 缓冲区满,等待 + std::this_thread::yield(); + } + // 模拟生产时间 + std::this_thread::sleep_for(std::chrono::microseconds(rand() % 100)); + } + std::cout << "Producer " << id << " finished.\n"; +} + +// 消费者线程 +void consumer(int id) { + int consumed = 0; + int value; + while (consumed < (PRODUCER_COUNT * ITEMS_PER_PRODUCER) / CONSUMER_COUNT) { + if (shared_buffer.pop(value)) { + ++consumed; + // std::cout << "Consumer " << id << " got: " << value << '\n'; + } else { + // 缓冲区空,等待 + std::this_thread::yield(); + } + } + std::cout << "Consumer " << id << " consumed " << consumed << " items.\n"; +} + +int main() { + std::cout << "=== Thread-Safe Ring Buffer Demo ===\n\n"; + + std::vector producers; + std::vector consumers; + + auto start = std::chrono::steady_clock::now(); + + // 启动消费者 + for (int i = 0; i < CONSUMER_COUNT; ++i) { + consumers.emplace_back(consumer, i); + } + + // 启动生产者 + for (int i = 0; i < PRODUCER_COUNT; ++i) { + producers.emplace_back(producer, i); + } + + // 等待所有生产者完成 + for (auto& p : producers) { + p.join(); + } + + // 等待所有消费者完成 + for (auto& c : consumers) { + c.join(); + } + + auto end = std::chrono::steady_clock::now(); + auto duration = std::chrono::duration_cast(end - start); + + std::cout << "\n=== Test Completed ===\n"; + std::cout << "Time taken: " << duration.count() << " ms\n"; + std::cout << "Final buffer size: " << shared_buffer.size() << '\n'; + std::cout << "Buffer empty: " << (shared_buffer.empty() ? "yes" : "no") << '\n'; + + std::cout << "\nKey points:\n"; + std::cout << "- Uses atomic operations for lock-free synchronization\n"; + std::cout << "- Memory ordering ensures correct visibility across threads\n"; + std::cout << "- Suitable for single-producer single-consumer scenarios\n"; + std::cout << "- For multiple producers/consumers, consider external locking\n"; + + return 0; +} diff --git a/code/examples/chapter07/03_circular_buffer/uart_example.cpp b/code/examples/chapter08/08_circular_buffer/uart_example.cpp similarity index 94% rename from code/examples/chapter07/03_circular_buffer/uart_example.cpp rename to code/examples/chapter08/08_circular_buffer/uart_example.cpp index 0eb985a89..874c4ac48 100644 --- a/code/examples/chapter07/03_circular_buffer/uart_example.cpp +++ b/code/examples/chapter08/08_circular_buffer/uart_example.cpp @@ -1,85 +1,85 @@ -// uart_example.cpp - 模拟 UART 串口接收场景 -#include "ring_buffer.h" -#include -#include -#include -#include -#include -#include - -// 模拟硬件寄存器 -std::atomic uart_data_ready{false}; -std::atomic uart_rx_reg{0}; - -// 接收缓冲区 -RingBuffer rx_buffer; - -// 模拟 UART 硬件接收中断 -void USART_IRQHandler() { - // 在真实硬件中,这是由硬件触发的中断 - uint8_t data = uart_rx_reg.load(); - uart_data_ready.store(false); - - // 中断里只做这件事:把数据放入缓冲区 - if (!rx_buffer.push(data)) { - std::cout << "[ISR] Buffer overrun! Data lost.\n"; - } -} - -// 模拟 UART 接收线程(模拟硬件产生数据) -void uart_rx_thread() { - const char* test_message = "Hello, Embedded World!"; - size_t index = 0; - - while (test_message[index] != '\0') { - // 模拟硬件接收一个字节 - uart_rx_reg.store(static_cast(test_message[index])); - uart_data_ready.store(true); - - // 触发中断(模拟) - USART_IRQHandler(); - - ++index; - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } -} - -// 处理单个字符 -void process_char(uint8_t ch) { - if (ch >= 32 && ch < 127) { - std::cout << "Processing: '" << static_cast(ch) << "'\n"; - } else { - std::cout << "Processing: 0x" << std::hex << static_cast(ch) << std::dec << '\n'; - } -} - -int main() { - std::cout << "=== UART Circular Buffer Example ===\n\n"; - - // 启动模拟 UART 接收线程 - std::thread uart_thread(uart_rx_thread); - - // 主循环:处理接收到的数据 - int idle_count = 0; - while (idle_count < 50) { // 运行一段时间后退出 - uint8_t ch; - if (rx_buffer.pop(ch)) { - process_char(ch); - idle_count = 0; - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ++idle_count; - } - } - - uart_thread.join(); - - std::cout << "\n=== Summary ===\n"; - std::cout << "Buffer size: " << rx_buffer.size() << '\n'; - std::cout << "This pattern demonstrates:\n"; - std::cout << "- ISR pushes data quickly\n"; - std::cout << "- Main loop processes at its own pace\n"; - std::cout << "- No malloc, deterministic behavior\n"; - - return 0; -} +// uart_example.cpp - 模拟 UART 串口接收场景 +#include "ring_buffer.h" +#include +#include +#include +#include +#include +#include + +// 模拟硬件寄存器 +std::atomic uart_data_ready{false}; +std::atomic uart_rx_reg{0}; + +// 接收缓冲区 +RingBuffer rx_buffer; + +// 模拟 UART 硬件接收中断 +void USART_IRQHandler() { + // 在真实硬件中,这是由硬件触发的中断 + uint8_t data = uart_rx_reg.load(); + uart_data_ready.store(false); + + // 中断里只做这件事:把数据放入缓冲区 + if (!rx_buffer.push(data)) { + std::cout << "[ISR] Buffer overrun! Data lost.\n"; + } +} + +// 模拟 UART 接收线程(模拟硬件产生数据) +void uart_rx_thread() { + const char* test_message = "Hello, Embedded World!"; + size_t index = 0; + + while (test_message[index] != '\0') { + // 模拟硬件接收一个字节 + uart_rx_reg.store(static_cast(test_message[index])); + uart_data_ready.store(true); + + // 触发中断(模拟) + USART_IRQHandler(); + + ++index; + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } +} + +// 处理单个字符 +void process_char(uint8_t ch) { + if (ch >= 32 && ch < 127) { + std::cout << "Processing: '" << static_cast(ch) << "'\n"; + } else { + std::cout << "Processing: 0x" << std::hex << static_cast(ch) << std::dec << '\n'; + } +} + +int main() { + std::cout << "=== UART Circular Buffer Example ===\n\n"; + + // 启动模拟 UART 接收线程 + std::thread uart_thread(uart_rx_thread); + + // 主循环:处理接收到的数据 + int idle_count = 0; + while (idle_count < 50) { // 运行一段时间后退出 + uint8_t ch; + if (rx_buffer.pop(ch)) { + process_char(ch); + idle_count = 0; + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + ++idle_count; + } + } + + uart_thread.join(); + + std::cout << "\n=== Summary ===\n"; + std::cout << "Buffer size: " << rx_buffer.size() << '\n'; + std::cout << "This pattern demonstrates:\n"; + std::cout << "- ISR pushes data quickly\n"; + std::cout << "- Main loop processes at its own pace\n"; + std::cout << "- No malloc, deterministic behavior\n"; + + return 0; +} diff --git a/code/examples/chapter07/04_intrusive_container/CMakeLists.txt b/code/examples/chapter08/09_intrusive_container/CMakeLists.txt similarity index 90% rename from code/examples/chapter07/04_intrusive_container/CMakeLists.txt rename to code/examples/chapter08/09_intrusive_container/CMakeLists.txt index 96be08b82..5cc47380a 100644 --- a/code/examples/chapter07/04_intrusive_container/CMakeLists.txt +++ b/code/examples/chapter08/09_intrusive_container/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.20) -project(chapter07_04_intrusive_container CXX) +project(chapter08_09_intrusive_container CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/code/examples/chapter07/04_intrusive_container/README.md b/code/examples/chapter08/09_intrusive_container/README.md similarity index 100% rename from code/examples/chapter07/04_intrusive_container/README.md rename to code/examples/chapter08/09_intrusive_container/README.md diff --git a/code/examples/chapter07/04_intrusive_container/inheritance_example.cpp b/code/examples/chapter08/09_intrusive_container/inheritance_example.cpp similarity index 92% rename from code/examples/chapter07/04_intrusive_container/inheritance_example.cpp rename to code/examples/chapter08/09_intrusive_container/inheritance_example.cpp index 748c6dd08..4097c7aaa 100644 --- a/code/examples/chapter07/04_intrusive_container/inheritance_example.cpp +++ b/code/examples/chapter08/09_intrusive_container/inheritance_example.cpp @@ -1,57 +1,57 @@ -// inheritance_example.cpp - 继承式侵入链表示例 -#include "intrusive_list.h" -#include - -struct Task : IntrusiveListNode { - int id; - const char* name; - - Task(int i, const char* n) : id(i), name(n) {} -}; - -int main() { - IntrusiveList runq; - - // 创建任务对象 - Task task1(1, "Task A"); - Task task2(2, "Task B"); - Task task3(3, "Task C"); - - std::cout << "=== Pushing tasks to queue ===\n"; - - // 添加到队列 - runq.push_back(&task1); - runq.push_back(&task2); - runq.push_front(&task3); // 链表顺序: task3, task1, task2 - - std::cout << "\nQueue contents:\n"; - for (auto& t : runq) { - std::cout << " Task " << t.id << ": " << t.name << '\n'; - } - - std::cout << "\n=== Removing task1 ===\n"; - runq.erase(&task1); - - std::cout << "Queue contents after erase:\n"; - for (auto& t : runq) { - std::cout << " Task " << t.id << ": " << t.name << '\n'; - } - - std::cout << "\n=== Popping from front ===\n"; - while (auto p = runq.pop_front()) { - std::cout << " Popped: Task " << p->id << ": " << p->name << '\n'; - } - - std::cout << "\nQueue empty: " << (runq.empty() ? "yes" : "no") << '\n'; - - // 演示错误检查(断言会触发) - std::cout << "\n=== Error handling demo ===\n"; - Task task4(4, "Task D"); - runq.push_back(&task4); - - std::cout << "Attempting to push already-linked node (should assert):\n"; - std::cout << "(Commented out to prevent crash)\n"; - // runq.push_back(&task4); // 这会触发断言 - - return 0; -} +// inheritance_example.cpp - 继承式侵入链表示例 +#include "intrusive_list.h" +#include + +struct Task : IntrusiveListNode { + int id; + const char* name; + + Task(int i, const char* n) : id(i), name(n) {} +}; + +int main() { + IntrusiveList runq; + + // 创建任务对象 + Task task1(1, "Task A"); + Task task2(2, "Task B"); + Task task3(3, "Task C"); + + std::cout << "=== Pushing tasks to queue ===\n"; + + // 添加到队列 + runq.push_back(&task1); + runq.push_back(&task2); + runq.push_front(&task3); // 链表顺序: task3, task1, task2 + + std::cout << "\nQueue contents:\n"; + for (auto& t : runq) { + std::cout << " Task " << t.id << ": " << t.name << '\n'; + } + + std::cout << "\n=== Removing task1 ===\n"; + runq.erase(&task1); + + std::cout << "Queue contents after erase:\n"; + for (auto& t : runq) { + std::cout << " Task " << t.id << ": " << t.name << '\n'; + } + + std::cout << "\n=== Popping from front ===\n"; + while (auto p = runq.pop_front()) { + std::cout << " Popped: Task " << p->id << ": " << p->name << '\n'; + } + + std::cout << "\nQueue empty: " << (runq.empty() ? "yes" : "no") << '\n'; + + // 演示错误检查(断言会触发) + std::cout << "\n=== Error handling demo ===\n"; + Task task4(4, "Task D"); + runq.push_back(&task4); + + std::cout << "Attempting to push already-linked node (should assert):\n"; + std::cout << "(Commented out to prevent crash)\n"; + // runq.push_back(&task4); // 这会触发断言 + + return 0; +} diff --git a/code/examples/chapter07/04_intrusive_container/intrusive_list.h b/code/examples/chapter08/09_intrusive_container/intrusive_list.h similarity index 67% rename from code/examples/chapter07/04_intrusive_container/intrusive_list.h rename to code/examples/chapter08/09_intrusive_container/intrusive_list.h index 858fe76c1..440251d09 100644 --- a/code/examples/chapter07/04_intrusive_container/intrusive_list.h +++ b/code/examples/chapter08/09_intrusive_container/intrusive_list.h @@ -1,92 +1,109 @@ -// intrusive_list.h - 简单、类型安全的侵入式双向链表(继承式) -#pragma once -#include -#include - -// Intrusive list node base — 继承它即可成为链表节点 -template -struct IntrusiveListNode { - T* prev = nullptr; - T* next = nullptr; -}; - -// Intrusive doubly linked list -template -class IntrusiveList { -public: - IntrusiveList() : head(nullptr), tail(nullptr) {} - - bool empty() const { return head == nullptr; } - - void push_front(T* node) { - assert(node && node->prev == nullptr && node->next == nullptr && "节点必须处于未链接状态"); - node->next = head; - if (head) head->prev = node; - head = node; - if (!tail) tail = node; - } - - void push_back(T* node) { - assert(node && node->prev == nullptr && node->next == nullptr && "节点必须处于未链接状态"); - node->prev = tail; - if (tail) tail->next = node; - tail = node; - if (!head) head = node; - } - - T* pop_front() { - if (!head) return nullptr; - T* n = head; - head = head->next; - if (head) head->prev = nullptr; - else tail = nullptr; - n->next = n->prev = nullptr; - return n; - } - - void erase(T* node) { - assert(node && "erase null"); - if (node->prev) node->prev->next = node->next; - else head = node->next; - - if (node->next) node->next->prev = node->prev; - else tail = node->prev; - - node->prev = node->next = nullptr; - } - - void clear() { - T* cur = head; - while (cur) { - T* nxt = cur->next; - cur->prev = cur->next = nullptr; - cur = nxt; - } - head = tail = nullptr; - } - - // 简单迭代器(只读/可写) - struct iterator { - using iterator_category = std::forward_iterator_tag; - using value_type = T; - using pointer = T*; - using reference = T&; - - explicit iterator(T* p) : p(p) {} - reference operator*() const { return *p; } - pointer operator->() const { return p; } - iterator& operator++() { p = p->next; return *this; } - iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } - bool operator==(const iterator& o) const { return p == o.p; } - bool operator!=(const iterator& o) const { return p != o.p; } - private: - T* p; - }; - - iterator begin() { return iterator(head); } - iterator end() { return iterator(nullptr); } - -private: - T* head; - T* tail; -}; +// intrusive_list.h - 简单、类型安全的侵入式双向链表(继承式) +#pragma once +#include +#include + +// Intrusive list node base — 继承它即可成为链表节点 +template struct IntrusiveListNode { + T* prev = nullptr; + T* next = nullptr; +}; + +// Intrusive doubly linked list +template class IntrusiveList { + public: + IntrusiveList() : head(nullptr), tail(nullptr) {} + + bool empty() const { return head == nullptr; } + + void push_front(T* node) { + assert(node && node->prev == nullptr && node->next == nullptr && "节点必须处于未链接状态"); + node->next = head; + if (head) + head->prev = node; + head = node; + if (!tail) + tail = node; + } + + void push_back(T* node) { + assert(node && node->prev == nullptr && node->next == nullptr && "节点必须处于未链接状态"); + node->prev = tail; + if (tail) + tail->next = node; + tail = node; + if (!head) + head = node; + } + + T* pop_front() { + if (!head) + return nullptr; + T* n = head; + head = head->next; + if (head) + head->prev = nullptr; + else + tail = nullptr; + n->next = n->prev = nullptr; + return n; + } + + void erase(T* node) { + assert(node && "erase null"); + if (node->prev) + node->prev->next = node->next; + else + head = node->next; + + if (node->next) + node->next->prev = node->prev; + else + tail = node->prev; + + node->prev = node->next = nullptr; + } + + void clear() { + T* cur = head; + while (cur) { + T* nxt = cur->next; + cur->prev = cur->next = nullptr; + cur = nxt; + } + head = tail = nullptr; + } + + // 简单迭代器(只读/可写) + struct iterator { + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using pointer = T*; + using reference = T&; + + explicit iterator(T* p) : p(p) {} + reference operator*() const { return *p; } + pointer operator->() const { return p; } + iterator& operator++() { + p = p->next; + return *this; + } + iterator operator++(int) { + iterator tmp = *this; + ++*this; + return tmp; + } + bool operator==(const iterator& o) const { return p == o.p; } + bool operator!=(const iterator& o) const { return p != o.p; } + + private: + T* p; + }; + + iterator begin() { return iterator(head); } + iterator end() { return iterator(nullptr); } + + private: + T* head; + T* tail; +}; diff --git a/code/examples/chapter07/04_intrusive_container/member_hook.h b/code/examples/chapter08/09_intrusive_container/member_hook.h similarity index 70% rename from code/examples/chapter07/04_intrusive_container/member_hook.h rename to code/examples/chapter08/09_intrusive_container/member_hook.h index c09a82fea..f447697fd 100644 --- a/code/examples/chapter07/04_intrusive_container/member_hook.h +++ b/code/examples/chapter08/09_intrusive_container/member_hook.h @@ -1,65 +1,76 @@ -// member_hook.h - 成员 hook 方式的侵入式链表 -#pragma once -#include -#include - -// container_of 宏 - 给定成员指针,获取包含对象指针 -#define CONTAINER_OF(ptr, type, member) \ - reinterpret_cast(reinterpret_cast(ptr) - offsetof(type, member)) - -// 简单的通用链表节点 -struct IntrusiveNode { - IntrusiveNode* prev = nullptr; - IntrusiveNode* next = nullptr; -}; - -// 通用侵入式双向链表 -class IntrusiveListGeneric { -public: - IntrusiveListGeneric() : head(nullptr), tail(nullptr) {} - - bool empty() const { return head == nullptr; } - - void push_back(IntrusiveNode* node) { - assert(node && node->prev == nullptr && node->next == nullptr); - node->prev = tail; - if (tail) tail->next = node; - tail = node; - if (!head) head = node; - } - - void push_front(IntrusiveNode* node) { - assert(node && node->prev == nullptr && node->next == nullptr); - node->next = head; - if (head) head->prev = node; - head = node; - if (!tail) tail = node; - } - - void erase(IntrusiveNode* node) { - if (node->prev) node->prev->next = node->next; - else head = node->next; - - if (node->next) node->next->prev = node->prev; - else tail = node->prev; - - node->prev = node->next = nullptr; - } - - IntrusiveNode* pop_front() { - if (!head) return nullptr; - IntrusiveNode* n = head; - head = head->next; - if (head) head->prev = nullptr; - else tail = nullptr; - n->next = n->prev = nullptr; - return n; - } - - IntrusiveNode* front() { return head; } - const IntrusiveNode* front() const { return head; } - -private: - IntrusiveNode* head; - IntrusiveNode* tail; -}; +// member_hook.h - 成员 hook 方式的侵入式链表 +#pragma once +#include +#include + +// container_of 宏 - 给定成员指针,获取包含对象指针 +#define CONTAINER_OF(ptr, type, member) \ + reinterpret_cast(reinterpret_cast(ptr) - offsetof(type, member)) + +// 简单的通用链表节点 +struct IntrusiveNode { + IntrusiveNode* prev = nullptr; + IntrusiveNode* next = nullptr; +}; + +// 通用侵入式双向链表 +class IntrusiveListGeneric { + public: + IntrusiveListGeneric() : head(nullptr), tail(nullptr) {} + + bool empty() const { return head == nullptr; } + + void push_back(IntrusiveNode* node) { + assert(node && node->prev == nullptr && node->next == nullptr); + node->prev = tail; + if (tail) + tail->next = node; + tail = node; + if (!head) + head = node; + } + + void push_front(IntrusiveNode* node) { + assert(node && node->prev == nullptr && node->next == nullptr); + node->next = head; + if (head) + head->prev = node; + head = node; + if (!tail) + tail = node; + } + + void erase(IntrusiveNode* node) { + if (node->prev) + node->prev->next = node->next; + else + head = node->next; + + if (node->next) + node->next->prev = node->prev; + else + tail = node->prev; + + node->prev = node->next = nullptr; + } + + IntrusiveNode* pop_front() { + if (!head) + return nullptr; + IntrusiveNode* n = head; + head = head->next; + if (head) + head->prev = nullptr; + else + tail = nullptr; + n->next = n->prev = nullptr; + return n; + } + + IntrusiveNode* front() { return head; } + const IntrusiveNode* front() const { return head; } + + private: + IntrusiveNode* head; + IntrusiveNode* tail; +}; diff --git a/code/examples/chapter07/04_intrusive_container/member_hook_example.cpp b/code/examples/chapter08/09_intrusive_container/member_hook_example.cpp similarity index 91% rename from code/examples/chapter07/04_intrusive_container/member_hook_example.cpp rename to code/examples/chapter08/09_intrusive_container/member_hook_example.cpp index 27eea2e64..590ef196c 100644 --- a/code/examples/chapter07/04_intrusive_container/member_hook_example.cpp +++ b/code/examples/chapter08/09_intrusive_container/member_hook_example.cpp @@ -1,59 +1,59 @@ -// member_hook_example.cpp - 成员 hook 方式示例 -#include "member_hook.h" -#include - -// 可以同时属于多个链表的对象 -struct MyObject { - int id; - IntrusiveNode ready_hook; // for ready list - IntrusiveNode wait_hook; // for wait list - - MyObject(int i) : id(i) {} -}; - -int main() { - IntrusiveListGeneric ready_list; - IntrusiveListGeneric wait_list; - - // 创建对象 - MyObject obj1(1); - MyObject obj2(2); - MyObject obj3(3); - - std::cout << "=== Member Hook Demo ===\n\n"; - - // 添加到 ready_list - ready_list.push_back(&obj1.ready_hook); - ready_list.push_back(&obj2.ready_hook); - - // 添加到 wait_list - wait_list.push_back(&obj3.wait_hook); - - std::cout << "Ready list:\n"; - for (IntrusiveNode* node = ready_list.front(); node; node = node->next) { - MyObject* obj = CONTAINER_OF(node, MyObject, ready_hook); - std::cout << " Object " << obj->id << '\n'; - } - - std::cout << "\nWait list:\n"; - for (IntrusiveNode* node = wait_list.front(); node; node = node->next) { - MyObject* obj = CONTAINER_OF(node, MyObject, wait_hook); - std::cout << " Object " << obj->id << '\n'; - } - - // 演示移动:从 wait_list 移到 ready_list - std::cout << "\n=== Moving obj3 from wait to ready ===\n"; - wait_list.erase(&obj3.wait_hook); - ready_list.push_back(&obj3.ready_hook); - - std::cout << "Ready list after move:\n"; - for (IntrusiveNode* node = ready_list.front(); node; node = node->next) { - MyObject* obj = CONTAINER_OF(node, MyObject, ready_hook); - std::cout << " Object " << obj->id << '\n'; - } - - std::cout << "\nWait list after move:\n"; - std::cout << " " << (wait_list.empty() ? "(empty)" : "not empty") << '\n'; - - return 0; -} +// member_hook_example.cpp - 成员 hook 方式示例 +#include "member_hook.h" +#include + +// 可以同时属于多个链表的对象 +struct MyObject { + int id; + IntrusiveNode ready_hook; // for ready list + IntrusiveNode wait_hook; // for wait list + + MyObject(int i) : id(i) {} +}; + +int main() { + IntrusiveListGeneric ready_list; + IntrusiveListGeneric wait_list; + + // 创建对象 + MyObject obj1(1); + MyObject obj2(2); + MyObject obj3(3); + + std::cout << "=== Member Hook Demo ===\n\n"; + + // 添加到 ready_list + ready_list.push_back(&obj1.ready_hook); + ready_list.push_back(&obj2.ready_hook); + + // 添加到 wait_list + wait_list.push_back(&obj3.wait_hook); + + std::cout << "Ready list:\n"; + for (IntrusiveNode* node = ready_list.front(); node; node = node->next) { + MyObject* obj = CONTAINER_OF(node, MyObject, ready_hook); + std::cout << " Object " << obj->id << '\n'; + } + + std::cout << "\nWait list:\n"; + for (IntrusiveNode* node = wait_list.front(); node; node = node->next) { + MyObject* obj = CONTAINER_OF(node, MyObject, wait_hook); + std::cout << " Object " << obj->id << '\n'; + } + + // 演示移动:从 wait_list 移到 ready_list + std::cout << "\n=== Moving obj3 from wait to ready ===\n"; + wait_list.erase(&obj3.wait_hook); + ready_list.push_back(&obj3.ready_hook); + + std::cout << "Ready list after move:\n"; + for (IntrusiveNode* node = ready_list.front(); node; node = node->next) { + MyObject* obj = CONTAINER_OF(node, MyObject, ready_hook); + std::cout << " Object " << obj->id << '\n'; + } + + std::cout << "\nWait list after move:\n"; + std::cout << " " << (wait_list.empty() ? "(empty)" : "not empty") << '\n'; + + return 0; +} diff --git a/code/examples/chapter07/04_intrusive_container/task_scheduler_example.cpp b/code/examples/chapter08/09_intrusive_container/task_scheduler_example.cpp similarity index 76% rename from code/examples/chapter07/04_intrusive_container/task_scheduler_example.cpp rename to code/examples/chapter08/09_intrusive_container/task_scheduler_example.cpp index ebe20e664..9439f3e11 100644 --- a/code/examples/chapter07/04_intrusive_container/task_scheduler_example.cpp +++ b/code/examples/chapter08/09_intrusive_container/task_scheduler_example.cpp @@ -1,100 +1,86 @@ -// task_scheduler_example.cpp - 使用侵入式链表的任务调度器 -#include "intrusive_list.h" -#include -#include -#include - -// 任务状态枚举 -enum class TaskState { - Ready, - Running, - Waiting, - Done -}; - -// 任务类 - 侵入式设计 -struct Task : IntrusiveListNode { - int id; - const char* name; - TaskState state; - int priority; - - Task(int i, const char* n, int p = 0) - : id(i), name(n), state(TaskState::Ready), priority(p) {} - - void run() { - std::cout << " Running Task " << id << ": " << name << '\n'; - state = TaskState::Running; - // 模拟任务执行 - state = TaskState::Done; - } -}; - -// 任务比较器(用于优先队列) -struct TaskCompare { - bool operator()(const Task* a, const Task* b) const { - return a->priority < b->priority; - } -}; - -// 简单的任务调度器 -class TaskScheduler { -public: - void add_task(Task* task) { - ready_list.push_back(task); - } - - Task* get_next_task() { - return ready_list.pop_front(); - } - - void run_all() { - std::cout << "\n=== Running all tasks ===\n"; - while (auto task = get_next_task()) { - if (task->state == TaskState::Ready) { - task->run(); - } - } - } - - bool empty() const { - return ready_list.empty(); - } - -private: - IntrusiveList ready_list; -}; - -int main() { - TaskScheduler scheduler; - - std::cout << "=== Intrusive Container Task Scheduler Demo ===\n\n"; - - // 创建任务(栈上分配,无堆操作) - Task task1(1, "Initialize Hardware", 10); - Task task2(2, "Read Sensors", 5); - Task task3(3, "Process Data", 8); - Task task4(4, "Send Report", 3); - - // 添加任务到调度器 - scheduler.add_task(&task1); - scheduler.add_task(&task2); - scheduler.add_task(&task3); - scheduler.add_task(&task4); - - std::cout << "Tasks added to scheduler (no memory allocation!)\n"; - std::cout << "Scheduler empty: " << (scheduler.empty() ? "yes" : "no") << '\n'; - - // 运行所有任务 - scheduler.run_all(); - - std::cout << "\nScheduler empty: " << (scheduler.empty() ? "yes" : "no") << '\n'; - - std::cout << "\n=== Benefits demonstrated ===\n"; - std::cout << "- No heap allocation for task nodes\n"; - std::cout << "- Tasks can be on stack or in static memory\n"; - std::cout << "- Zero overhead abstraction\n"; - std::cout << "- Deterministic memory usage\n"; - - return 0; -} +// task_scheduler_example.cpp - 使用侵入式链表的任务调度器 +#include "intrusive_list.h" +#include +#include +#include + +// 任务状态枚举 +enum class TaskState { Ready, Running, Waiting, Done }; + +// 任务类 - 侵入式设计 +struct Task : IntrusiveListNode { + int id; + const char* name; + TaskState state; + int priority; + + Task(int i, const char* n, int p = 0) : id(i), name(n), state(TaskState::Ready), priority(p) {} + + void run() { + std::cout << " Running Task " << id << ": " << name << '\n'; + state = TaskState::Running; + // 模拟任务执行 + state = TaskState::Done; + } +}; + +// 任务比较器(用于优先队列) +struct TaskCompare { + bool operator()(const Task* a, const Task* b) const { return a->priority < b->priority; } +}; + +// 简单的任务调度器 +class TaskScheduler { + public: + void add_task(Task* task) { ready_list.push_back(task); } + + Task* get_next_task() { return ready_list.pop_front(); } + + void run_all() { + std::cout << "\n=== Running all tasks ===\n"; + while (auto task = get_next_task()) { + if (task->state == TaskState::Ready) { + task->run(); + } + } + } + + bool empty() const { return ready_list.empty(); } + + private: + IntrusiveList ready_list; +}; + +int main() { + TaskScheduler scheduler; + + std::cout << "=== Intrusive Container Task Scheduler Demo ===\n\n"; + + // 创建任务(栈上分配,无堆操作) + Task task1(1, "Initialize Hardware", 10); + Task task2(2, "Read Sensors", 5); + Task task3(3, "Process Data", 8); + Task task4(4, "Send Report", 3); + + // 添加任务到调度器 + scheduler.add_task(&task1); + scheduler.add_task(&task2); + scheduler.add_task(&task3); + scheduler.add_task(&task4); + + std::cout << "Tasks added to scheduler (no memory allocation!)\n"; + std::cout << "Scheduler empty: " << (scheduler.empty() ? "yes" : "no") << '\n'; + + // 运行所有任务 + scheduler.run_all(); + + std::cout << "\nScheduler empty: " << (scheduler.empty() ? "yes" : "no") << '\n'; + + std::cout << "\n=== Benefits demonstrated ===\n"; + std::cout << "- No heap allocation for task nodes\n"; + std::cout << "- Tasks can be on stack or in static memory\n"; + std::cout << "- Zero overhead abstraction\n"; + std::cout << "- Deterministic memory usage\n"; + + return 0; +} diff --git a/code/examples/chapter07/05_etl/CMakeLists.txt b/code/examples/chapter08/10_etl/CMakeLists.txt similarity index 93% rename from code/examples/chapter07/05_etl/CMakeLists.txt rename to code/examples/chapter08/10_etl/CMakeLists.txt index d209c5841..54ec79df4 100644 --- a/code/examples/chapter07/05_etl/CMakeLists.txt +++ b/code/examples/chapter08/10_etl/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.20) -project(chapter07_05_etl CXX) +project(chapter08_10_etl CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/code/examples/chapter07/05_etl/README.md b/code/examples/chapter08/10_etl/README.md similarity index 100% rename from code/examples/chapter07/05_etl/README.md rename to code/examples/chapter08/10_etl/README.md diff --git a/code/examples/chapter07/05_etl/etl_pool_demo.cpp b/code/examples/chapter08/10_etl/etl_pool_demo.cpp similarity index 87% rename from code/examples/chapter07/05_etl/etl_pool_demo.cpp rename to code/examples/chapter08/10_etl/etl_pool_demo.cpp index ab335a7de..75af17ff5 100644 --- a/code/examples/chapter07/05_etl/etl_pool_demo.cpp +++ b/code/examples/chapter08/10_etl/etl_pool_demo.cpp @@ -1,147 +1,146 @@ -// etl_pool_demo.cpp - ETL 对象池示例 -// 注意:此示例需要 ETL 库支持 -// https://github.com/ETLCPP/etl - -#include -#include -#include -#include - -// 模拟 ETL object_pool 接口(用于演示) -template -class EtlPoolDemo { - struct Node { - Node* next; - alignas(T) char storage[sizeof(T)]; - }; - - std::array pool_; - Node* free_list_; - -public: - EtlPoolDemo() { - // 初始化空闲链表 - free_list_ = &pool_[0]; - for (size_t i = 0; i < N - 1; ++i) { - pool_[i].next = &pool_[i + 1]; - } - pool_[N - 1].next = nullptr; - } - - // 分配对象(调用构造函数) - template - T* create(Args&&... args) { - if (!free_list_) return nullptr; - - Node* node = free_list_; - free_list_ = free_list_->next; - - return new (node->storage) T(std::forward(args)...); - } - - // 释放对象(调用析构函数) - void destroy(T* obj) { - if (!obj) return; - - obj->~T(); - - Node* node = reinterpret_cast(obj); - node->next = free_list_; - free_list_ = node; - } - - size_t capacity() const { return N; } -}; - -// 示例对象 -struct Sensor { - int id; - const char* name; - int value; - - Sensor(int i, const char* n) : id(i), name(n), value(0) {} - - void read() { - value = id * 42; // 模拟读取 - } - - void display() const { - std::cout << " Sensor " << id << " (" << name - << "): " << value << '\n'; - } -}; - -int main() { - std::cout << "=== ETL Object Pool Demo ===\n\n"; - - // 创建容量为 5 的传感器对象池 - // etl::object_pool sensor_pool; // 使用真实 ETL 时的写法 - EtlPoolDemo sensor_pool; - - std::cout << "Pool capacity: " << sensor_pool.capacity() << "\n\n"; - - // 分配传感器对象 - std::cout << "=== Creating sensors ===\n"; - Sensor* s1 = sensor_pool.create(1, "Temperature"); - Sensor* s2 = sensor_pool.create(2, "Humidity"); - Sensor* s3 = sensor_pool.create(3, "Pressure"); - Sensor* s4 = sensor_pool.create(4, "Light"); - Sensor* s5 = sensor_pool.create(5, "Motion"); - - // 尝试分配第 6 个(应该失败) - Sensor* s6 = sensor_pool.create(6, "Sound"); - if (!s6) { - std::cout << "Failed to create Sensor 6 (pool exhausted)\n"; - } - - // 使用传感器 - std::cout << "\n=== Reading sensors ===\n"; - s1->read(); - s2->read(); - s3->read(); - s4->read(); - s5->read(); - - std::cout << "\n=== Sensor values ===\n"; - s1->display(); - s2->display(); - s3->display(); - s4->display(); - s5->display(); - - // 释放一些传感器 - std::cout << "\n=== Releasing some sensors ===\n"; - sensor_pool.destroy(s2); - sensor_pool.destroy(s4); - std::cout << "Released Sensors 2 and 4\n"; - - // 现在可以重新分配 - std::cout << "\n=== Creating new sensors ===\n"; - Sensor* s7 = sensor_pool.create(7, "Voltage"); - if (s7) { - s7->read(); - s7->display(); - } - - Sensor* s8 = sensor_pool.create(8, "Current"); - if (s8) { - s8->read(); - s8->display(); - } - - // 清理 - std::cout << "\n=== Cleanup ===\n"; - sensor_pool.destroy(s1); - sensor_pool.destroy(s3); - sensor_pool.destroy(s5); - sensor_pool.destroy(s7); - sensor_pool.destroy(s8); - - std::cout << "\n=== Key benefits ===\n"; - std::cout << "- Pre-allocated memory, no fragmentation\n"; - std::cout << "- O(1) allocation and deallocation\n"; - std::cout << "- Objects constructed on-demand\n"; - std::cout << "- Perfect for fixed-size object collections\n"; - - return 0; -} +// etl_pool_demo.cpp - ETL 对象池示例 +// 注意:此示例需要 ETL 库支持 +// https://github.com/ETLCPP/etl + +#include +#include +#include +#include + +// 模拟 ETL object_pool 接口(用于演示) +template class EtlPoolDemo { + struct Node { + Node* next; + alignas(T) char storage[sizeof(T)]; + }; + + std::array pool_; + Node* free_list_; + + public: + EtlPoolDemo() { + // 初始化空闲链表 + free_list_ = &pool_[0]; + for (size_t i = 0; i < N - 1; ++i) { + pool_[i].next = &pool_[i + 1]; + } + pool_[N - 1].next = nullptr; + } + + // 分配对象(调用构造函数) + template T* create(Args&&... args) { + if (!free_list_) + return nullptr; + + Node* node = free_list_; + free_list_ = free_list_->next; + + return new (node->storage) T(std::forward(args)...); + } + + // 释放对象(调用析构函数) + void destroy(T* obj) { + if (!obj) + return; + + obj->~T(); + + Node* node = reinterpret_cast(obj); + node->next = free_list_; + free_list_ = node; + } + + size_t capacity() const { return N; } +}; + +// 示例对象 +struct Sensor { + int id; + const char* name; + int value; + + Sensor(int i, const char* n) : id(i), name(n), value(0) {} + + void read() { + value = id * 42; // 模拟读取 + } + + void display() const { + std::cout << " Sensor " << id << " (" << name << "): " << value << '\n'; + } +}; + +int main() { + std::cout << "=== ETL Object Pool Demo ===\n\n"; + + // 创建容量为 5 的传感器对象池 + // etl::object_pool sensor_pool; // 使用真实 ETL 时的写法 + EtlPoolDemo sensor_pool; + + std::cout << "Pool capacity: " << sensor_pool.capacity() << "\n\n"; + + // 分配传感器对象 + std::cout << "=== Creating sensors ===\n"; + Sensor* s1 = sensor_pool.create(1, "Temperature"); + Sensor* s2 = sensor_pool.create(2, "Humidity"); + Sensor* s3 = sensor_pool.create(3, "Pressure"); + Sensor* s4 = sensor_pool.create(4, "Light"); + Sensor* s5 = sensor_pool.create(5, "Motion"); + + // 尝试分配第 6 个(应该失败) + Sensor* s6 = sensor_pool.create(6, "Sound"); + if (!s6) { + std::cout << "Failed to create Sensor 6 (pool exhausted)\n"; + } + + // 使用传感器 + std::cout << "\n=== Reading sensors ===\n"; + s1->read(); + s2->read(); + s3->read(); + s4->read(); + s5->read(); + + std::cout << "\n=== Sensor values ===\n"; + s1->display(); + s2->display(); + s3->display(); + s4->display(); + s5->display(); + + // 释放一些传感器 + std::cout << "\n=== Releasing some sensors ===\n"; + sensor_pool.destroy(s2); + sensor_pool.destroy(s4); + std::cout << "Released Sensors 2 and 4\n"; + + // 现在可以重新分配 + std::cout << "\n=== Creating new sensors ===\n"; + Sensor* s7 = sensor_pool.create(7, "Voltage"); + if (s7) { + s7->read(); + s7->display(); + } + + Sensor* s8 = sensor_pool.create(8, "Current"); + if (s8) { + s8->read(); + s8->display(); + } + + // 清理 + std::cout << "\n=== Cleanup ===\n"; + sensor_pool.destroy(s1); + sensor_pool.destroy(s3); + sensor_pool.destroy(s5); + sensor_pool.destroy(s7); + sensor_pool.destroy(s8); + + std::cout << "\n=== Key benefits ===\n"; + std::cout << "- Pre-allocated memory, no fragmentation\n"; + std::cout << "- O(1) allocation and deallocation\n"; + std::cout << "- Objects constructed on-demand\n"; + std::cout << "- Perfect for fixed-size object collections\n"; + + return 0; +} diff --git a/code/examples/chapter07/05_etl/etl_queue_demo.cpp b/code/examples/chapter08/10_etl/etl_queue_demo.cpp similarity index 86% rename from code/examples/chapter07/05_etl/etl_queue_demo.cpp rename to code/examples/chapter08/10_etl/etl_queue_demo.cpp index 8d903fca1..170b137e0 100644 --- a/code/examples/chapter07/05_etl/etl_queue_demo.cpp +++ b/code/examples/chapter08/10_etl/etl_queue_demo.cpp @@ -1,88 +1,90 @@ -// etl_queue_demo.cpp - ETL 固定容量队列示例 -// 注意:此示例需要 ETL 库支持 -// https://github.com/ETLCPP/etl - -#include -#include - -// 模拟 ETL queue 接口(用于演示) -template -class EtlQueueDemo { - std::array buffer_; // +1 for empty/full distinction - size_t head_ = 0; - size_t tail_ = 0; - -public: - bool push(const T& value) { - if (full()) return false; - buffer_[head_] = value; - head_ = (head_ + 1) % (N + 1); - return true; - } - - bool pop(T& out) { - if (empty()) return false; - out = buffer_[tail_]; - tail_ = (tail_ + 1) % (N + 1); - return true; - } - - bool empty() const { return head_ == tail_; } - bool full() const { return (head_ + 1) % (N + 1) == tail_; } - - size_t size() const { - if (head_ >= tail_) return head_ - tail_; - return (N + 1) - (tail_ - head_); - } - - size_t capacity() const { return N; } -}; - -// 消息结构 -struct Message { - int id; - int data; -}; - -int main() { - std::cout << "=== ETL Queue Demo ===\n\n"; - - // 消息队列,容量 8 - // etl::queue msg_queue; // 使用真实 ETL 时的写法 - EtlQueueDemo msg_queue; - - std::cout << "Queue capacity: " << msg_queue.capacity() << "\n\n"; - - // 生产者:发送消息 - std::cout << "=== Producer: Sending messages ===\n"; - for (int i = 0; i < 10; ++i) { - Message msg{i, i * 100}; - if (msg_queue.push(msg)) { - std::cout << "Sent: ID=" << msg.id << ", Data=" << msg.data << '\n'; - } else { - std::cout << "Queue full! Message " << i << " dropped.\n"; - break; - } - } - - std::cout << "\nQueue size: " << msg_queue.size() << "\n\n"; - - // 消费者:处理消息 - std::cout << "=== Consumer: Processing messages ===\n"; - while (!msg_queue.empty()) { - Message msg; - if (msg_queue.pop(msg)) { - std::cout << "Processed: ID=" << msg.id << ", Data=" << msg.data << '\n'; - } - } - - std::cout << "\nQueue empty: " << (msg_queue.empty() ? "yes" : "no") << '\n'; - - std::cout << "\n=== Typical embedded use case ===\n"; - std::cout << "- ISR pushes data to queue\n"; - std::cout << "- Main loop processes at its own pace\n"; - std::cout << "- No malloc, deterministic behavior\n"; - std::cout << "- Type-safe, unlike raw byte buffers\n"; - - return 0; -} +// etl_queue_demo.cpp - ETL 固定容量队列示例 +// 注意:此示例需要 ETL 库支持 +// https://github.com/ETLCPP/etl + +#include +#include + +// 模拟 ETL queue 接口(用于演示) +template class EtlQueueDemo { + std::array buffer_; // +1 for empty/full distinction + size_t head_ = 0; + size_t tail_ = 0; + + public: + bool push(const T& value) { + if (full()) + return false; + buffer_[head_] = value; + head_ = (head_ + 1) % (N + 1); + return true; + } + + bool pop(T& out) { + if (empty()) + return false; + out = buffer_[tail_]; + tail_ = (tail_ + 1) % (N + 1); + return true; + } + + bool empty() const { return head_ == tail_; } + bool full() const { return (head_ + 1) % (N + 1) == tail_; } + + size_t size() const { + if (head_ >= tail_) + return head_ - tail_; + return (N + 1) - (tail_ - head_); + } + + size_t capacity() const { return N; } +}; + +// 消息结构 +struct Message { + int id; + int data; +}; + +int main() { + std::cout << "=== ETL Queue Demo ===\n\n"; + + // 消息队列,容量 8 + // etl::queue msg_queue; // 使用真实 ETL 时的写法 + EtlQueueDemo msg_queue; + + std::cout << "Queue capacity: " << msg_queue.capacity() << "\n\n"; + + // 生产者:发送消息 + std::cout << "=== Producer: Sending messages ===\n"; + for (int i = 0; i < 10; ++i) { + Message msg{i, i * 100}; + if (msg_queue.push(msg)) { + std::cout << "Sent: ID=" << msg.id << ", Data=" << msg.data << '\n'; + } else { + std::cout << "Queue full! Message " << i << " dropped.\n"; + break; + } + } + + std::cout << "\nQueue size: " << msg_queue.size() << "\n\n"; + + // 消费者:处理消息 + std::cout << "=== Consumer: Processing messages ===\n"; + while (!msg_queue.empty()) { + Message msg; + if (msg_queue.pop(msg)) { + std::cout << "Processed: ID=" << msg.id << ", Data=" << msg.data << '\n'; + } + } + + std::cout << "\nQueue empty: " << (msg_queue.empty() ? "yes" : "no") << '\n'; + + std::cout << "\n=== Typical embedded use case ===\n"; + std::cout << "- ISR pushes data to queue\n"; + std::cout << "- Main loop processes at its own pace\n"; + std::cout << "- No malloc, deterministic behavior\n"; + std::cout << "- Type-safe, unlike raw byte buffers\n"; + + return 0; +} diff --git a/code/examples/chapter07/05_etl/etl_vector_demo.cpp b/code/examples/chapter08/10_etl/etl_vector_demo.cpp similarity index 91% rename from code/examples/chapter07/05_etl/etl_vector_demo.cpp rename to code/examples/chapter08/10_etl/etl_vector_demo.cpp index 6d6de0151..611510cfb 100644 --- a/code/examples/chapter07/05_etl/etl_vector_demo.cpp +++ b/code/examples/chapter08/10_etl/etl_vector_demo.cpp @@ -1,94 +1,95 @@ -// etl_vector_demo.cpp - ETL 固定容量向量示例 -// 注意:此示例需要 ETL 库支持 -// https://github.com/ETLCPP/etl - -#include - -// 如果你有 ETL 库,取消下面的注释并调整路径 -// #include - -// 模拟 ETL vector 接口(用于演示) -template -class EtlVectorDemo { - T buffer_[N]; - size_t size_ = 0; - -public: - bool push_back(const T& value) { - if (size_ >= N) return false; - buffer_[size_++] = value; - return true; - } - - size_t size() const { return size_; } - size_t capacity() const { return N; } - - T& operator[](size_t index) { return buffer_[index]; } - const T& operator[](size_t index) const { return buffer_[index]; } - - T* data() { return buffer_; } - const T* data() const { return buffer_; } - - // 迭代器支持 - T* begin() { return buffer_; } - T* end() { return buffer_ + size_; } - const T* begin() const { return buffer_; } - const T* end() const { return buffer_ + size_; } - - void insert(size_t pos, const T& value) { - if (size_ >= N || pos > size_) return; - for (size_t i = size_; i > pos; --i) { - buffer_[i] = buffer_[i - 1]; - } - buffer_[pos] = value; - ++size_; - } -}; - -int main() { - std::cout << "=== ETL Vector Demo ===\n\n"; - - // 最大容量 8 的静态向量,内存事先分配好(无动态分配) - // etl::vector v; // 使用真实 ETL 时的写法 - EtlVectorDemo v; - - std::cout << "Vector capacity: " << v.capacity() << '\n'; - - std::cout << "\n=== Adding elements ===\n"; - for (int i = 0; i < 6; ++i) { - if (v.push_back(i * 10)) { - std::cout << "Added: " << i * 10 << ", size: " << v.size() << '\n'; - } - } - - std::cout << "\n=== Contents ===\n"; - for (auto it = v.begin(); it != v.end(); ++it) { - std::cout << *it << ' '; - } - std::cout << '\n'; - - std::cout << "\n=== Insert at position 2 ===\n"; - v.insert(2, 99); - for (const auto& val : v) { - std::cout << val << ' '; - } - std::cout << '\n'; - - std::cout << "\n=== Filling to capacity ===\n"; - for (int i = 0; i < 10; ++i) { - if (!v.push_back(i * 100)) { - std::cout << "Failed to add " << i * 100 << " (buffer full)\n"; - break; - } - } - - std::cout << "\nFinal size: " << v.size() << '/' << v.capacity() << '\n'; - - std::cout << "\n=== Key benefits ===\n"; - std::cout << "- No heap allocation\n"; - std::cout << "- Deterministic memory usage\n"; - std::cout << "- Compile-time capacity specification\n"; - std::cout << "- STL-compatible interface\n"; - - return 0; -} +// etl_vector_demo.cpp - ETL 固定容量向量示例 +// 注意:此示例需要 ETL 库支持 +// https://github.com/ETLCPP/etl + +#include + +// 如果你有 ETL 库,取消下面的注释并调整路径 +// #include + +// 模拟 ETL vector 接口(用于演示) +template class EtlVectorDemo { + T buffer_[N]; + size_t size_ = 0; + + public: + bool push_back(const T& value) { + if (size_ >= N) + return false; + buffer_[size_++] = value; + return true; + } + + size_t size() const { return size_; } + size_t capacity() const { return N; } + + T& operator[](size_t index) { return buffer_[index]; } + const T& operator[](size_t index) const { return buffer_[index]; } + + T* data() { return buffer_; } + const T* data() const { return buffer_; } + + // 迭代器支持 + T* begin() { return buffer_; } + T* end() { return buffer_ + size_; } + const T* begin() const { return buffer_; } + const T* end() const { return buffer_ + size_; } + + void insert(size_t pos, const T& value) { + if (size_ >= N || pos > size_) + return; + for (size_t i = size_; i > pos; --i) { + buffer_[i] = buffer_[i - 1]; + } + buffer_[pos] = value; + ++size_; + } +}; + +int main() { + std::cout << "=== ETL Vector Demo ===\n\n"; + + // 最大容量 8 的静态向量,内存事先分配好(无动态分配) + // etl::vector v; // 使用真实 ETL 时的写法 + EtlVectorDemo v; + + std::cout << "Vector capacity: " << v.capacity() << '\n'; + + std::cout << "\n=== Adding elements ===\n"; + for (int i = 0; i < 6; ++i) { + if (v.push_back(i * 10)) { + std::cout << "Added: " << i * 10 << ", size: " << v.size() << '\n'; + } + } + + std::cout << "\n=== Contents ===\n"; + for (auto it = v.begin(); it != v.end(); ++it) { + std::cout << *it << ' '; + } + std::cout << '\n'; + + std::cout << "\n=== Insert at position 2 ===\n"; + v.insert(2, 99); + for (const auto& val : v) { + std::cout << val << ' '; + } + std::cout << '\n'; + + std::cout << "\n=== Filling to capacity ===\n"; + for (int i = 0; i < 10; ++i) { + if (!v.push_back(i * 100)) { + std::cout << "Failed to add " << i * 100 << " (buffer full)\n"; + break; + } + } + + std::cout << "\nFinal size: " << v.size() << '/' << v.capacity() << '\n'; + + std::cout << "\n=== Key benefits ===\n"; + std::cout << "- No heap allocation\n"; + std::cout << "- Deterministic memory usage\n"; + std::cout << "- Compile-time capacity specification\n"; + std::cout << "- STL-compatible interface\n"; + + return 0; +} diff --git a/documents/en/vol3-standard-library/index.md b/documents/en/vol3-standard-library/index.md index 20f67f717..93b0ecc1c 100644 --- a/documents/en/vol3-standard-library/index.md +++ b/documents/en/vol3-standard-library/index.md @@ -28,8 +28,5 @@ This volume provides a deep dive into the C++ standard library. Object Size and Trivial Types array span - Circular Buffer - Intrusive Containers Custom Allocators - Type-Safe Register Access diff --git a/documents/en/vol3-standard-library/02-type-safe-register-access.md b/documents/en/vol8-domains/embedded/02-type-safe-register-access.md similarity index 98% rename from documents/en/vol3-standard-library/02-type-safe-register-access.md rename to documents/en/vol8-domains/embedded/02-type-safe-register-access.md index 4e352b67b..261f01af8 100644 --- a/documents/en/vol3-standard-library/02-type-safe-register-access.md +++ b/documents/en/vol8-domains/embedded/02-type-safe-register-access.md @@ -8,17 +8,17 @@ cpp_standard: description: Type-safe register wrapper difficulty: intermediate order: 2 -platform: host +platform: stm32f1 prerequisites: - 'Chapter 7: 容器与数据结构' reading_time_minutes: 7 tags: - cpp-modern -- host +- stm32f1 - intermediate title: Type-Safe Register Access translation: - source: documents/vol3-standard-library/02-type-safe-register-access.md + source: documents/vol8-domains/embedded/02-type-safe-register-access.md source_hash: ee7289ceef37902b9cdc6d8479414487f7cdf0f30acb7c738bf4937d04ab1834 translated_at: '2026-05-26T11:37:19.392812+00:00' engine: anthropic diff --git a/documents/en/vol3-standard-library/03-circular-buffer.md b/documents/en/vol8-domains/embedded/03-circular-buffer.md similarity index 98% rename from documents/en/vol3-standard-library/03-circular-buffer.md rename to documents/en/vol8-domains/embedded/03-circular-buffer.md index 1ce18b35e..b68ff0373 100644 --- a/documents/en/vol3-standard-library/03-circular-buffer.md +++ b/documents/en/vol8-domains/embedded/03-circular-buffer.md @@ -8,17 +8,17 @@ cpp_standard: description: Efficient circular buffer difficulty: intermediate order: 3 -platform: host +platform: stm32f1 prerequisites: - 'Chapter 6: RAII与智能指针' reading_time_minutes: 6 tags: - cpp-modern -- host +- stm32f1 - intermediate title: Circular Buffer Implementation translation: - source: documents/vol3-standard-library/03-circular-buffer.md + source: documents/vol8-domains/embedded/03-circular-buffer.md source_hash: 244238468099658b6070bdd00700e98ca2c24f4e869ccb425b756eb1ff99b464 translated_at: '2026-05-26T11:37:34.986895+00:00' engine: anthropic diff --git a/documents/en/vol3-standard-library/04-intrusive-containers.md b/documents/en/vol8-domains/embedded/04-intrusive-containers.md similarity index 99% rename from documents/en/vol3-standard-library/04-intrusive-containers.md rename to documents/en/vol8-domains/embedded/04-intrusive-containers.md index 7686826c3..4be0919ca 100644 --- a/documents/en/vol3-standard-library/04-intrusive-containers.md +++ b/documents/en/vol8-domains/embedded/04-intrusive-containers.md @@ -8,17 +8,17 @@ cpp_standard: description: Intrusive container design difficulty: intermediate order: 4 -platform: host +platform: stm32f1 prerequisites: - 'Chapter 6: RAII与智能指针' reading_time_minutes: 9 tags: - cpp-modern -- host +- stm32f1 - intermediate title: Intrusive Container Design translation: - source: documents/vol3-standard-library/04-intrusive-containers.md + source: documents/vol8-domains/embedded/04-intrusive-containers.md source_hash: 24e237b2960b248f9f2dc4c56c20e8e807a888d72f4844b5541a5197c450bd42 translated_at: '2026-05-26T11:37:35.486345+00:00' engine: anthropic diff --git a/documents/en/vol8-domains/embedded/core-embedded-cpp-index.md b/documents/en/vol8-domains/embedded/core-embedded-cpp-index.md index 9b5c28478..ccbf392da 100644 --- a/documents/en/vol8-domains/embedded/core-embedded-cpp-index.md +++ b/documents/en/vol8-domains/embedded/core-embedded-cpp-index.md @@ -70,14 +70,14 @@ This is the table of contents for *Modern C++ Tutorial for Embedded Systems*. Cl - [array](../../vol3-standard-library/01-array.md) - [span](../../vol3-standard-library/02-span.md) -- [Circular Buffer](../../vol3-standard-library/03-circular-buffer.md) -- [Intrusive Container Design](../../vol3-standard-library/04-intrusive-containers.md) +- [Circular Buffer](./03-circular-buffer.md) +- [Intrusive Container Design](./04-intrusive-containers.md) - [ETL](./05-etl.md) - [Custom Allocators](../../vol3-standard-library/06-custom-allocators.md) ## Chapter 8 - Type Safety and Utility Types -- [Type-Safe Register Access](../../vol3-standard-library/02-type-safe-register-access.md) +- [Type-Safe Register Access](./02-type-safe-register-access.md) ## Chapter 10 - Concurrency and Atomic Operations diff --git a/documents/en/vol8-domains/embedded/index.md b/documents/en/vol8-domains/embedded/index.md index cc663f03f..a57a45fcd 100644 --- a/documents/en/vol8-domains/embedded/index.md +++ b/documents/en/vol8-domains/embedded/index.md @@ -46,5 +46,8 @@ This directory contains a large number of embedded-related articles and an STM32 嵌入式 C++ 教程——ETL 中断安全的代码编写 嵌入式 C++ 教程——std::array vs C 数组 + 循环缓冲区 + 侵入式容器设计 + 类型安全的寄存器访问 目录 diff --git a/documents/vol3-standard-library/index.md b/documents/vol3-standard-library/index.md index 6d23abf2c..143187656 100644 --- a/documents/vol3-standard-library/index.md +++ b/documents/vol3-standard-library/index.md @@ -23,8 +23,5 @@ tags: 对象大小与平凡类型 array span - 环形缓冲区 - 侵入式容器 自定义分配器 - 类型安全寄存器访问 diff --git a/documents/vol3-standard-library/02-type-safe-register-access.md b/documents/vol8-domains/embedded/02-type-safe-register-access.md similarity index 99% rename from documents/vol3-standard-library/02-type-safe-register-access.md rename to documents/vol8-domains/embedded/02-type-safe-register-access.md index 66d2a68b3..419fbd6a7 100644 --- a/documents/vol3-standard-library/02-type-safe-register-access.md +++ b/documents/vol8-domains/embedded/02-type-safe-register-access.md @@ -8,13 +8,13 @@ cpp_standard: description: 类型安全寄存器封装 difficulty: intermediate order: 2 -platform: host +platform: stm32f1 prerequisites: - 'Chapter 7: 容器与数据结构' reading_time_minutes: 7 tags: - cpp-modern -- host +- stm32f1 - intermediate title: 类型安全的寄存器访问 --- diff --git a/documents/vol3-standard-library/03-circular-buffer.md b/documents/vol8-domains/embedded/03-circular-buffer.md similarity index 99% rename from documents/vol3-standard-library/03-circular-buffer.md rename to documents/vol8-domains/embedded/03-circular-buffer.md index 527404501..574c801ea 100644 --- a/documents/vol3-standard-library/03-circular-buffer.md +++ b/documents/vol8-domains/embedded/03-circular-buffer.md @@ -8,13 +8,13 @@ cpp_standard: description: 高效循环缓冲区 difficulty: intermediate order: 3 -platform: host +platform: stm32f1 prerequisites: - 'Chapter 6: RAII与智能指针' reading_time_minutes: 6 tags: - cpp-modern -- host +- stm32f1 - intermediate title: 循环缓冲区实现 --- diff --git a/documents/vol3-standard-library/04-intrusive-containers.md b/documents/vol8-domains/embedded/04-intrusive-containers.md similarity index 99% rename from documents/vol3-standard-library/04-intrusive-containers.md rename to documents/vol8-domains/embedded/04-intrusive-containers.md index d1c297622..5f3385154 100644 --- a/documents/vol3-standard-library/04-intrusive-containers.md +++ b/documents/vol8-domains/embedded/04-intrusive-containers.md @@ -8,13 +8,13 @@ cpp_standard: description: 侵入式容器设计 difficulty: intermediate order: 4 -platform: host +platform: stm32f1 prerequisites: - 'Chapter 6: RAII与智能指针' reading_time_minutes: 9 tags: - cpp-modern -- host +- stm32f1 - intermediate title: 侵入式容器设计 --- diff --git a/documents/vol8-domains/embedded/core-embedded-cpp-index.md b/documents/vol8-domains/embedded/core-embedded-cpp-index.md index 02a7f87d0..eba10fa99 100644 --- a/documents/vol8-domains/embedded/core-embedded-cpp-index.md +++ b/documents/vol8-domains/embedded/core-embedded-cpp-index.md @@ -64,14 +64,14 @@ order: 0 - [array](../../vol3-standard-library/01-array.md) - [span](../../vol3-standard-library/02-span.md) -- [循环缓冲区](../../vol3-standard-library/03-circular-buffer.md) -- [侵入式容器设计](../../vol3-standard-library/04-intrusive-containers.md) +- [循环缓冲区](./03-circular-buffer.md) +- [侵入式容器设计](./04-intrusive-containers.md) - [ETL](./05-etl.md) - [自定义的分配器](../../vol3-standard-library/06-custom-allocators.md) ## Chapter 8 - 类型安全与工具类型 -- [类型安全的寄存器访问](../../vol3-standard-library/02-type-safe-register-access.md) +- [类型安全的寄存器访问](./02-type-safe-register-access.md) ## Chapter 10 - 并发与原子操作 diff --git a/documents/vol8-domains/embedded/index.md b/documents/vol8-domains/embedded/index.md index 9b34926e0..3c3cbd1fe 100644 --- a/documents/vol8-domains/embedded/index.md +++ b/documents/vol8-domains/embedded/index.md @@ -41,5 +41,8 @@ tags: 嵌入式 C++ 教程——ETL 中断安全的代码编写 嵌入式 C++ 教程——std::array vs C 数组 + 循环缓冲区 + 侵入式容器设计 + 类型安全的寄存器访问 目录 diff --git a/todo/012-vol3-standard-library.md b/todo/012-vol3-standard-library.md index e14926b7c..50a21fe1e 100644 --- a/todo/012-vol3-standard-library.md +++ b/todo/012-vol3-standard-library.md @@ -34,24 +34,24 @@ estimated_effort: epic ## Maintenance Asset TODO(已确认决策) -### M1: 迁移 `02-type-safe-register-access.md` 至 vol8 ✅ 已确认 +### M1: 迁移 `02-type-safe-register-access.md` 至 vol8 ✅ 已完成 - **依据**:嵌入式寄存器位操作,与"标准库深入"定位无关。vol8-domains/embedded 是自然归属。 - **交付物**:文件从 vol3 移至 vol8,更新两侧 index.md、英文翻译、内部链接。 - **待 vol8 侧确认**:归入 embedded 哪个子章节。 -### M2: 迁移 `03-circular-buffer.md` 和 `04-intrusive-containers.md` 至 vol8 ✅ 已确认 +### M2: 迁移 `03-circular-buffer.md` 和 `04-intrusive-containers.md` 至 vol8 ✅ 已完成 - **依据**:手写环形缓冲区和侵入式容器均不属于 C++ 标准库 API。凡是不是标准库的内容都迁移至 vol8,具体归入哪个领域到地方再分析决策。 - **交付物**:同 M1。同时迁移 `chapter07/03_circular_buffer/` 和 `chapter07/04_intrusive_container/` 代码目录。 - **待 vol8 侧确认**:归入 embedded 哪个子章节。 -### M4: 迁移 ETL 代码至 vol8 ✅ 已确认 +### M4: 迁移 ETL 代码至 vol8 ✅ 已完成 - **依据**:`chapter07/05_etl/`(3 个 .cpp)是嵌入式替代方案库,定位与卷三标准库主线不符。跟随 M2 一起迁移。嵌入式就是嵌入式。 - **交付物**:迁移代码目录,vol3 正文无需改动(本来就没接入)。 -### M3: 更新 index.md 🕐 待触发 +### M3: 更新 index.md ✅ 已完成 - **依据**:迁移完成后 index.md 描述与实际内容差距更大。 - **决策**:在迁移任务完成时同步更新,不单独提前修改。 @@ -204,8 +204,8 @@ estimated_effort: epic ## Acceptance -- [ ] M1/M2/M4 迁移完成,vol3 只剩标准库相关文章。 -- [ ] 迁移完成后更新 index.md(M3)。 +- [x] M1/M2/M4 迁移完成,vol3 只剩标准库相关文章。 +- [x] 迁移完成后更新 index.md(M3)。 - [ ] 新卷三目录从平铺专题改为章节化结构。 - [ ] 第一部分:至少完成容器选择指南、vector 深入、string 深入、map/set、unordered_map。 - [ ] 第二部分:至少完成迭代器基础、算法总览(上)。 diff --git a/todo/020-projects.md b/todo/020-projects.md index c00c6fc8b..1df3dd1a3 100644 --- a/todo/020-projects.md +++ b/todo/020-projects.md @@ -27,7 +27,7 @@ estimated_effort: epic - **STM32F1 工程**:`code/stm32f1-tutorials/` 含 LED(C++23 模板)、Button(事件处理)、UART(中断驱动)三个可构建工程。 - **卷三 allocator 代码**:`code/examples/chapter07/06_custom_allocator/` 含 bump_allocator、stack_allocator 等 7 个文件。 -- **ETL demo**:`code/examples/chapter07/05_etl/` 含 ETL vector 参考实现。 +- **ETL demo**:`code/examples/chapter08/10_etl/` 含 ETL vector 参考实现。 - **卷五协程代码**:`code/volumn_codes/vol5/ch06-async-io-coroutine/` 含协程 echo server 基础代码。 ### 仅规划入口的资产