{"id":20030827,"url":"https://github.com/igozdev/public_cast","last_synced_at":"2025-03-02T05:20:59.688Z","repository":{"id":210580368,"uuid":"726914839","full_name":"igozdev/public_cast","owner":"igozdev","description":null,"archived":false,"fork":false,"pushed_at":"2023-12-03T20:22:43.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-12T17:47:23.077Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/igozdev.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}},"created_at":"2023-12-03T19:12:50.000Z","updated_at":"2023-12-03T19:34:35.000Z","dependencies_parsed_at":"2023-12-03T20:38:39.328Z","dependency_job_id":null,"html_url":"https://github.com/igozdev/public_cast","commit_stats":null,"previous_names":["igozdev/public_cast"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igozdev%2Fpublic_cast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igozdev%2Fpublic_cast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igozdev%2Fpublic_cast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/igozdev%2Fpublic_cast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/igozdev","download_url":"https://codeload.github.com/igozdev/public_cast/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241461903,"owners_count":19966773,"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-13T09:28:35.369Z","updated_at":"2025-03-02T05:20:59.669Z","avatar_url":"https://github.com/igozdev.png","language":"C++","readme":"# public_cast\n\u003e Compile time string literal encryptor for C++.\n\n[![license][badge.license]][license]\n[![release][badge.release]][release]\n[![godbolt][badge.godbolt]][godbolt]\n\n[badge.license]: https://img.shields.io/badge/license-mit-green.svg\n[license]: https://github.com/igozdev/public_cast/blob/main/LICENSE\n[badge.release]: https://img.shields.io/github/release/igozdev/public_cast.svg\n[release]: https://github.com/igozdev/public_cast/releases/latest\n[badge.godbolt]: https://img.shields.io/badge/try_it-on_godbolt-indigo.svg\n[godbolt]: https://godbolt.org/z/PKnK86Pj7\n\n* [Usage](#usage)\n* [Example](#example)\n\n# Usage\n## pc::accessor\n`pc::accessor` allows for a private member to be accessed via template instantiation, taking the template parameters `\u003cTagType, Member\u003e`.\n#### Example, creating an accessor for class `foo`'s private member `bar` with a new tag named `my_tag`:\n```c++\ntemplate struct pc::accessor\u003cclass my_tag, \u0026foo::bar\u003e;\n```\n\u003e [!WARNING]\n\u003e A unique tag should be used for each template instantiation so that in the case of creating accessors for multiple class members of the same type, values are not overwritten.\n\n## pc::public_cast\n`pc::public_cast` takes the template parameters `\u003cTagType, MemberType, ObjectType (deduced)\u003e` and 1 argument, the object from which the member is accessed. It returns a reference to the member if it is a member object, or a callable object which calls and returns the result of the member function if it is a member function.\n#### Example, accessing object `f` of type `foo`'s private `double` member object `bar` instantiated with tag `foo(bar)`, and private `char(int, float)` member function `baz` instantiated with tag `foo(baz)`:\n```c++\nint x = pc::public_cast\u003cfoo(bar), double\u003e(f);\nchar y = pc::public_cast\u003cfoo(baz), char(int, float)\u003e(f)(10, 5.3f); \n```\n\u003e [!IMPORTANT]\n\u003e An appropriate template instantiation of `pc::accessor` must be created for each private member that may be accessed by `pc::public_cast` or any other `pc` function.\n\n## pc::publicize \u0026 pc::publicize_static\n`pc::publicize` takes the template parameters `\u003cTagType, MemberType, ObjectType\u003e` and returns the member pointer of that private member.\u003cbr\u003e\n`pc::publicize_static` takes the template parameters `\u003cTagType, MemberType, ObjectType\u003e` and returns the pointer to that private static member.\n#### Example, accessing the member pointer to `foo`'s private `std::string` member `bar` instantiated with tag `foo(bar)`, and the pointer to `foo`'s private static `float` member `baz` instantiated with tag `foo(baz)`:\n```c++\nstd::string foo::* x = pc::publicize\u003cfoo(bar), std::string, foo\u003e();\nfloat* y = pc::publicize_static\u003cfoo(baz), float, foo\u003e();\n```\n## pc::modified \u0026 pc::modifier\nCertain member functions may have cv or reference qualifiers, and thus their type cannot be described by the general `ReturnType(ArgTypes...)` format. In this case, `pc::modified` is used. `pc::modified` is a type taking the template parameters `\u003cFunctionType, Modifiers\u003e` where `Modifiers` is a value of type `pc::modifier`, and may be used as the member type in `pc::public_cast` or `pc::publicize`.\u003cbr\u003e\n`pc::modifier` defines the following flags: `pc::modifier::const_`, `pc::modifier::volatile_`, `pc::modifier::lvalue`, and `pc::modifier::rvalue`, of which multiple may be combined using the `|` operator.\n#### Example, calling object `f` of type `foo`'s private member function `void bar(int) const \u0026\u0026` instantiated with tag `foo(bar)`:\n```c++\npc::public_cast\u003cfoo(bar), pc::modified\u003cvoid(int), pc::modifier::const_ | pc::modifier::rvalue\u003e\u003e(f)(5);`\n```\n\n# Example\n```c++\n#include \u003cpublic_cast.hpp\u003e\n#include \u003ciostream\u003e\n\nclass foo // example class\n{\nprivate:\n    int x = 99;\n    inline static int s = 10;\n\n    float bar(int v)\n    {\n        std::cout \u003c\u003c \"bar called with \" \u003c\u003c v \u003c\u003c std::endl;\n        return static_cast\u003cfloat\u003e(v) / 2.f;\n    }\n    static void baz(float v)\n    {\n        std::cout \u003c\u003c \"baz called with \" \u003c\u003c v \u003c\u003c std::endl;\n    }\n\n    std::string special() const \u0026\n    {\n        return std::string(\"special!\");\n    }\n};\n\nnamespace tag // instantiate pc::accessor template for private members\n{\n    template struct pc::accessor\u003cfoo(class x), \u0026foo::x\u003e;\n    template struct pc::accessor\u003cfoo(class s), \u0026foo::s\u003e;\n    template struct pc::accessor\u003cfoo(class bar), \u0026foo::bar\u003e;\n    template struct pc::accessor\u003cfoo(class baz), \u0026foo::baz\u003e;\n    template struct pc::accessor\u003cfoo(class special), \u0026foo::special\u003e;\n}\n\nint main()\n{\n    foo f;\n\n    std::cout \u003c\u003c pc::public_cast\u003cfoo(tag::x), int\u003e(f) \u003c\u003c std::endl; // print `f.x`\n    pc::public_cast\u003cfoo(tag::x), int\u003e(f) += 5; // add 5 to `f.x`\n    std::cout \u003c\u003c pc::public_cast\u003cfoo(tag::x), int\u003e(f) \u003c\u003c std::endl; // print `f.x` again\n\n    float result = pc::public_cast\u003cfoo(tag::bar), float(int)\u003e(f)(55); // call `f.bar(55)` and store result\n    std::cout \u003c\u003c result \u003c\u003c std::endl;\n\n    std::string s = pc::public_cast\u003cfoo(tag::special), pc::modified\u003cstd::string(void), pc::modifier::const_ | pc::modifier::lvalue\u003e\u003e(f)(); // call `f.special()` and store result\n    std::cout \u003c\u003c s \u003c\u003c std::endl;\n\n    std::cout \u003c\u003c pc::public_cast\u003cfoo(tag::s), int, foo\u003e() \u003c\u003c std::endl; // print `foo::s`\n    pc::public_cast\u003cfoo(tag::baz), void(float), foo\u003e()(3.14f); // call `foo::baz(3.14f)`\n\n    foo new_f;\n    auto f_x_ptr = pc::publicize\u003cfoo(tag::x), int, foo\u003e();\n    std::cout \u003c\u003c new_f.*f_x_ptr \u003c\u003c std::endl; // print `new_f.x` using member pointer\n\n    std::cout \u003c\u003c *pc::publicize_static\u003cfoo(tag::s), int, foo\u003e() \u003c\u003c std::endl; // print `foo::s` using pointer\n}\n\n////////////////// Possible output: //////////////////\n// 99\n// 104\n// bar called with 55\n// 27.5\n// special!\n// 10\n// baz called with 3.14\n// 99\n// 10\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figozdev%2Fpublic_cast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figozdev%2Fpublic_cast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figozdev%2Fpublic_cast/lists"}