{"id":23681410,"url":"https://github.com/codecat/scratch2","last_synced_at":"2025-08-01T09:03:39.992Z","repository":{"id":44406606,"uuid":"89406426","full_name":"codecat/scratch2","owner":"codecat","description":"Single-header base C++ classes.","archived":false,"fork":false,"pushed_at":"2025-07-06T11:22:00.000Z","size":181,"stargazers_count":29,"open_issues_count":2,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-06T12:29:20.446Z","etag":null,"topics":["c-plus-plus","classes","header-only","single-header"],"latest_commit_sha":null,"homepage":"","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/codecat.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,"zenodo":null}},"created_at":"2017-04-25T21:01:15.000Z","updated_at":"2025-07-06T11:22:03.000Z","dependencies_parsed_at":"2025-04-20T14:29:21.816Z","dependency_job_id":"cb1f84a5-b51a-43bc-b0af-1b29c5cd1db4","html_url":"https://github.com/codecat/scratch2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/codecat/scratch2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecat%2Fscratch2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecat%2Fscratch2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecat%2Fscratch2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecat%2Fscratch2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codecat","download_url":"https://codeload.github.com/codecat/scratch2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codecat%2Fscratch2/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268197194,"owners_count":24211649,"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","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["c-plus-plus","classes","header-only","single-header"],"created_at":"2024-12-29T18:38:08.847Z","updated_at":"2025-08-01T09:03:39.915Z","avatar_url":"https://github.com/codecat.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# s2\r\n\r\nScratch2 is a collection of minimal single-header libraries that implement base functionality. All header files can be included individually, the headers do not depend on each other.\r\n\r\n* Absolute core:\r\n  * [`s2string.h`](#s2stringh)\r\n  * [`s2list.h`](#s2listh)\r\n  * [`s2dict.h`](#s2dicth)\r\n  * [`s2ref.h`](#s2refh)\r\n  * [`s2func.h`](#s2func)\r\n* System utility:\r\n  * [`s2file.h`](#s2fileh)\r\n  * [`s2fiber.h`](#s2fiberh)\r\n* Miscellaneous:\r\n  * [`s2test.h`](#s2testh)\r\n\r\nTo use any of these, you need to define `S2_IMPL` in *one* implementation file and include the files you need there. Note that this does not apply to some files where there is a generic implementation and therefore must be used purely as a header, for example `s2list.h`.\r\n\r\n## `s2string.h`\r\n\r\nProvides the class `s2::string` to use as a normal string container. The most basic example would be:\r\n\r\n```c++\r\n#include \u003ccstdio\u003e\r\n#include \u003cs2string.h\u003e\r\n\r\nint main()\r\n{\r\n\ts2::string test;\r\n\ttest = \"Hello, \";\r\n\ttest += \"world.\";\r\n\tprintf(\"%s\\n\", test.c_str());\r\n\r\n\treturn 0;\r\n}\r\n```\r\n\r\n## `s2list.h`\r\n\r\nProvides the class `s2::list\u003cT\u003e` to use as a container of multiple elements. The most basic example would be:\r\n\r\n```c++\r\n#include \u003ccstdio\u003e\r\n#include \u003cs2list.h\u003e\r\n\r\nint main()\r\n{\r\n\ts2::list\u003cint\u003e test;\r\n\ttest.add(1);\r\n\ttest.add(2);\r\n\ttest.add(3);\r\n\r\n\tfor (int num : test) {\r\n\t\tprintf(\"%d\\n\", num);\r\n\t}\r\n\r\n\treturn 0;\r\n}\r\n```\r\n\r\nWhen using non-pointer type classes for `T`, be advised that when calling `add(const T \u0026)`, you are invoking the copy constructor. To avoid calling the copy constructor needlessly, you can also call `add()` without a parameter, which will add a new element using the default (empty) constructor, and return the instance.\r\n\r\nWhen such items are removed from the list, the destructor will be called. Indeed, `s2::list` manages its own available memory for each element. This means that it's illegal to get a reference to an element and then proceed to remove it from the list.\r\n\r\n## `s2dict.h`\r\n\r\nProvides the class `s2::dict\u003cTKey, TValue\u003e` to use as a container of key/value pairs. The most basic example would be:\r\n\r\n```c++\r\n#include \u003ccstdio\u003e\r\n#include \u003cs2dict.h\u003e\r\n\r\nint main()\r\n{\r\n\ts2::dict\u003cint, int\u003e test;\r\n\ttest[10] = 100;\r\n\ttest[20] = 200;\r\n\ttest[30] = 300;\r\n\tprintf(\"%d, %d, %d\\n\", test[10], test[20], test[30]);\r\n\r\n\treturn 0;\r\n}\r\n```\r\n\r\nRead the note above about non-pointer type classes for `s2list.h`, as this also applies to this class. The only difference here is that it is applied to both the key and the value.\r\n\r\n## `s2ref.h`\r\n\r\nProvides the class `s2::ref\u003cT\u003e` to use as a reference counted pointer. The most basic example would be:\r\n\r\n```c++\r\n#include \u003ccstdio\u003e\r\n#include \u003cs2ref.h\u003e\r\n\r\nstruct Foo {};\r\n\r\nint main()\r\n{\r\n\ts2::ref\u003cFoo\u003e test;\r\n\t{\r\n\t\ts2::ref\u003cFoo\u003e test2 = new Foo;\r\n\t\ttest = test2;\r\n\t}\r\n\tprintf(\"%d @ %p\\n\", test.count(), test.ptr());\r\n\r\n\treturn 0;\r\n}\r\n```\r\n\r\n## `s2func.h`\r\n\r\nProvides a container for executable functions. The most basic example would be:\r\n\r\n```c++\r\n#include \u003ccstdio\u003e\r\n#include \u003cs2func.h\u003e\r\n\r\nint main()\r\n{\r\n\tint num = 0;\r\n\ts2::func\u003cvoid()\u003e func = [\u0026num]() {\r\n\t\tnum += 10;\r\n\t};\r\n\r\n\tfor (int i = 0; i \u003c 10; i++) {\r\n\t\tfunc();\r\n\t}\r\n\r\n\tprintf(\"num = %d\\n\", num);\r\n\treturn 0;\r\n}\r\n```\r\n\r\n## `s2file.h`\r\n\r\nProvides the class `s2::file` to use for primitive reading and writing to files on disk. The most basic example would be:\r\n\r\n```c++\r\n#include \u003cs2file.h\u003e\r\n\r\nint main()\r\n{\r\n\tint number = 10;\r\n\r\n\ts2::file test(\"test.bin\");\r\n\ttest.open(s2::filemode::write);\r\n\ttest.write(\u0026number, sizeof(number));\r\n\ttest.close();\r\n\r\n\treturn 0;\r\n}\r\n```\r\n\r\nAlso included are the following functions:\r\n\r\n```c++\r\nbool s2::file_exists(const char* filename);\r\nsize_t s2::file_size(const char* filename);\r\n```\r\n\r\n## `s2fiber.h`\r\n\r\nProvides the class `s2::fiber` to use for fiber scheduling. The most basic example would be:\r\n\r\n```c++\r\n#include \u003ccstdio\u003e\r\n#include \u003cs2fiber.h\u003e\r\n\r\nstatic void fiber_func(s2::fiber \u0026fib)\r\n{\r\n\tfor (int i = 0; i \u003c 10; i++) {\r\n\t\tprintf(\"Fiber tick %d\\n\", i);\r\n\t\tfib.yield();\r\n\t}\r\n\tprintf(\"Finished!\\n\");\r\n}\r\n\r\nint main()\r\n{\r\n\ts2::fiber fib(fiber_func);\r\n\r\n\twhile (!fib.isfinished()) {\r\n\t\tprintf(\"Not finished yet..\\n\");\r\n\t\tfib.resume();\r\n\t}\r\n\r\n\treturn 0;\r\n}\r\n```\r\n\r\nNote that on Mac OS, you are currently required to build with `-D_XOPEN_SOURCE`.\r\n\r\n## `s2test.h`\r\n\r\nProvides functions for unit testing. The most basic example would be:\r\n\r\n```c++\r\n#include \u003cs2test.h\u003e\r\n\r\nint main()\r\n{\r\n\ts2::test_begin();\r\n\r\n\tS2_TEST(true == true);\r\n\tS2_TEST(false == false);\r\n\r\n\ts2::test_end();\r\n\r\n\treturn s2::test_retval();\r\n}\r\n```\r\n\r\nTests can also be grouped by simply calling `s2::test_group(const char* group)` before each group of `S2_TEST()` macros.\r\n\r\n# Todo\r\n\r\n* Ability to replace standard lib functions such as `malloc`, `printf`, and `fopen` with custom functions\r\n* Consider string using stack memory for short strings\r\n\r\n# License\r\n\r\nScratch2 is MIT licensed.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodecat%2Fscratch2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodecat%2Fscratch2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodecat%2Fscratch2/lists"}