### Install ReaderWriterQueue via Header Files Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Include the necessary header files directly into your project for manual integration. ```cpp // Option 1: manual copy // Copy readerwriterqueue.h and atomicops.h into your source tree, then: #include "readerwriterqueue.h" #include "readerwritercircularbuffer.h" // only if using the circular buffer variant ``` -------------------------------- ### Install ReaderWriterQueue using CMake Source: https://github.com/cameron314/readerwriterqueue/blob/master/README.md Use CMake to build and install the library into your system's include directory. This method allows you to include the library in your projects without directly managing source files. ```bash mkdir build cd build cmake .. make install ``` -------------------------------- ### Basic Usage in C++ Main Function Source: https://github.com/cameron314/readerwriterqueue/blob/master/README.md A minimal C++ example showing how to include the `readerwriterqueue.h` header and instantiate a `ReaderWriterQueue` within a `main` function. ```cpp #include int main() { moodycamel::ReaderWriterQueue q(100); } ``` -------------------------------- ### Install ReaderWriterQueue after CMake Install Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Include the readerwriterqueue headers after installing the library using CMake's 'make install' command. ```cpp // Option 3: after CMake install (make install) #include ``` -------------------------------- ### Install ReaderWriterQueue with CMake FetchContent Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Use CMake's FetchContent module to download and integrate the readerwriterqueue library into your project. ```cmake include(FetchContent) FetchContent_Declare( readerwriterqueue GIT_REPOSITORY https://github.com/cameron314/readerwriterqueue GIT_TAG master ) FetchContent_MakeAvailable(readerwriterqueue) add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE readerwriterqueue) ``` -------------------------------- ### Include ReaderWriterQueue in C++ Source Source: https://github.com/cameron314/readerwriterqueue/blob/master/README.md After installation, include the library's header file in your C++ source code to start using its functionalities. ```cpp #include ``` -------------------------------- ### Inspect Front Element with `peek` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Get a raw pointer to the front element without removing it using `peek`. Returns `nullptr` if the queue is empty. This operation must be performed by a consumer thread only and does not affect the element's position in the queue. ```cpp #include "readerwriterqueue.h" #include using namespace moodycamel; ReaderWriterQueue q(4); q.enqueue(10); q.enqueue(20); int* front = q.peek(); assert(front != nullptr && *front == 10); // peek does not consume — try_dequeue still returns 10 first int val; q.try_dequeue(val); assert(val == 10); front = q.peek(); assert(front != nullptr && *front == 20); q.try_dequeue(val); front = q.peek(); assert(front == nullptr); // queue empty ``` -------------------------------- ### Introspect Queue Size and Capacity Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Use `size_approx()` to get an approximate count of elements, safe for concurrent access from both producer and consumer threads. `max_capacity()` returns the total number of slots available before allocation is needed when the queue is empty. Both methods are safe to call from any thread. ```cpp #include "readerwriterqueue.h" #include #include using namespace moodycamel; ReaderWriterQueue q(100); printf("Max capacity (pre-alloc): %zu\n", q.max_capacity()); // e.g. "Max capacity (pre-alloc): 127" (rounded up to next power-of-two minus 1) for (int i = 0; i < 50; ++i) q.enqueue(i); printf("Approximate size: %zu\n", q.size_approx()); // ~50 int v; for (int i = 0; i < 20; ++i) q.try_dequeue(v); printf("After 20 dequeues: %zu\n", q.size_approx()); // ~30 ``` -------------------------------- ### CMake Integration with FetchContent Source: https://github.com/cameron314/readerwriterqueue/blob/master/README.md Demonstrates how to integrate the readerwriterqueue library into an existing CMake project using `FetchContent`. This method downloads and builds the library as part of your project's build process. ```cmake include(FetchContent) FetchContent_Declare( readerwriterqueue GIT_REPOSITORY https://github.com/cameron314/readerwriterqueue GIT_TAG master ) FetchContent_MakeAvailable(readerwriterqueue) add_library(my_target main.cpp) target_link_libraries(my_target PUBLIC readerwriterqueue) ``` -------------------------------- ### Basic SPSC Queue Operations Source: https://github.com/cameron314/readerwriterqueue/blob/master/README.md Demonstrates basic enqueue and dequeue operations using ReaderWriterQueue. Use `enqueue` for dynamic resizing and `try_enqueue` for non-allocating, slot-limited additions. `try_dequeue` attempts to remove an element without blocking. ```cpp using namespace moodycamel; ReaderWriterQueue q(100); // Reserve space for at least 100 elements up front q.enqueue(17); // Will allocate memory if the queue is full bool succeeded = q.try_enqueue(18); // Will only succeed if the queue has an empty slot (never allocates) assert(succeeded); int number; succeeded = q.try_dequeue(number); // Returns false if the queue was empty assert(succeeded && number == 17); // You can also peek at the front item of the queue (consumer only) int* front = q.peek(); assert(*front == 18); succeeded = q.try_dequeue(number); assert(succeeded && number == 18); front = q.peek(); assert(front == nullptr); // Returns nullptr if the queue was empty ``` -------------------------------- ### Construct Elements In-Place with `try_emplace` and `emplace` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Use `try_emplace` for non-allocating in-place construction or `emplace` when allocation is acceptable. Both methods use perfect forwarding to construct elements directly within the queue's storage, avoiding intermediate copies or moves. `try_emplace` is guaranteed not to allocate memory. ```cpp #include "readerwriterqueue.h" #include #include using namespace moodycamel; struct Point { int x, y; }; ReaderWriterQueue q(16); // Construct Point{3, 7} directly in-place — no temporary created bool ok = q.try_emplace(3, 7); assert(ok); // emplace may allocate if queue is full ok = q.emplace(10, 20); assert(ok); // Works with string args too ReaderWriterQueue sq(8); sq.try_emplace(5, 'x'); // constructs std::string(5, 'x') == "xxxxx" ``` -------------------------------- ### BlockingReaderWriterQueue with wait_dequeue Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Demonstrates indefinite blocking dequeue using wait_dequeue and timed dequeue with wait_dequeue_timed. Ensure the queue is initialized before use. ```cpp #include "readerwriterqueue.h" #include #include #include using namespace moodycamel; BlockingReaderWriterQueue q(64); std::thread producer([&] { for (int i = 0; i < 10; ++i) { q.enqueue(i); std::this_thread::sleep_for(std::chrono::milliseconds(5)); } }); std::thread consumer([&] { int item; for (int i = 0; i < 10; ++i) { // Blocks indefinitely until an element is available q.wait_dequeue(item); assert(item == i); } // Timed variant (returns false on timeout) bool got = q.wait_dequeue_timed(item, std::chrono::milliseconds(50)); assert(!got); // producer is done; times out // Raw microseconds overload got = q.wait_dequeue_timed(item, std::int64_t(1000)); // 1 ms assert(!got); }); producer.join(); consumer.join(); assert(q.size_approx() == 0); ``` -------------------------------- ### `ReaderWriterQueue::peek` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Provides a raw pointer to the front element without removing it. Returns `nullptr` if the queue is empty. This operation must be called exclusively from the consumer thread. ```APIDOC ## `ReaderWriterQueue::peek` — Inspect Front Without Removing Returns a **raw pointer** to the front element (the next one `try_dequeue` would remove), or `nullptr` if the queue is empty. The element is not removed. Must be called from the **consumer thread only**. ### Method - `const T* peek() const` ### Description Returns a pointer to the front element without removing it. Returns `nullptr` if the queue is empty. This method is intended for use by consumer threads only. ### Request Example ```cpp ReaderWriterQueue q(4); q.enqueue(10); q.enqueue(20); int* front = q.peek(); // front points to 10 int val; q.try_dequeue(val); // val is 10 front = q.peek(); // front points to 20 q.try_dequeue(val); // val is 20 front = q.peek(); // front is nullptr ``` ### Response - `const T*`: A pointer to the front element, or `nullptr` if the queue is empty. ``` -------------------------------- ### Construct ReaderWriterQueue with Custom MAX_BLOCK_SIZE Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Instantiate a ReaderWriterQueue with a custom MAX_BLOCK_SIZE, suitable for cases where element counts are known and small. Memory is pre-allocated for a specified number of elements. ```cpp // Custom MAX_BLOCK_SIZE — useful when element count is known and small ReaderWriterQueue small_q(50); ``` -------------------------------- ### Construct ReaderWriterQueue with Default MAX_BLOCK_SIZE Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Create a ReaderWriterQueue instance pre-allocating memory for a specified number of elements. The default MAX_BLOCK_SIZE of 512 is used. ```cpp #include "readerwriterqueue.h" using namespace moodycamel; // Pre-allocate for 1000 elements; MAX_BLOCK_SIZE stays at the default 512 ReaderWriterQueue q(1000); ``` -------------------------------- ### Move Construct ReaderWriterQueue Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Create a new ReaderWriterQueue by moving from an existing one. Note that the move operation itself is not thread-safe. ```cpp // Move construction (not thread-safe during the move itself) ReaderWriterQueue q2(std::move(q)); ``` -------------------------------- ### `ReaderWriterQueue::size_approx` / `max_capacity` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Provides approximate size and maximum capacity information about the queue. Both methods are safe to call from any thread. ```APIDOC ## `ReaderWriterQueue::size_approx` / `max_capacity` — Introspection `size_approx()` returns an approximate element count (safe to call from both threads). `max_capacity()` returns the total number of slots that could be enqueued without allocation when the queue is empty (safe from both threads, but see the note about concurrent consumer activity). ### Methods - `size_t size_approx() const` - `size_t max_capacity() const` ### Description `size_approx()` returns an approximate count of elements currently in the queue. `max_capacity()` returns the total number of slots available in the queue when it is empty. Both methods are thread-safe. ### Request Example ```cpp ReaderWriterQueue q(100); // Example output: Max capacity (pre-alloc): 127 (rounded up to next power-of-two minus 1) printf("Max capacity (pre-alloc): %zu\n", q.max_capacity()); for (int i = 0; i < 50; ++i) q.enqueue(i); // Example output: Approximate size: ~50 printf("Approximate size: %zu\n", q.size_approx()); int v; for (int i = 0; i < 20; ++i) q.try_dequeue(v); // Example output: After 20 dequeues: ~30 printf("Approximate size after 20 dequeues: %zu\n", q.size_approx()); ``` ### Response - `size_t`: For `size_approx()`, the approximate number of elements. For `max_capacity()`, the maximum number of elements the queue can hold without allocation. ``` -------------------------------- ### `ReaderWriterQueue::try_emplace` / `ReaderWriterQueue::emplace` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Constructs an element directly within the queue's storage using perfect forwarding. `try_emplace` avoids allocation, while `emplace` may allocate if the queue is full. ```APIDOC ## `ReaderWriterQueue::try_emplace` / `ReaderWriterQueue::emplace` — In-Place Construction Construct an element directly inside the queue's storage using perfect forwarding, avoiding any intermediate copy or move. `try_emplace` never allocates; `emplace` may allocate. ### Method - `bool try_emplace(Args&&... args)` - `bool emplace(Args&&... args)` ### Description Constructs an element directly within the queue's storage using perfect forwarding. `try_emplace` never allocates; `emplace` may allocate if the queue is full. ### Request Example ```cpp struct Point { int x, y; }; ReaderWriterQueue q(16); // Construct Point{3, 7} directly in-place — no temporary created bool ok = q.try_emplace(3, 7); // emplace may allocate if queue is full ok = q.emplace(10, 20); // Works with string args too ReaderWriterQueue sq(8); sq.try_emplace(5, 'x'); // constructs std::string(5, 'x') == "xxxxx" ``` ### Response - `bool`: `true` if the element was successfully constructed, `false` otherwise (e.g., if `try_emplace` would have allocated). ``` -------------------------------- ### Blocking SPSC Queue with Threads Source: https://github.com/cameron314/readerwriterqueue/blob/master/README.md Illustrates using `BlockingReaderWriterQueue` with multiple threads for producer-consumer scenarios. `wait_dequeue` blocks indefinitely if the queue is empty, requiring careful usage to avoid deadlocks or undefined behavior, especially during queue destruction. ```cpp BlockingReaderWriterQueue q; std::thread reader([&]() { int item; #if 1 for (int i = 0; i != 100; ++i) { // Fully-blocking: q.wait_dequeue(item); } #else for (int i = 0; i != 100; ) { // Blocking with timeout if (q.wait_dequeue_timed(item, std::chrono::milliseconds(5))) ++i; } #endif }); std::thread writer([&]() { for (int i = 0; i != 100; ++i) { q.enqueue(i); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }); writer.join(); reader.join(); assert(q.size_approx() == 0); ``` -------------------------------- ### Enqueue with Dynamic Growth Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Enqueues a value, dynamically allocating new memory blocks if the current ones are full. Returns false only if memory allocation fails. Supports both copy and move semantics. ```cpp #include "readerwriterqueue.h" #include using namespace moodycamel; ReaderWriterQueue q(4); // Copy-enqueue bool ok = q.enqueue(std::string("hello")); assert(ok); // Move-enqueue (no copy of the string data) std::string msg = "world"; ok = q.enqueue(std::move(msg)); assert(ok); assert(msg.empty()); // moved-from // Enqueue beyond initial capacity — allocates a new block automatically for (int i = 0; i < 100; ++i) { ok = q.enqueue(std::to_string(i)); assert(ok); // only fails on OOM } ``` -------------------------------- ### ReaderWriterQueue Constructor Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Constructs a non-blocking SPSC queue that pre-allocates memory. It can optionally take a custom MAX_BLOCK_SIZE. ```APIDOC ## ReaderWriterQueue - Constructor Constructs a non-blocking SPSC queue that pre-allocates enough contiguous memory to hold at least `size` elements without further allocation. `MAX_BLOCK_SIZE` (default `512`) controls the maximum number of elements per internal block and must be a power of two ≥ 2. ```cpp #include "readerwriterqueue.h" using namespace moodycamel; // Pre-allocate for 1000 elements; MAX_BLOCK_SIZE stays at the default 512 ReaderWriterQueue q(1000); // Custom MAX_BLOCK_SIZE — useful when element count is known and small ReaderWriterQueue small_q(50); // Move construction (not thread-safe during the move itself) ReaderWriterQueue q2(std::move(q)); ``` ``` -------------------------------- ### BlockingReaderWriterCircularBuffer with wait_enqueue and wait_dequeue Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Illustrates a fixed-capacity circular buffer that blocks on both enqueue (when full) and dequeue (when empty). Use wait_enqueue_timed and wait_dequeue_timed for operations with timeouts. Non-blocking variants like try_enqueue and try_dequeue are also available. ```cpp #include "readerwritercircularbuffer.h" #include #include #include using namespace moodycamel; // Fixed capacity of 4 slots — producer will block when full BlockingReaderWriterCircularBuffer q(4); std::thread producer([&] { for (int i = 0; i < 8; ++i) { // Blocks when queue is full (back-pressure to producer) q.wait_enqueue(i); } // Timed enqueue — returns false if slot not available in time bool ok = q.wait_enqueue_timed(99, std::chrono::milliseconds(10)); (void)ok; }); std::thread consumer([&] { int item; for (int i = 0; i < 8; ++i) { q.wait_dequeue(item); assert(item == i); std::this_thread::sleep_for(std::chrono::milliseconds(2)); } // Timed dequeue with std::chrono duration bool got = q.wait_dequeue_timed(item, std::chrono::milliseconds(100)); (void)got; }); producer.join(); consumer.join(); // Non-blocking variants q.try_enqueue(1); int v; bool got = q.try_dequeue(v); assert(got && v == 1); // Peek without removing q.try_enqueue(42); int* front = q.peek(); assert(front && *front == 42); q.try_pop(); // discard without returning value assert(q.size_approx() == 0); assert(q.max_capacity() == 4); ``` -------------------------------- ### Discard Front Element with `pop` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Remove and destroy the front element using `pop`. Returns `true` if an element was successfully removed, and `false` if the queue was empty. This is useful when an element has already been inspected via `peek` and no longer needs to be retained. This operation must be performed by a consumer thread only. ```cpp #include "readerwriterqueue.h" #include using namespace moodycamel; ReaderWriterQueue q(4); q.enqueue(1); q.enqueue(2); int* front = q.peek(); assert(front && *front == 1); bool removed = q.pop(); // discard 1 assert(removed); front = q.peek(); assert(front && *front == 2); q.pop(); // discard 2 assert(!q.pop()); // false — queue empty ``` -------------------------------- ### Non-Blocking Dequeue with `try_dequeue` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Attempt to move the front element into a provided variable using `try_dequeue`. This method is thread-safe for consumers and returns `true` on success, moving the value, or `false` if the queue is empty without modifying the target variable. It is suitable for move-only types. ```cpp #include "readerwriterqueue.h" #include using namespace moodycamel; ReaderWriterQueue q(4); q.enqueue(42); q.enqueue(99); int val; bool got = q.try_dequeue(val); assert(got && val == 42); got = q.try_dequeue(val); assert(got && val == 99); got = q.try_dequeue(val); assert(!got); // queue is empty // Works with move-only types ReaderWriterQueue> pq(4); pq.enqueue(std::make_unique(7)); std::unique_ptr ptr; pq.try_dequeue(ptr); assert(*ptr == 7); ``` -------------------------------- ### Non-Allocating Enqueue with try_enqueue Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Attempts to enqueue a value without allocating memory. Returns false immediately if no free slot is available in the existing blocks. Ideal for performance-critical paths where guaranteed delivery is secondary to predictable latency. ```cpp #include "readerwriterqueue.h" #include using namespace moodycamel; ReaderWriterQueue q(8); // exactly 8 slots guaranteed int dropped = 0; for (int i = 0; i < 12; ++i) { if (!q.try_enqueue(i)) { ++dropped; // no allocation; just reports failure } } // At most 8 items fit; at least 4 were dropped (exact count depends on consumer) assert(dropped >= 0); ``` -------------------------------- ### `ReaderWriterQueue::try_dequeue` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Attempts to move the front element into the provided result variable. Returns `true` on success and `false` if the queue is empty. This operation must be called exclusively from the consumer thread. ```APIDOC ## `ReaderWriterQueue::try_dequeue` — Non-Blocking Dequeue Attempts to move the front element into `result`. Returns `true` and moves the value on success; returns `false` without modifying `result` if the queue is empty. Must be called from the **consumer thread only**. ### Method - `bool try_dequeue(T& result)` ### Description Attempts to move the front element into `result`. Returns `true` on success, `false` if the queue is empty. This method is intended for use by consumer threads only. ### Parameters #### Request Body - `result` (T&): A reference to a variable where the dequeued element will be moved. ### Request Example ```cpp ReaderWriterQueue q(4); q.enqueue(42); q.enqueue(99); int val; bool got = q.try_dequeue(val); // got is true, val is 42 got = q.try_dequeue(val); // got is true, val is 99 got = q.try_dequeue(val); // got is false, val is unchanged // Works with move-only types ReaderWriterQueue> pq(4); pq.enqueue(std::make_unique(7)); std::unique_ptr ptr; pq.try_dequeue(ptr); // ptr now owns the unique_ptr with value 7 ``` ### Response - `bool`: `true` if an element was successfully dequeued and moved, `false` if the queue was empty. ``` -------------------------------- ### ReaderWriterQueue::try_enqueue Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Enqueues a value without allocating memory. Returns `false` immediately if there is no free slot in the existing blocks. Use this on the hot path when predictable latency matters more than guaranteed delivery. ```APIDOC ## ReaderWriterQueue::try_enqueue - Non-Allocating Enqueue Enqueues a value **without allocating memory**. Returns `false` immediately if there is no free slot in the existing blocks. Use this on the hot path when predictable latency matters more than guaranteed delivery. ```cpp #include "readerwriterqueue.h" #include using namespace moodycamel; ReaderWriterQueue q(8); // exactly 8 slots guaranteed int dropped = 0; for (int i = 0; i < 12; ++i) { if (!q.try_enqueue(i)) { ++dropped; // no allocation; just reports failure } } // At most 8 items fit; at least 4 were dropped (exact count depends on consumer) assert(dropped >= 0); ``` ``` -------------------------------- ### Blocking Circular Buffer Operations Source: https://github.com/cameron314/readerwriterqueue/blob/master/README.md Shows how to use `BlockingReaderWriterCircularBuffer`, which has a fixed capacity. It supports non-blocking `try_enqueue`/`try_dequeue` and blocking `wait_enqueue`/`wait_dequeue` operations, including timed waits. ```cpp BlockingReaderWriterCircularBuffer q(1024); // pass initial capacity q.try_enqueue(1); int number; q.try_dequeue(number); assert(number == 1); q.wait_enqueue(123); q.wait_dequeue(number); assert(number == 123); q.wait_dequeue_timed(number, std::chrono::milliseconds(10)); ``` -------------------------------- ### `ReaderWriterQueue::pop` Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Removes and destroys the front element without returning it. Returns `true` if an element was removed, and `false` if the queue was empty. This operation must be called exclusively from the consumer thread. ```APIDOC ## `ReaderWriterQueue::pop` — Discard Front Element Removes and destroys the front element without returning it. Returns `true` on success, `false` if the queue was empty. Useful when the value was already read via `peek`. Must be called from the **consumer thread only**. ### Method - `bool pop()` ### Description Removes and destroys the front element without returning it. Returns `true` if an element was successfully removed, `false` if the queue was empty. This method is intended for use by consumer threads only. ### Request Example ```cpp ReaderWriterQueue q(4); q.enqueue(1); q.enqueue(2); q.pop(); // removes and destroys 1, returns true q.pop(); // removes and destroys 2, returns true bool removed = q.pop(); // returns false, queue is empty ``` ### Response - `bool`: `true` if the front element was successfully removed and destroyed, `false` if the queue was empty. ``` -------------------------------- ### ReaderWriterQueue::enqueue Source: https://context7.com/cameron314/readerwriterqueue/llms.txt Enqueues a copy or moved value. If the current internal blocks are full, it allocates a new block. Returns `false` only if memory allocation fails. ```APIDOC ## ReaderWriterQueue::enqueue - Enqueue with Dynamic Growth Enqueues a copy or moved value. If the current internal blocks are full, allocates a new block (doubles in size up to `MAX_BLOCK_SIZE`). Returns `false` only if memory allocation fails. ```cpp #include "readerwriterqueue.h" #include using namespace moodycamel; ReaderWriterQueue q(4); // Copy-enqueue bool ok = q.enqueue(std::string("hello")); assert(ok); // Move-enqueue (no copy of the string data) std::string msg = "world"; ok = q.enqueue(std::move(msg)); assert(ok); assert(msg.empty()); // moved-from // Enqueue beyond initial capacity — allocates a new block automatically for (int i = 0; i < 100; ++i) { ok = q.enqueue(std::to_string(i)); assert(ok); // only fails on OOM } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.