| 270 | */ |
| 271 | template<typename T, Concepts::ByteLike StorageType> |
| 272 | T IO::CircularBuffer<T, StorageType>::read(qsizetype size) |
| 273 | { |
| 274 | const qsizetype current_size = this->size(); |
| 275 | Q_ASSERT(size <= current_size); |
| 276 | if (size > current_size) [[unlikely]] |
| 277 | return T{}; |
| 278 | |
| 279 | T result; |
| 280 | result.resize(size); |
| 281 | |
| 282 | const qsizetype head = m_head.load(std::memory_order_relaxed); |
| 283 | const qsizetype firstChunk = std::min(size, m_capacity - head); |
| 284 | std::memcpy(result.data(), &m_buffer[head], firstChunk); |
| 285 | |
| 286 | if (size > firstChunk) [[unlikely]] |
| 287 | std::memcpy(result.data() + firstChunk, &m_buffer[0], size - firstChunk); |
| 288 | |
| 289 | const qsizetype new_head = (head + size) & m_capacityMask; |
| 290 | m_head.store(new_head, std::memory_order_release); |
| 291 | |
| 292 | return result; |
| 293 | } |
| 294 | |
| 295 | /** |
| 296 | * @brief Advances the read head by N bytes without copying. Cheaper than |
no test coverage detected