{"id":29104751,"url":"https://github.com/nholthaus/queue","last_synced_at":"2025-06-29T00:33:53.880Z","repository":{"id":40247242,"uuid":"299389052","full_name":"nholthaus/queue","owner":"nholthaus","description":"C++17 Library of various queue containers","archived":false,"fork":false,"pushed_at":"2024-08-16T17:10:30.000Z","size":2699,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T22:31:35.282Z","etag":null,"topics":["circular-buffers","concurrent-data-structure","iterators","queues"],"latest_commit_sha":null,"homepage":"https://nholthaus.github.io/queue/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nholthaus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-28T17:53:24.000Z","updated_at":"2024-12-25T18:39:00.000Z","dependencies_parsed_at":"2024-11-21T06:34:16.323Z","dependency_job_id":null,"html_url":"https://github.com/nholthaus/queue","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/nholthaus/queue","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nholthaus%2Fqueue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nholthaus%2Fqueue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nholthaus%2Fqueue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nholthaus%2Fqueue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nholthaus","download_url":"https://codeload.github.com/nholthaus/queue/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nholthaus%2Fqueue/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262518102,"owners_count":23323301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["circular-buffers","concurrent-data-structure","iterators","queues"],"created_at":"2025-06-29T00:33:00.415Z","updated_at":"2025-06-29T00:33:53.868Z","avatar_url":"https://github.com/nholthaus.png","language":"C++","readme":"![Build Status](https://github.com/nholthaus/queue/actions/workflows/cmake-multi-platform.yml/badge.svg) ![language](https://img.shields.io/badge/language-c++20-blue.svg) ![license](https://img.shields.io/badge/license-MIT-orange.svg) ![copyright](https://img.shields.io/badge/%C2%A9-Nic_Holthaus-orange.svg) ![msvc2022](https://img.shields.io/badge/MSVC-2022-ff69b4.svg) ![gcc-11.4.0](https://img.shields.io/badge/GCC-11.4.0-ff69b4.svg)\n\nA modern C++ header-only library of various types of queue\n\n# Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Build Instructions](#build-instructions)\n- [Usage](#usage)\n  - [Concurrent Queue](#concurrent-queue)\n    - [Example](#example)\n  - [Circular Queue](#circular-queue)\n    - [Example](#example-1)\n\n# Build Instructions\n\nEach class in the library itself is a single header only. You can use the included CMake in a subdirectory and add the interface library, or just copy the `*.h` files (and license) into your project.\n\nTo build and run the unit tests:\n\n``` bash\nmkdir build\ncd build\ncmake -DBUILD_TESTS=ON ..\ncmake --build . --config Release\nctest\n```\n\nTo build the documentation, replace the above `cmake` command with the following:\n\n```\ncmake -DBUILD_TESTS=ON -DBUILD_DOCUMENTATION=ON ..\n```\n\n# Usage\n\n## Concurrent Queue\n\nThe `concurrent_queue` class is a templated FIFO (first-in, first-out) queue that is suitable for concurrent use, including cases where there are multiple producers and multiple consumers reading and writing the queue simultaneously. It has an atomic `push`/`pop` interface for enqueueing and dequeueing elements.\n\n### Example\n\nRun it live on [Compiler Explorer](https://godbolt.org/z/Gn3znj).\n\n``` cpp\n#include \u003cchrono\u003e\n#include \u003cfuture\u003e\n#include \u003ciostream\u003e\n#include \u003cnumeric\u003e\n#include \u003cthread\u003e\n#include \u003cvector\u003e\n\n#include \u003cconcurrent_queue.h\u003e\n\nusing namespace std::chrono_literals;\n\nint main()\n{\n        // Push 100 ints from one deque to another via a set of producer/consumer threads\n        // running at different rates via a concurrent queue\n        \n        constexpr int    test_size = 100;\n        std::deque\u003cint\u003e numbers_in(test_size);\n        std::deque\u003cint\u003e numbers_out;\n        std::iota(numbers_in.begin(), numbers_in.end(), 0);\n        \n        std::cout \u003c\u003c \"In size: \" \u003c\u003c numbers_in.size() \u003c\u003c std::endl;\n        std::cout \u003c\u003c \"Out size: \" \u003c\u003c numbers_out.size() \u003c\u003c std::endl;\n        \n        concurrent_queue\u003cint\u003e queue;\n        \n        // produce integers at 200Hz and consume them at 1000 Hz\n        auto producer = std::async(std::launch::async, [\u0026queue, \u0026numbers_in]\n               {\n                   while(!numbers_in.empty())\n                   {\n                       queue.push(numbers_in.front());\n                       numbers_in.pop_front();\n                       std::this_thread::sleep_for(5ms);\n                   }\n                   return std::this_thread::get_id();\n               });\n        auto consumer = std::async(std::launch::async, [\u0026queue, \u0026numbers_out, test_size]\n               {\n                   int val;\n                   while (numbers_out.size() \u003c test_size)\n                   {\n                       if (queue.try_pop_for(val, 1ms))\n                           numbers_out.push_back(val);\n                   }\n                   return std::this_thread::get_id();\n               });\n\n        auto producer_id = producer.get();\n        auto consumer_id = consumer.get();\n        \n        std::cout \u003c\u003c \"In size: \" \u003c\u003c numbers_in.size() \u003c\u003c std::endl;\n        std::cout \u003c\u003c \"Out size: \" \u003c\u003c numbers_out.size() \u003c\u003c std::endl;\n}\n```\n\n## Circular Queue\n\nThe `circular_queue` class is a fixed capacity, STL-style, templated circular buffer.\n\nSee http://en.wikipedia.org/wiki/Circular_buffer for details of how circular buffers work.\n\nThis implementation shares many features of a double-ended queue. This structure allows for the individual elements to be accessed directly through random access iterators, with storage handled automatically by over-writing elements from the opposite end of the container as it grows. As long as elements are added consistently to EITHER the front or the back, once full, the container will expand by over-writing the oldest element. If elements are added to both sides of the buffer, the behavior is effectively user defined.\n\nTherefore, the `circular_queue` provides a functionality similar to vectors, but with efficient insertion and deletion of elements also at the beginning of the sequence, and not only at its end. Also, like vectors (and unlike dequeues), all elements are stored in contiguous memory locations, and offset access IS allowed.\n\nBoth vectors and the `circular_queue` provide a very similar interface and can be used for similar purposes, but internally both work in quite different ways: While vectors use a single array that needs to be occasionally reallocated for growth, the elements of a `circular_queue` are over-written once the buffer reaches its maximum capacity, ensuring elements are inserted and accessed in constant time and with a uniform sequential interface (through iterators), as opposed to the vector's amortized constant time. This allows them to grow more efficiently under certain circumstances, especially with very long sequences, where reallocation's become more expensive, and real-time applications where stale data is not as useful as current data.\n\nFor operations that involve frequent insertion or removals of elements at positions other than the beginning or the end, `circular_queue` performs worse and has less consistent iterators and references than lists and forward lists.\n\n### Example\n\nRun it live on [Compiler Explorer](https://godbolt.org/z/f3dscW).\n\n``` cpp\n#include \u003ciostream\u003e\n#include \u003ccircular_queue.h\u003e\n\nint main()\n{\n    circular_queue\u003cint\u003e q(10);\n\n    for(int i = 0; i \u003c 13; ++i)\n    {\n        q.push_back(i);\n        if(q.full()) std::cout \u003c\u003c \"Buffer Overflow!\" \u003c\u003c std::endl;\n    }\n\n    for(unsigned int i = 0; i \u003c q.size(); ++i)\n    {\n        std::cout \u003c\u003c \"q[\" \u003c\u003c i \u003c\u003c \"]: \" \u003c\u003c q[i] \u003c\u003c std::endl;\n    }\n}\n\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnholthaus%2Fqueue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnholthaus%2Fqueue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnholthaus%2Fqueue/lists"}