{"id":16783142,"url":"https://github.com/bengreenier/cppfactory","last_synced_at":"2025-10-28T06:38:31.487Z","repository":{"id":49993735,"uuid":"105477472","full_name":"bengreenier/CppFactory","owner":"bengreenier","description":"Modern c++ object factory implementation in \u003c200 lines","archived":false,"fork":false,"pushed_at":"2021-06-06T17:23:39.000Z","size":164,"stargazers_count":12,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T19:21:39.161Z","etag":null,"topics":["cpp","cpp-11","design-patterns","factory-pattern"],"latest_commit_sha":null,"homepage":"https://bengreenier.github.io/CppFactory","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/bengreenier.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}},"created_at":"2017-10-01T21:58:02.000Z","updated_at":"2022-07-29T08:23:26.000Z","dependencies_parsed_at":"2022-08-19T19:00:33.982Z","dependency_job_id":null,"html_url":"https://github.com/bengreenier/CppFactory","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2FCppFactory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2FCppFactory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2FCppFactory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bengreenier%2FCppFactory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bengreenier","download_url":"https://codeload.github.com/bengreenier/CppFactory/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248306211,"owners_count":21081642,"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":["cpp","cpp-11","design-patterns","factory-pattern"],"created_at":"2024-10-13T07:49:03.590Z","updated_at":"2025-10-28T06:38:26.443Z","avatar_url":"https://github.com/bengreenier.png","language":"C++","readme":"# CppFactory\n\nModern c++ object factory implementation in \u003c200 lines :package: :factory:\n\n![build status](https://b3ngr33ni3r.visualstudio.com/_apis/public/build/definitions/47f8d118-934e-48ed-82d8-52d850a66d71/2/badge)\n\nI needed a simple to use, easy to mock c++ factory library (that could be used for dependecy injection) and a quick search didn't yield what I was looking for. So I built this one. Read the API docs - ([raw](./docs)) - ([hosted](https://bengreenier.github.io/CppFactory)).\n\n## Concepts\n\n\u003e Some terminology you may not be familiar with, but you'll want to know.\n\n### Object Lifecycle\n\nIn CppFactory, objects are all captured in `std::shared_ptr` wrappers, so there is no need to worry about manually deleting objects that you retrieve via the `Object\u003cTObject\u003e::Get()` call. However, you may choose to modify how the runtime handles object allocation to optimize for your use case.\n\nBy default, `Object`s are unmanaged, meaning when the object returned (by `Object\u003cTObject\u003e::Get()`) falls out of scope it is destroyed. This works great for object types that are not re-used (or if you wish to manage lifetime yourself). However, for something with a longer life (perhaps a representation of a database connection) that will be reused in many places, you may use a `GlobalObject`. `GlobalObject`s are powered by `Object`s under the hood, meaning that you can still configure allocators at the `Object` level. All `GlobalObject` provides is a lightweight caching wrapper around the `Object\u003cTObject\u003e::Get()` method. This looks like the following:\n\n```\nGlobalObject\u003cTObject\u003e::Get()\n```\n\nTo clear the `GlobalObject` cache, simply call `GlobalObject\u003cTObject\u003e::Reset()` or (to reset only a single zone, for example `10`) `GlobalObject\u003cTObject\u003e::Reset\u003c10\u003e()`.\n\n### Object Zones\n\nIn CppFactory, objects of the same type are all retrieved from the same factory, so it can become difficult to work with different instances of the same type. To deal with this, CppFactory provides a concept of zones.\n\nZones enable you to draw logical boundries throughout your codebase and to retrieve instances only for that zone. To represent this, you may pass an `int` to `Get()`, `RegisterAllocator()` and `RemoveGlobal()` as a template parameter. The int is how CppFactory represents a zone, and tracks object allocation within that zone. Here's an example:\n\n```\nObject\u003cTObject\u003e::Get\u003c10\u003e()\n```\n\nYou may also use an `enum` (backed by an `int`) to represent zones, which looks like the following:\n\n```\nenum Zones\n{\n    ZoneOne,\n    ZoneTwo\n}\n\nObject\u003cTObject\u003e::Get\u003cZones::ZoneOne\u003e()\n```\n\nNote that you'll likely find this most useful when coupled with `GlobalObject`.\n\n## Usage\n\nUsing constructors and destructors:\n\n```\n#include \u003cCppFactory/CppFactory.hpp\u003e\n\nusing namespace CppFactory;\n\nstruct Data\n{\n    int Value;\n};\n\nint main()\n{\n    // using default allocator (ctor)\n    std::shared_ptr\u003cData\u003e object = Object\u003cData\u003e::Get();\n    object-\u003eValue = 2;\n\n    // a global object using the default allocator (ctor)\n    std::shared_ptr\u003cData\u003e global = GlobalObject\u003cData\u003e::Get();\n\n    return 0;\n}\n```\n\nUsing custom allocators and deallocators:\n\n```\n#include \u003cCppFactory/CppFactory.hpp\u003e\n\nusing namespace CppFactory;\n\nstruct Data\n{\n    int Value;\n};\n\nint main()\n{\n    Object\u003cData\u003e::RegisterAllocator([] {\n        // custom allocator\n        auto ptr = (Data*)malloc(sizeof(Data));\n        ptr-\u003eValue = 0;\n\n        // custom deallocator\n        return std::shared_ptr\u003cData\u003e(ptr, [](Data* data) { free(data); });\n    });\n\n    // use defined allocator\n    std::shared_ptr\u003cData\u003e object = Object\u003cData\u003e::Get();\n    object-\u003eValue = 2;\n\n    // a global object using the allocator\n    std::shared_ptr\u003cData\u003e global = GlobalObject\u003cData\u003e::Get();\n\n    return 0;\n}\n```\n\nUsing factory object pattern (old school):\n\n```\n#include \u003cCppFactory/CppFactory.hpp\u003e\n\nusing namespace CppFactory;\n\nstruct Data\n{\n    int Value;\n};\n\nint main()\n{\n    Factory\u003cData\u003e factory;\n\n    // use defined allocator\n    std::shared_ptr\u003cData\u003e object = factory.Allocate();\n    object-\u003eValue = 2;\n\n    return 0;\n}\n```\n\nUsing factory object pattern (custom factory):\n\n```\n#include \u003cCppFactory/CppFactory.hpp\u003e\n\nusing namespace CppFactory;\n\nstruct DataArgs\n{\n    int Value;\n    int Value2;\n\n    DataArgs(int value, int value2) : Value(value), Value2(value2) {}\n};\n\nint main()\n{\n    Factory\u003cDataArgs, int, int\u003e factory;\n\n    // use defined allocator\n    std::shared_ptr\u003cData\u003e object = factory.Allocate(10, 20);\n    // object-\u003eValue == 10;\n    // object-\u003eValue2 == 20;\n\n    return 0;\n}\n```\n\nSee [the tests](./CppFactory.UnitTests/CppFactoryTests.cpp) for more examples.\n\n## Timing\n\n\u003e Note: Test runs `10000` iterations for each type below. See the code [here](./CppFactory.UnitTests/CppFactoryTests.cpp#L176).\n\n```\nUntracked, normal alloc: 34ms (0.003400ms / iteration)\nGlobal, normal alloc: 36ms (0.003600ms / iteration)\nUntracked, slow alloc: 110694ms (11.069400ms / iteration)\nGlobal, slow alloc: 62ms (0.006200ms / iteration)\n```\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbengreenier%2Fcppfactory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbengreenier%2Fcppfactory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbengreenier%2Fcppfactory/lists"}