{"id":20730590,"url":"https://github.com/gbmhunter/cpputils","last_synced_at":"2025-08-03T19:38:11.098Z","repository":{"id":69958333,"uuid":"100288026","full_name":"gbmhunter/CppUtils","owner":"gbmhunter","description":"A library with a range of utility classes and methods for jump starting C++ applications.","archived":false,"fork":false,"pushed_at":"2019-05-20T18:25:18.000Z","size":78,"stargazers_count":18,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-30T03:51:15.227Z","etag":null,"topics":["bit-manipulation","cpp","event","library","queue","threadsafe","utility"],"latest_commit_sha":null,"homepage":null,"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/gbmhunter.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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":"2017-08-14T16:32:09.000Z","updated_at":"2025-02-23T18:03:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"271988f2-c5c0-4603-98ed-16796590a859","html_url":"https://github.com/gbmhunter/CppUtils","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FCppUtils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FCppUtils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FCppUtils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbmhunter%2FCppUtils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gbmhunter","download_url":"https://codeload.github.com/gbmhunter/CppUtils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250522298,"owners_count":21444511,"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":["bit-manipulation","cpp","event","library","queue","threadsafe","utility"],"created_at":"2024-11-17T05:12:04.312Z","updated_at":"2025-04-23T22:02:30.878Z","avatar_url":"https://github.com/gbmhunter.png","language":"C++","readme":"========\nCppUtils\n========\n\n-----------------------------------------------------------------------------------------\nA library with a range of utility classes and methods for jump starting C++ applications.\n-----------------------------------------------------------------------------------------\n\n.. image:: https://travis-ci.org/gbmhunter/CppUtils.svg?branch=master\n\t:target: https://travis-ci.org/gbmhunter/CppUtils\n\nBits.hpp\n========\n\nContains static bit manipulation methods. This includes methods for generating a bit mask, getting an arbitrary sequence of bits from an integer type, or setting an arbitrary sequence of bits in an integer type.\n\n**BitMask()**\n\n.. code:: cpp\n\n    uint8_t bitMask;\n    bitMask = Bits::BitMask\u003cuint8_t\u003e(1));\n    // bitMask = 0b00000001 or 0x01\n\n    bitMask = Bits::BitMask\u003cuint8_t\u003e(4));\n    // bitMask = 0b00001111 or 0x0F\n\n    bitMask = Bits::BitMask\u003cuint32_t\u003e(11));\n    // bitMask = 0x000007FF\n\n**GetBits()**\n\n.. code:: cpp\n\n    uint8_t result;\n    result = Bits::GetBits(0b11001100, 0, 3));\n    // result = 0b00000100 or 0x4\n\n    result = Bits::GetBits(0b11001100, 2, 5));\n    // result = 0b00010011 or 0x13\n\n**SetBits()**\n\n.. code:: cpp\n\n    uint8_t result;\n    result = Bits::SetBits(0b00000000, 0b11011, 0, 5));\n    // result = 0b00011011 or 0x1B\n\n    result = Bits::SetBits(0b11111111, 0b11011, 0, 5));\n    // result = 0b11111011 or 0xFB\n\nEvent.hpp\n=========\n\nContains a basic event class which you can use to implement an event/listener based design.\n\n**Basic Example**\n\n.. code:: cpp\n\n    Event\u003cvoid()\u003e event;\n\n    event.AddListener([\u0026](){\n        std::cout \u003c\u003c \"Listener called!\" \u003c\u003c std::endl;\n    });\n\n    event.Fire(); // Prints \"Listener called!\"\n\n**One Input Parameter**\n\n.. code:: cpp\n\n    Event\u003cvoid(std::string)\u003e event;\n\n    event.AddListener([\u0026](std::string msg){\n        std::cout \u003c\u003c msg \u003c\u003c std::endl;\n    });\n\n    event.Fire(\"Hello\"); // Prints \"Hello\"\n\n**Bind To Method**\n\n.. code:: cpp\n\n    class TestClass {\n        void TestMethod() {\n            std::cout \u003c\u003c \"TestMethod() called.\" \u003c\u003c std::endl;\n        }\n    }\n\n    int main() {\n        TestClass testClass;\n\n        Event\u003cvoid(std::string)\u003e event;\n\n        event.AddListener(std::bind(\u0026TestClass::TestMethod, \u0026testClass));\n\n        event.Fire(); // Prints \"TestMethod() called\"\n    }\n\nException.hpp\n=============\n\nException.hpp provides functionality to throw an exception which will print the file name and line number that it was thrown on, which can be of great help when debugging!\n\nOnce including the header file, you can throw one of these exceptions with the :code:`THROW_EXCEPT()` macro, as shown in the below code:\n\n.. code:: cpp\n\n    #include \"CppUtils/Exception.hpp\"\n\n    int main() {\n        THROW_EXCEPT(\"Something bad happened!\");\n    }\n\nThe above code will print:\n\n.. code:: cpp\n\n    terminate called after throwing an instance of 'Exception'\n      what(): /home/user/main.cpp:4: Something bad happened!\n\n\nHeapTracker.hpp\n===============\n\nHeapTracker.hpp contains a :code:`HeapTracker` class which can be used keep track of memory allocations and deallocations (via :code:`new`, :code:`new[]`, :code:`delete`, and :code:`delete[]`) to the heap.\n\n**Usage:**\n\n.. code:: cpp\n\n    #include \"CppUtils/HeapTracker.hpp\"\n\n    // IMPORTANT! Only use these macros in one .cpp file. These macros define functions for new and delete\n    // which override the default ones provided by the compiler. These new functions define some additional\n    // code to keep track of new/delete calls.\n    HEAP_TRACKER_NEW;\n    HEAP_TRACKER_DELETE;\n\n    int main() {\n        std::cout \u003c\u003c \"Heap size (B) = \" \u003c\u003c HeapTracker::Instance().GetHeapSize_B() \u003e\u003e std::endl;\n        // Prints some value \"x\"\n\n        uint8_t* tempBuffer = new uint8_t[100];\n\n        std::cout \u003c\u003c \"Heap size (B) = \" \u003c\u003c HeapTracker::Instance().GetHeapSize_B() \u003e\u003e std::endl;\n        // Prints \"x + 100\"\n\n        delete[] tempBuffer;\n\n        std::cout \u003c\u003c \"Heap size (B) = \" \u003c\u003c HeapTracker::Instance().GetHeapSize_B() \u003e\u003e std::endl;\n        // Prints \"x\" again\n\n        return 0;\n    }\n\n**Points To Note:**\n\n- :code:`HeapTracker` is thread safe. :code:`HeapTracker::Instance().GetHeapSize_B()` can be called from multiple threads. The additions to the overriden new and delete functions are also thread safe.\n- :code:`HeapTracker` does not report the **exact** number of bytes used by the heap. This is becausethe compiler adds additional meta-data to a heap allocation so that :code:`delete` knows exactly how to delete the provided memory pointer (e.g. how many array elements to delete if :code:`delete[]` is called). Typically this is done by inserting a byte before the returned pointer which holds this meta-data, although this is implementation specific. Also, :code:`HeapTracker` creates a map on the heap to store needed pointer/size data which is not counted by :code:`GetHeapSize_B()` (a custom allocator is used to prevent infinite recursion). Thus the number returned by :code:`GetHeapSize_B()` will always be slightly less than the true heap usage, although should still be relatively accurate.\n- As mentioned above, the macros :code:`HEAP_TRACKER_NEW` and :code:`HEAP_TRACKER_DELETE` should be included in only one source file. However, :code:`#include CppUtils/HeapTracker.hpp` can be included in as many files as you want.\n- Using :code:`HeapTracker` imposes a **small** performance penalty as extra code is run on every call to :code:`new` or :code:`delete`. For every :code:`new`, a :code:`std::mutex` is locked, a map entry is created and the byte count incremented. On every :code:`delete`, a :code:`std::mutex` is locked, a map key/value pair is looked up and removed, and the byte count decremented.\n- :code:`HeapTracker` is not able to keep track of heap allocations that do not use the standard :code:`new`/:code:`delete`. This includes any use of :code:`malloc()`/:code:`free()` and custom allocators.\n- :code:`HeapTracker` is a thread-safe Singleton. Use :code:`HeapTracker::Instance()` to acquire a reference to the single instance.\n\nLogger.hpp\n==========\n\nA simpler header-only logging class which supports:\n\n- printf() style support (for the easy logging of integers, hex values, e.t.c)\n- Different logging severities (e.g. DEBUG, WARNING, ERROR)\n- Automatic capture of filename, line number and function name\n- User control of where to direct logging output (does not automatically go to std::cout)\n- ANSI colour support\n\n**Usage:**\n\n.. code:: cpp\n\n    #include \"CppUtils/Logger.hpp\"\n\n    using namespace mn::CppUtils;\n\n    int main() {\n        Logger logger(\"ExampleLogger\", Logger::Severity::DEBUG, Logger::Color::BLUE, [](Logger::Severity severity, std::string msg){\n            std::cout \u003c\u003c msg \u003c\u003c std::endl;\n        });\n\n        int myNum = 5;\n        LOG(logger, \"My num. = %i\", myNum); // Prints \"ExampleLogger (/home/CppUtils/Example.cpp, 10, main()). DEBUG: My num. = 5\" in a blue font\n    }\n\n\nStrConv.hpp\n===========\n\nA header-only collection of \"to string\" conversion methods which convert various objects (incl discrete values and iterable types) to various string representations.\n\n**ToHex()**\n\n.. code:: cpp\n\n    std::cout \u003c\u003c StrConv::ToHex(15, 2) \u003c\u003c std::endl;\n    // Prints \"0xFF\"\n\n    std::cout \u003c\u003c StrConv::ToHex(4, 3) \u003c\u003c std::endl;\n    // Prints \"0x004\"\n\n    std::cout \u003c\u003c StrConv::ToHex(std::vector({ 0x0A, 0x0B }) \u003c\u003c std::endl;\n    // Prints \"{ 0x0A, 0x0B }\"\n\n**ToAscii()**\n\n.. code:: cpp\n\n    std::cout \u003c\u003c StrConv::ToAscii(std::vector({ 'a', 'b' }) \u003c\u003c std::endl;\n    // Prints \"{ 'a', 'b' }\"\n\n\nThreadSafeQueue.hpp\n===================\n\nContains a cross-platform thread safe queue object which uses the C++14 standard only (no UNIX :code:`pthread` or Windows :code:`CreateThread`).\n\nTimer.hpp\n=========\n\nA timer which allows you to run code after a timeout occurs (code will be run within a new timer thread).\n\n.. code:: cpp\n\n    #include \u003catomic\u003e\n    #include \"CppUtils/Timer.hpp\"\n    using namespace std::literals;\n\n    std::atomic\u003cbool\u003e callbackCalled(false);\n    Timer timer(100ms, [\u0026]{\n        // This will be called in the context of a timer thread, be aware\n        // of concurrency concerns!\n        callbackCalled.store(true);\n    });\n\n    std::this_thread::sleep_for(200ms);\n\n    std::cout \u003c\u003c \"callbackCalled = \" \u003c\u003c callbackCalled.load() \u003c\u003c std::endl;\n    // Prints \"true\"\n\nTimerWheel.hpp\n==============\n\nThis header file contains a :code:`TimerWheel` class that can be used to easily create and manage timers (timeouts) in a multi-threaded environment.\n\n**Single-Shot Timer Example**\n\n.. code:: cpp\n\n    #include \"CppUtils/TimerWheel.hpp\"\n\n    using namespace std::literals;\n    using namespace mn::CppUtils::TimerWheel;\n\n    int main() {\n        TimerWheel timerWheel;\n\n        timerWheel.AddSingleShotTimer(500ms, [\u0026]() {\n            std::cout \u003c\u003c \"Timer expired!\" \u003c\u003c std::endl;\n        });\n\n        std::this_thread::sleep_for(1000ms);\n\n        // \"Timer expired!\" will be printed after 500ms\n    }\n\nNote that the lambda callback provided above is executed in the context of the :code:`TimerWheel` thread. This callback could put messages onto other thread's commands queues, notify a :code:`std::condition_variable`, or lock a :code:`std::mutex` and perform actions on another thread's data.\n\n:code:`TimerWheel` also supports *repetitive timers*.\n\n**Repetitive Timer Example**\n\n.. code:: cpp\n\n    #include \"CppUtils/TimerWheel.hpp\"\n\n    using namespace std::literals;\n    using namespace mn::CppUtils::TimerWheel;\n\n    int main() {\n        TimerWheel timerWheel;\n\n        timerWheel.AddRepetitiveTimer(300ms, 3, [\u0026]() {\n            std::cout \u003c\u003c \"Repeat\" \u003c\u003c std::endl;\n        });\n\n        std::this_thread::sleep_for(1000ms);\n\n        // \"Repeat\" will be printed every 300ms for a total of three times.\n        // Provide -1 instead of 3 to the timer constructor to make the timer run indefinitely.\n    }\n\nVerNumParser.hpp\n================\n\nThis header file provides a class which has utility functions for dealing with string-based version numbers.\n\n.. code:: cpp\n\n    #include \"CppUtils/VerNumParser.hpp\"\n    \n    using namespace mn::CppUtils;\n\n    int main() {\n        \n        // Converts a version string into the individual integer\n        // digits\n        auto digits = VerNumParser::ToInts(\"v2.7.4\");\n\n        std::cout \u003c\u003c digits[0]; // \"2\"\n        std::cout \u003c\u003c digits[1]; // \"7\"\n        std::cout \u003c\u003c digits[2]; // \"4\"\n    }","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbmhunter%2Fcpputils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgbmhunter%2Fcpputils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbmhunter%2Fcpputils/lists"}