{"id":19017463,"url":"https://github.com/junkdog/pupene","last_synced_at":"2025-06-24T18:39:09.857Z","repository":{"id":148960318,"uuid":"110811608","full_name":"junkdog/pupene","owner":"junkdog","description":"A non-invasive, multi-format serialization library for C++17.","archived":false,"fork":false,"pushed_at":"2017-11-26T18:39:14.000Z","size":1381,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-16T19:08:25.829Z","etag":null,"topics":["introspection","serialization"],"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/junkdog.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2017-11-15T09:19:33.000Z","updated_at":"2023-08-09T06:02:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"69acdedf-51c3-4dc2-b63d-3c0e3d452509","html_url":"https://github.com/junkdog/pupene","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/junkdog/pupene","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkdog%2Fpupene","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkdog%2Fpupene/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkdog%2Fpupene/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkdog%2Fpupene/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/junkdog","download_url":"https://codeload.github.com/junkdog/pupene/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junkdog%2Fpupene/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261735156,"owners_count":23201966,"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":["introspection","serialization"],"created_at":"2024-11-08T19:47:06.484Z","updated_at":"2025-06-24T18:39:09.828Z","avatar_url":"https://github.com/junkdog.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## pupene\n\nA non-invasive, multi-format serialization library for C++17.\n\n\n### Features or Caveats \n\nThis library was primarily conceived as a foundation for assisting with building \ntooling for gamedev projects. The approach and naming conventions are borrowed\nfrom Daniel Randle's [Pupping - a method for serializing data][article]. \n\n- Works with default constructible types.\n  - `pupene` relies on direct field access to read/write. \n- Concise and simple:\n    - `pup()` - one serializer-agnostic read/write function per type.\n    - `Pupper` - serializer, binary and optional JSON support included. \n    - Serialization format can not be customized, this makes it non-ideal for\n      dealing with third-party formats.\n    - Zero dependencies, unless built with JSON support. \n- Not limited to performing only pure serialization.\n  - Example using [imgui and pupene][pupene_imgui] to auto-generate editor UI:s at runtime. \n\n [pupene_imgui]: https://github.com/junkdog/pupene_imgui\n [article]: https://www.gamedev.net/articles/programming/general-and-gameplay-programming/pupping-a-method-for-serializing-data-r4485/\n\n\n### Getting started\n\nAdd [this conan remote](https://bintray.com/junkdog/conan):\n\n```bash\nconan remote add junkdog https://api.bintray.com/conan/junkdog/conan\n```\n\nIn your project's conanfile.txt/py:\n\n```\n[requires]\npupene/0.2.0@junkdog/stable\n```\n\n\n### Links\n\n- Full API documentation, including this README: https://junkdog.github.io/pupene/index.html\n- Github repository: https://github.com/junkdog/pupene\n- Issues: https://github.com/junkdog/pupene/issues\n\n\n### A brief introduction \n\nAt the core, `pupene` is built around serializers called _puppers_, and `pup`\nfunctions - a combined read/write function per serializable type.\n\nInclude `\u003cpupene/binary.h\u003e` and/or `\u003cpupene/json.h\u003e` (requires `-DPUPENE_BUILD_JSON=true`) to\naccess the appropriate puppers.\n\nRefer to the [API docs](https://junkdog.github.io/pupene) for more detailed\ndocumentation. The [tests][tests] may be of some interest too.\n\nNamespace `pupene` is omitted from example code, in the interest of brevity.\n\n [tests]: https://github.com/junkdog/pupene/tree/master/test\n\n\n#### Pupper\n\n`Pupper` is on the receiving end of `pup`; they only deal directly with values once\n`pup` has flattened the object into a sequence of integer, decimal and string types. \n\nIncluded Puppers, and related convenience functions:\n- JsonReader: `from_json()`\n- JsonWriter: `to_json()`\n- BinaryReader: `from_binary()`\n- BinaryWriter: `to_binary()`\n- DebugPupper: `to_debug()`\n \n\nA `pup` function must exist for each serializable type. \n\n#### pup \n\nAn object is serializable when there's a matching `pup` function; these describe \nthe structure of the type by enumerating its fields. All `pup` functions must\nbe defined in the `pupene::fns` namespace.\n\nA limited number of fundamental types are built-in:\n- Integer and decimal types\n- `std::string`\n- STL containers, such as `std::vector` and `std::map`\n\n`pup()` for a type `FooBar` has the following signature:\n\n```cpp\ntemplate \u003ctypename P\u003e\nvoid pup(Pupper\u003cP\u003e\u0026 p,         // Pupper-agnostic - works with all  \n         FooBar\u0026 value,        // must be reference\n         const Meta\u0026 meta);    // name and Meta::Type\n```\n\n**N.B.** For function resolution to work, `pup` functions must be declared in \na file which does not `#include` any puppers, implicitly or explicitly. \n\n#### Example\n\nYou have some models:\n\n```cpp\nstruct Color {\n    float r, g, b, a;\n};\n\nstruct FontReference {\n    std::string path;             \n    Color inner;\n    Color outer;\n};\n```\n\nTo make the types eligible, each requires its own pup function in the namespace `pupene:fns`.\n\n```cpp\n#include \u003cpupene/pup.h\u003e\n\nnamespace pupene::fns {               // required namespace\n\n    template\u003ctypename P\u003e\n    void pup(Pupper\u003cP\u003e\u0026 p,            // the serializer in use \n             Color\u0026 color,            // always as non-const references \n             const Meta\u0026 meta) {      // metadata for color \n        \n        // idiomatic boilerplate     \n        pup_object(p, color, meta, [\u0026color](auto\u0026\u0026 fpup) {\n            fpup(color.r, \"r\");       // enumerate each field\n            fpup(color.g, \"g\");\n            fpup(color.b, \"b\");\n            fpup(color.a, \"a\");\n        });\n    }\n    \n    template\u003ctypename P\u003e\n    void pup(Pupper\u003cP\u003e\u0026 p,          \n             FontReference\u0026 ref,    \n             const Meta\u0026 meta) {    \n        \n        pup_object(p, ref, meta, [\u0026ref](auto\u0026\u0026 fpup) {\n            fpup(ref.path,  \"path\");  \n            fpup(ref.inner, \"inner\"); // dispatches to pup for Color\n            fpup(ref.outer, \"outer\");\n        });\n    }\n}\n```\n\nOnce the necessary pup:s are implemented, serialization between different\nformat becomes possible e.g.:\n\n```cpp\n// load binary from input stream\nstd::istream\u0026 in = ...;\nColor color = from_binary\u003cColor\u003e(in);\n\n// save to json (assumes built with PUPENE_BUILD_JSON=true)\nstd::string raw_json = to_json(color);\n```\n\n`Color` and `FontReference` can now also be combined with some STL containers: \n\n```cpp\nstd::unordered_map\u003cColor, FontReference\u003e colored_fonts = {\n    {colorA, small}, {colorB, medium}, {colorC, large}\n};\n\n// complex keys - such as Color - are ok\nstd::string raw_json = to_json(colored_fonts);\n\n// (this doesn't require any user-supplied pup:s)\nstd::vector\u003cint\u003e numbers = {0, 1, 6, -2, 4, 5, 7};\nto_binary(numbers, std::cout);\n```\n\n\n### Building\n\nUnless already added, The `conan-community` remote has to be added for\nthe `Boost` test dependency to work:\n\n```bash\nconan remote add conan-community https://api.bintray.com/conan/conan-community/conan \n```\n\n\n#### Using Conan\n\nFirst-time setup:\n\n```bash\nconan install . --build missing --install-folder _builds \n```\n\nBuild project:\n\n```bash\nconan build . --build-folder _builds\n```\n\n#### Using CMake:\n\nOnce conan has built the project for the first time, CMake should work as\nexpected.\n\nBuild project:\n\n```bash\ncmake --build _builds --target install -- -j 8\n```\n\nTests are run with:\n\n```bash\ncmake --build _build  --target test\n```\n... or run the tests with valgrind/memcheck:\n\n```bash\ncmake --build _build --target valgrind\n```\n\n#### CLion/CMake\n\nTo play nice with CLion, manually specify the compiler using *CMake Options* \nunder `Settings \u003e Build, Execution, Deployment \u003e CMake`, e.g.:\n\n```bash\n-DCMAKE_CXX_COMPILER=/usr/bin/clang++-5.0\n```\n\n### Overarching TODO\n- Types currently require a default constructor to be eligble for `pup`.\n- Benchmarking and profiling remain.\n\n### Alternative libraries:\n- [MetaStuff](https://github.com/eliasdaler/MetaStuff): C++14, similar but expanded features compared to `pupene`\n- [cereal](https://github.com/USCiLab/cereal): C++11, only binary serialization(?)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunkdog%2Fpupene","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjunkdog%2Fpupene","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunkdog%2Fpupene/lists"}