{"id":40411118,"url":"https://github.com/vpiotr/xnode","last_synced_at":"2026-01-20T14:08:39.609Z","repository":{"id":139543847,"uuid":"41957774","full_name":"vpiotr/xnode","owner":"vpiotr","description":"C++ variant data type with on-the-fly conversion ","archived":false,"fork":false,"pushed_at":"2025-05-13T21:14:02.000Z","size":181,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-13T21:44:23.589Z","etag":null,"topics":["dynamic-types"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vpiotr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"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":"2015-09-05T10:54:46.000Z","updated_at":"2025-05-13T21:14:05.000Z","dependencies_parsed_at":"2025-05-14T23:00:38.517Z","dependency_job_id":null,"html_url":"https://github.com/vpiotr/xnode","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vpiotr/xnode","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpiotr%2Fxnode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpiotr%2Fxnode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpiotr%2Fxnode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpiotr%2Fxnode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vpiotr","download_url":"https://codeload.github.com/vpiotr/xnode/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vpiotr%2Fxnode/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28604712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T12:01:53.233Z","status":"ssl_error","status_checked_at":"2026-01-20T12:01:46.545Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["dynamic-types"],"created_at":"2026-01-20T14:08:38.822Z","updated_at":"2026-01-20T14:08:39.596Z","avatar_url":"https://github.com/vpiotr.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Introduction\nxnode is a lightweight, header-only C++ library for dynamically typed values with automatic conversion between types.\n\n[![CI Build Status](https://github.com/vpiotr/xnode/actions/workflows/ci.yml/badge.svg)](https://github.com/vpiotr/xnode/actions/workflows/ci.yml)\n\n# License\nBSD\n\n# Project home\nhttps://github.com/vpiotr/xnode\n\n# Purpose\nBringing the power and flexibility of dynamic typing to modern C++, allowing you to write more expressive and adaptable code.\n\n# Key Features\n* **Zero-cost Abstractions**: Header-only with no external dependencies beyond STL\n* **Seamless Type Flexibility**: Change types at runtime with automatic conversion\n* **Modern C++ Design**: Template-based, STL-compatible architecture\n* **Rich Data Structures**: Property lists and vector containers with insertion-order preservation\n* **Extensible Type System**: Easily add support for your custom types\n* **Developer-Friendly API**: Intuitive interface with fluent builder methods\n\n# Why xnode?\n* **Simplify Dynamic Data Handling**\n\n\t\txnode value;        \n\t\tvalue.set_as(5);                 // Store as integer\n\t\tvalue.set_as(false);             // Change to boolean\n\t\tvalue.set_as(\"dynamic typing\");  // Change to string\n\t\t\n\t\t// Type safety when you need it\n\t\tAssert(value.is\u003cstd::string\u003e());\n\n* **Smart Type Conversions** - Automatic, transparent, and safe\n\n\t    xnode value;\n\t    value.set_as(\"123\");  // Store as string\n\t    \n\t    // Automatic conversion when needed\n\t    int num = value.get_as\u003cint\u003e();  // Converts to 123\n\t    \n\t    // Type safety built-in\n\t    Assert(value.is\u003cstd::string\u003e());\n\t    Assert(value.is_convertable_to\u003cint\u003e());\n\t\n* **Flexible Container Types** - Including dynamic arrays with tuple-like functionality\n\n\t    // Modern C++17 version with direct values\n\t    #if __cplusplus \u003e= 201703L\n\t    xarray modern = xarray::of(42, \"Direct values\", 3.14, true);\n\t    Assert(modern[0].get_as\u003cint\u003e() == 42);\n\t    #endif\n\n\t\t// Create a heterogeneous collection (like a tuple)\n\t    xarray values = xarray::of(\n\t        xnode::value_of(42),              // int\n\t        xnode::value_of(\"Hello World\"),   // string\n\t        xnode::value_of(3.14),            // double\n\t        xnode::value_of(true)             // bool\n\t    );\n\t    \n\t    // Access elements type-safely\n\t    int first = values[0].get_as\u003cint\u003e();            // 42\n\t    std::string second = values[1].get_as\u003cstd::string\u003e(); // \"Hello World\"\t    \n\t\n\n* **Elegant Named Parameters** - Cleaner than builder pattern, more flexible than structs\n\n\t\tstd::string printInFont(const xnode \u0026font, const std::string \u0026text) {\n\t\t\tconst xobject \u0026options = font.get_ref\u003cxobject\u003e();\n\t\t\t\n\t\t\t// Default values handled elegantly with get_def\n\t\t\tstd::ostringstream out;\n\t\t\tout \u003c\u003c \"text in font [\";\n\t\t\tout \u003c\u003c \"color:\" \u003c\u003c options.get_def(\"color\", xnode::value_of(0x00ff00)).get_as\u003cint\u003e();\n\t\t\tout \u003c\u003c \", font_name:\" \u003c\u003c options.get_def(\"font_name\", xnode::value_of(\"courier\")).get_as\u003cstd::string\u003e();\n\t\t\tout \u003c\u003c \", size:\" \u003c\u003c options.get_def(\"size\", xnode::value_of(10)).get_as\u003cint\u003e();\n\t\t\tout \u003c\u003c \", bold:\" \u003c\u003c options.get_def(\"bold\", xnode::value_of(false)).get_as\u003cbool\u003e();\n\t\t\tout \u003c\u003c \"] = \" \u003c\u003c text;\n\t\t\t\n\t\t\treturn out.str();  \n\t\t}\n\t\t\n\t\t// Create options with fluent static 'of' method:\n\t\tauto result = printInFont(\n\t\t\txnode::value_of(xobject::of(\n\t\t\t\t\"color\", xnode::value_of(0xff0000),\n\t\t\t\t\"font_name\", xnode::value_of(std::string(\"arial\")),\n\t\t\t\t\"size\", xnode::value_of(12),\n\t\t\t\t\"bold\", xnode::value_of(true)\n\t\t\t)), \n\t\t\t\"Hello World!\"\n\t\t);\n\n* **Smart Object Ownership** - Automatic memory management for dynamic objects\n\n\t\t// Let xnode handle object lifecycle\n\t\tvoid useObjectOwnership() {\n\t\t\tstruct CustomObject {\n\t\t\t\tint data1;\n\t\t\t\tint data2;\n\t\t\t};\n\t\t\n\t\t\t// Create an object to be owned by xnode\n\t\t\tstd::unique_ptr\u003cCustomObject\u003e obj(new CustomObject{42, 100});\n\t\t\n\t\t\t// Transfer ownership to xnode\n\t\t\txnode container;\n\t\t\tcontainer.hold(obj.release());\n\t\t\n\t\t\t// Use the object safely\n\t\t\tCustomObject* ptr = container.get_ptr\u003cCustomObject\u003e();\n\t\t\tstd::cout \u003c\u003c \"Values: \" \u003c\u003c ptr-\u003edata1 \u003c\u003c \", \" \u003c\u003c ptr-\u003edata2 \u003c\u003c std::endl;\n\t\t\t\n\t\t\t// Object is automatically deleted when container goes out of scope\n\t\t}\n\n* **Flexible Memory Models** - Store owned objects or reference existing memory\n\n\t\t// Work with existing memory without ownership concerns\n\t\tvoid workWithExistingData() {\n\t\t\t// External data we want to reference\n\t\t\tchar existingData[] = \"Hello xnode!\";\n\t\t\t\n\t\t\t// Store a pointer without taking ownership\n\t\t\txnode reference;\n\t\t\treference.set_as(existingData);\n\t\t\t\n\t\t\t// Use the data through xnode\n\t\t\tchar* data = reference.get_as\u003cchar*\u003e();\n\t\t\tstd::cout \u003c\u003c data \u003c\u003c std::endl; // Prints \"Hello xnode!\"\n\t\t\t\n\t\t\t// xnode won't attempt to free this memory\n\t\t}\n\n\n# Type Conversion System\n\nxnode comes with a rich set of built-in conversions for seamless interoperability:\n\n* **Fundamental Types**: All C++ numeric types (integer and floating-point)\n* **Logical Values**: bool with smart conversion from/to other types\n* **Text Support**: Full std::string integration\n* **Custom Types**: Easily extend with your own conversion rules\n\nCreate your own conversion paths by implementing a simple policy class (see `xnode_long_double.h` for a practical example).\n\t\t\n# Compatibility\n\n* **Standards**: C++11 and later\n* **Platforms**: Cross-platform (Windows, Linux, macOS)\n* **Compilers**: \n  * Modern GCC/Clang toolchains\n  * Microsoft Visual Studio 2015+\n  * Any compiler with good C++11 support\n\n# Advantages Over Alternatives\n\n* **Lighter than Boost**: Self-contained with no external dependencies\n* **More Dynamic than std::any**: Built-in type conversion\n* **More Flexible than std::variant**: Change types at runtime\n* **More Modern than void\\***: Type-safe with no casting required\n\n# Building\nxnode is a header-only library, so you can just include the headers in your project.\n\n## Using CMake (Recommended)\nxnode uses modern CMake for its build system. To build and install:\n\n```bash\n# Create build directory\nmkdir build\ncd build\n\n# Configure (customize your options as needed)\ncmake ..\n\n# Build the tests\ncmake --build .\n\n# Run the tests\nctest\n\n# Install the library (may require elevated privileges)\ncmake --install .\n```\n\n### CMake Options\n- `XNODE_BUILD_TESTS` - Build tests (ON by default)\n\n## Using the library in your CMake project\nAfter installing, you can use the library in your own CMake project:\n\n```cmake\nfind_package(xnode REQUIRED)\ntarget_link_libraries(your_target PRIVATE xnode::xnode)\n```\n\n## Manual Integration\nFor simple projects, you can just copy the headers from the `include` directory into your project.\n\n# Contact information\n* [LinkedIn](http://pl.linkedin.com/pub/piotr-likus/2/307/7b9/)\n\n# Documentation\nTo build documentation, use Code::Blocks 13 and command:\n\n    DoxyBlocks \\ Extract documentation\n\nOutput will be generated into: \"./help/html/\" directory in html format.\n\n# Release History\nSee the [CHANGELOG](doc/CHANGELOG).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvpiotr%2Fxnode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvpiotr%2Fxnode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvpiotr%2Fxnode/lists"}