{"id":19521843,"url":"https://github.com/inochi2d/numem","last_synced_at":"2026-01-28T19:13:03.394Z","repository":{"id":212833252,"uuid":"719344381","full_name":"Inochi2D/numem","owner":"Inochi2D","description":"No-GC memory managment utilities for DLang","archived":false,"fork":false,"pushed_at":"2025-07-15T12:40:30.000Z","size":640,"stargazers_count":31,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-16T04:24:09.006Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"D","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Inochi2D.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2023-11-16T01:02:56.000Z","updated_at":"2025-07-15T12:38:50.000Z","dependencies_parsed_at":"2024-02-17T11:29:16.425Z","dependency_job_id":"b1a7daab-f87d-464f-b3af-e725ca2a0d3e","html_url":"https://github.com/Inochi2D/numem","commit_stats":null,"previous_names":["inochi2d/numem"],"tags_count":66,"template":false,"template_full_name":null,"purl":"pkg:github/Inochi2D/numem","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inochi2D%2Fnumem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inochi2D%2Fnumem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inochi2D%2Fnumem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inochi2D%2Fnumem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Inochi2D","download_url":"https://codeload.github.com/Inochi2D/numem/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Inochi2D%2Fnumem/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265637448,"owners_count":23802714,"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":[],"created_at":"2024-11-11T00:35:23.801Z","updated_at":"2026-01-28T19:13:03.387Z","avatar_url":"https://github.com/Inochi2D.png","language":"D","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"numem.png\" alt=\"NuMem\" style=\"width: 50%; max-width: 512px; height: auto;\"\u003e\n\u003c/p\u003e\n\n[![Unit Test Status](https://github.com/Inochi2D/numem/actions/workflows/pushes.yml/badge.svg)](https://github.com/Inochi2D/numem/actions/workflows/pushes.yml)\n\nNu:Mem is a package for D which implements various nogc memory managment tools, allowing classes, strings, and more to be handled safely in nogc mode.\nThis library is still a work in progress, but is intended to be used within Inochi2D's nogc rewrite to allow the library to have good ergonomics, \nwhile allowing more seamless integration with other programming languages.\n\n\u0026nbsp;\n\u0026nbsp;\n\u0026nbsp;\n\n\u0026nbsp;\n\u0026nbsp;\n\u0026nbsp;\n\n# Using numem\nNumem allows you to instantiate classes without the GC, it's highly recommended that you mark all functions in classes as `@nogc` to avoid GC conflicts.  \n\nUsing `nogc_new` you can instantiate types on the heap, and `nogc_delete` can destruct and free types.\n\n### Note\n\nAs of numem 1.3.0, a D Compiler with frontend version 2.106 or newer is required.  \nFor macOS builds, LDC 1.41.0 or newer is required.\n\n## Hooksets\n\nNumem works on a concept of hooksets, all core functionality of numem is built on a small series of internal hook functions.  \nBy default, numem provides an internal hookset that uses the system's C library and compiler intrinsics to provide the given\nfunctionality. If you have special requirements you can implement your own, overwriting the function calls as needed.\n\nThe following hooksets are provided as subpackages that you can include.\n\n| Name           |                                                                                 Comments |\n| :------------- | ---------------------------------------------------------------------------------------: |\n| `hookset-libc` |                                                                Deprecated, does nothing. |\n| `hookset-dgc`  |           Forwards all allocation and deallocation to the D Runtime's garbage collector. |\n| `hookset-wasm` | Implements a very simple allocator called \"walloc\", not recommended for production, yet. |\n\n## Using Classes\n\n```d\nimport numem;\n\nclass MyClass {\n@nogc:\n    void doSomething() {\n        import core.stdc.stdio : printf;\n        printf(\"Hello, world!\\n\");\n    }\n}\n\nvoid main() {\n    MyClass klass = nogc_new!MyClass();\n    klass.doSomething();\n\n    nogc_delete(klass);\n}\n```\n\nAll features of classes are available without the GC, such as subclassing and interfaces.\n\nIt is recommended that nogc classes extend `NuObject`.\n```d\nimport numem;\n\nclass MyClass : NuObject {\n@nogc:\n    // NuObject ensures all the derived functions\n    // are nogc; as such you can easily override functions\n    // like opEquals.\n}\n```\n\n## Reference Counted Classes\n\nNumem features an extra base class, derived from `NuObject`, called `NuRefCounted`.\nThis class implements manual reference counting using the `retain` and `release` functions.\n\n```d\nimport numem;\nimport std.stdio;\n\nclass MyRCClass : NuRefCounted {\n@nogc:\nprivate:\n    int secret;\n\npublic:\n    ~this() {\n        import core.stdc.stdio : printf;\n        printf(\"Deleted!\\n\");\n    }\n\n    int getSecret() {\n        return secret;\n    }\n}\n\nvoid main() {\n    MyRCClass rcclass = nogc_new!MyRCClass();\n\n    // Add one refcount.\n    rcclass.retain();\n    writeln(rcclass.retain().getSecret());\n\n    // Repeatedly release a refcount until rcclass is freed.\n    while(rcclass)\n        rcclass = rcclass.release();\n\n    assert(rcclass is null);\n}\n```\n\n## Using slices\n\nNumem allows creating slice buffers, however these buffers are less safe than higher level\nalternatives available in [nulib](https://github.com/Inochi2D/nulib).\n\n```d\n// Allocate a new float slice, then set all values to 0.\nfloat[] myFloatSlice = nu_malloca!float(42);\nmyFloatSlice[0..$] = 0.0;\n\n// Resize slice, and add -1 to the end of it.\nmyFloatSlice = myFloatSlice.nu_resize(43);\nmyFloatSlice[$-1] = -1; \n\n// Slices must be freed by you, you can either resize the slice to a length\n// of 0, or use nu_freea\nnu_freea(myFloatSlice);\n\n// Is equivalent to nu_freea(myFloatSlice);\nmyFloatSlice = myFloatSlice.nu_resize(0);\n```\n\nThese slice handling functions are marked `@system` due to their memory unsafe nature.  \nAs such you may not use them in `@safe` code.\n\n## Option types\n\nNumem features optional and result types for more safely handling application state.\n\n`Option!T` wraps a value that either exists or does not exist.\n```d\n/// Somewhere else\nOption!MyClass getGlobalInstance() {\n    return __globalClassInstance ? none!MyClass() : some(__globalClassInstance);\n}\n\n/// In your code\nif (auto instance = getGlobalInstance()) {\n    // Instance is valid\n    instance.get().doSomething();\n}\n```\n\n`Result!T` wraps a value and error state together.\n```d\n/// In some class\nstatic Result!File open(string file) @nogc nothrow {\n    if (!exists(file))\n        return error!File(\"File does not exist!\");\n    \n    return ok!File(nogc_new!File(file));\n}\n\n/// In your code\nauto file = File.open(\"myfile.txt\");\nif (!file) {\n\n    // file is closed, crash with fatal error.\n    nu_fatal(file.error);\n}\n\n// File is open, unwrap it\nFile unwrapped = file.get();\n```\n\nThese 2 constructs are marked as `@trusted @nogc nothrow`, allowing you to use them within code that should not throw exceptions. `get` will fatally crash if the state of the container is invalid, so make sure to check the validity before calling `get`.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finochi2d%2Fnumem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finochi2d%2Fnumem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finochi2d%2Fnumem/lists"}