{"id":21072171,"url":"https://github.com/theartful/bindable_properties","last_synced_at":"2025-08-14T00:18:30.748Z","repository":{"id":173730693,"uuid":"651207711","full_name":"theartful/bindable_properties","owner":"theartful","description":"Bindable properties for C++11 inspired by Qt's properties but with a couple of twists.","archived":false,"fork":false,"pushed_at":"2023-07-01T19:09:44.000Z","size":18,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-01T17:17:55.448Z","etag":null,"topics":["bindable-properties","cpp","cpp11","observer-pattern"],"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/theartful.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}},"created_at":"2023-06-08T18:38:37.000Z","updated_at":"2023-09-03T17:55:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"9d2df7ba-3bfd-40ef-bdc5-706eb51ef2a9","html_url":"https://github.com/theartful/bindable_properties","commit_stats":null,"previous_names":["theartful/bindable_properties"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/theartful/bindable_properties","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theartful%2Fbindable_properties","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theartful%2Fbindable_properties/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theartful%2Fbindable_properties/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theartful%2Fbindable_properties/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theartful","download_url":"https://codeload.github.com/theartful/bindable_properties/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theartful%2Fbindable_properties/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270338071,"owners_count":24567042,"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-13T02:00:09.904Z","response_time":66,"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":["bindable-properties","cpp","cpp11","observer-pattern"],"created_at":"2024-11-19T18:55:46.658Z","updated_at":"2025-08-14T00:18:30.674Z","avatar_url":"https://github.com/theartful.png","language":"C++","readme":"# Bindable Properties for C++11\n\nThis is a C++ library that provides an implementation of properties that can\nbe bound to each other. It allows for properties to be treated as data members,\nwhile also providing the ability to automatically update other properties when a\nproperty's value is changed.\n\n## Features\n\n- Support simple property views and complex bindings to one or more properties.\n- Automatic updates for bound properties.\n- Define custom notifications for when property changes its value.\n- Views and bound properties can request the original property to change.\n\n## Semantics\n\n### Property Ownership\n\nThere are two ways to create a property: as an owner, or as a view/binding. When\nyou create a property as an owner, the property owns its data, and is responsible\nfor handling change requests. When you create a property as a view or a binding,\nthe property value is a function of one or more other properties, and any changes\nmade to these properties will be reflected in the view.\n\nYou can transfer ownership of a property to another property by using the move\nconstructor or move assignment operator.\n```C++\nproperty\u003cint\u003e x = 5;\nproperty\u003cint\u003e y = x; // now y is a view of x, any changes to x will be reflected in y\n\nproperty\u003cint\u003e z = std::move(x); // x is moved into z, so any changes to z is reflected in y\n```\n\n### Property Binding\n\nThere are two types of property bindings:\n1. Views, or simple bindings. These can be done using the copy constructor.\nThese are lightweight and don't require any allocations.\n```C++\nproperty\u003cint\u003e x;\nproperty\u003cint\u003e y = x;\n\nx = 4;\nassert(y.value() == 4);\n```\n\n2. Complex bindings, where a property is a function of one or more other properties.\nBound properties are automatically updated when any of their dependencies change\nvalue.\n```C++\nproperty\u003cint\u003e x;\nproperty\u003cint\u003e y;\n\nproperty\u003cint\u003e z;\nz.set_binding([=]() { return x.value() + y.value(); });\n\nx = 4;\ny = 5;\n\nassert_eq(z.value() == 9);\n```\n\n\n### Notifications\n\nYou can register a single notification lambda function to be called whenever a\nproperty's value changes. Notifications can only be set on bound properties,\nsince owner properties are the ones making the change.\n```C++\nx.set_notifier([](int new_value) { std::cout \u003c\u003c \"x changed to \" \u003c\u003c new_value; });\n```\n\n\n### Change Requests and Setters\n\nBound properties can request owner properties to change their values. Owner\nproperties respond to this request by calling the registered `setter` lambda,\nor simply accept the change if no lambda is registered.\n```C++\nproperty\u003cint\u003e owner;\nowner.set_setter([\u0026](int value) { owner = value; });\n\nproperty\u003cint\u003e view = owner;\nview.request_change(5);\n\nassert(view.value() == 5);\n```\n\n### Example with Complex Bindings\n\n```C++\nusing namespace bindable_properties;\n\nproperty\u003cint\u003e x = 20;\nproperty\u003cint\u003e y = 21;\nproperty\u003cdouble\u003e hypotenuse; // Represents the hypotenuse of a right triangle\n\n// Binding: hypotenuse = sqrt(x^2 + y^2)\nhypotenuse.set_binding(\n    // binding expression\n    [\u0026] { return std::sqrt(x * x + y * y); },\n    // handles change requests by trying to change y to achieve the requested\n    // hypotenuse\n    [\u0026](double value) {\n        // Setter that calls request_change on the x property\n        y.request_change(std::sqrt(value * value - x * x));\n    },\n    // notification lambda when the value changes\n    [](double value) {\n        std::cout \u003c\u003c \"hypotenuse changed to \" \u003c\u003c value \u003c\u003c '\\n';\n    }\n);\n\nassert(hypotenuse.value() == 29.0);\n\nhypotenuse.request_change(101.0);\nassert(x.value() == 20);\nassert(y.value() == 99);\nassert(hypotenuse.value() == 101.0);\n```\n\n### Gotcha\n\nOn any given instance of a property, you can only call one of `set_setter`,\n`set_notifier`, or `set_binding`. A setter can be only set for the owner, and\n`set_binding` cannot be called on an already bound property (such as views).\nThis is done because the property class only keeps track of one function to\npreserve memory.\n\n## No Allocations\n\nThis library doesn't do any memory allocations as long as you:\n1. Use lambdas with only a single pointer as a state.\n2. Don't use complex bindings and only use property views.\n\n## Use\n\nAdd the following lines to your CMakeLists.txt file:\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n  bindable_properties\n  GIT_REPOSITORY    https://github.com/theartful/bindable_properties\n  GIT_TAG           master\n)\n\nFetchContent_MakeAvailable(bindable_properties)\n\ntarget_link_libraries(target PUBLIC bindable_properties)\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheartful%2Fbindable_properties","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheartful%2Fbindable_properties","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheartful%2Fbindable_properties/lists"}