{"id":15047732,"url":"https://github.com/microsoft/proxy","last_synced_at":"2025-05-14T04:08:15.154Z","repository":{"id":37854189,"uuid":"497837654","full_name":"microsoft/proxy","owner":"microsoft","description":"Proxy: Next Generation Polymorphism in C++","archived":false,"fork":false,"pushed_at":"2025-05-07T06:29:08.000Z","size":534,"stargazers_count":2619,"open_issues_count":2,"forks_count":182,"subscribers_count":45,"default_branch":"main","last_synced_at":"2025-05-07T23:47:33.760Z","etag":null,"topics":["cpp","cpp20","cross-platform","duck-typing","header-only","library","polymorphism","single-header"],"latest_commit_sha":null,"homepage":"https://microsoft.github.io/proxy/docs/specifications.html","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/microsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-05-30T07:36:39.000Z","updated_at":"2025-05-07T15:15:26.000Z","dependencies_parsed_at":"2023-11-25T15:23:19.361Z","dependency_job_id":"a1458fd4-2664-4931-9667-51067a79eade","html_url":"https://github.com/microsoft/proxy","commit_stats":{"total_commits":114,"total_committers":8,"mean_commits":14.25,"dds":"0.17543859649122806","last_synced_commit":"b61bab444bbf8ebef57f1522fd8414b0e1c1956f"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/microsoft%2Fproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/microsoft","download_url":"https://codeload.github.com/microsoft/proxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254069647,"owners_count":22009558,"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","cpp20","cross-platform","duck-typing","header-only","library","polymorphism","single-header"],"created_at":"2024-09-24T21:03:47.805Z","updated_at":"2025-05-14T04:08:10.130Z","avatar_url":"https://github.com/microsoft.png","language":"C++","readme":"# Proxy: Next Generation Polymorphism in C++\n\n[![Proxy-CI](https://github.com/microsoft/proxy/actions/workflows/pipeline-ci.yml/badge.svg)](https://github.com/microsoft/proxy/actions/workflows/pipeline-ci.yml)\n\nAre you looking to simplify the lifetime management and maintenance of polymorphic objects in C++?\n\nDo you want to write polymorphic code in C++ as easily as in [GC languages](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) like Java or C#, without sacrificing performance?\n\nHave you tried other polymorphic programming libraries in C++ but found them deficient?\n\nIf so, this library is for you.\n\n## Our Mission\n\n\"Proxy\" is a modern C++ library that helps you use polymorphism (a way to use different types of objects interchangeably) without needing inheritance.\n\n\"Proxy\" was created by Microsoft engineers and has been used in the Windows operating system since 2022. For many years, using inheritance was the main way to achieve polymorphism in C++. However, new programming languages like [Rust](https://doc.rust-lang.org/book/ch10-02-traits.html) offer better ways to do this. We have improved our understanding of object-oriented programming and decided to use *pointers* in C++ as the foundation for \"Proxy\". Specifically, the \"Proxy\" library is designed to be:\n\n- **Portable**: \"Proxy\" was implemented as a single-header library in standard C++20. It can be used on any platform while the compiler supports C++20. The majority of the library is [freestanding](https://en.cppreference.com/w/cpp/freestanding), making it feasible for embedded engineering or kernel design of an operating system.\n- **Non-intrusive**: An implementation type is no longer required to inherit from an abstract binding.\n- **Well-managed**: \"Proxy\" provides a GC-like capability that manages the lifetimes of different objects efficiently without the need for an actual garbage collector.\n- **Fast**: With typical compiler optimizations, \"Proxy\" produces high-quality code that is as good as or better than hand-written code. In many cases, \"Proxy\" performs better than traditional inheritance-based approaches, especially in managing the lifetimes of objects.\n- **Accessible**: Learned from user feedback, accessibility has been significantly improved in \"Proxy 3\" with intuitive syntax, good IDE compatibility, and accurate diagnostics.\n- **Flexible**: Not only member functions, the \"abstraction\" of \"Proxy\" allows *any* expression to be polymorphic, including free functions, operators, conversions, etc. Different abstractions can be freely composed on demand. Performance tuning is supported for experts to balance between extensibility and performance.\n\nPlease refer to the [Proxy's Frequently Asked Questions](https://microsoft.github.io/proxy/docs/faq.html) for more background, and refer to the [specifications](https://microsoft.github.io/proxy/docs/specifications.html) for more technical details.\n\n## Quick Start\n\n\"Proxy\" is a header-only C++20 library. To use the library, make sure your compiler meets the [minimum requirements](#compiler-req) and just include the header file [proxy.h](https://github.com/microsoft/proxy/blob/main/proxy.h) in your source code. Alternatively, you can install the library via [vcpkg](https://learn.microsoft.com/en-us/vcpkg/get_started/overview) or [conan](https://conan.io/), by searching for \"proxy\" (see [vcpkg.io](https://vcpkg.io/en/package/proxy) and [conan.io](https://conan.io/center/recipes/proxy)).\n\n### Hello World\n\nLet's get started with the following \"Hello World\" example ([run](https://godbolt.org/z/jr81Poz83)):\n\n```cpp\n#include \u003cformat\u003e\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\n#include \"proxy.h\"\n\nstruct Formattable : pro::facade_builder\n    ::support_format\n    ::build {};\n\nint main() {\n  std::string str = \"Hello World\";\n  pro::proxy\u003cFormattable\u003e p1 = \u0026str;\n  std::cout \u003c\u003c std::format(\"p1 = {}\\n\", *p1);  // Prints \"p1 = Hello World\"\n\n  pro::proxy\u003cFormattable\u003e p2 = std::make_unique\u003cint\u003e(123);\n  std::cout \u003c\u003c std::format(\"p2 = {}\\n\", *p2);  // Prints \"p2 = 123\"\n\n  pro::proxy\u003cFormattable\u003e p3 = pro::make_proxy\u003cFormattable\u003e(3.14159);\n  std::cout \u003c\u003c std::format(\"p3 = {:.2f}\\n\", *p3);  // Prints \"p3 = 3.14\"\n}\n```\n\nHere is a step-by-step explanation:\n\n- `#include \u003cformat\u003e`: For [`std::format`](https://en.cppreference.com/w/cpp/utility/format/format).\n- `#include \u003ciostream\u003e`: For [`std::cout`](https://en.cppreference.com/w/cpp/io/cout).\n- `#include \u003cstring\u003e`: For [`std::string`](https://en.cppreference.com/w/cpp/string/basic_string).\n- `#include \"proxy.h\"`: For the \"Proxy\" library. Most of the facilities of the library are defined in namespace `pro`. If the library is consumed via [vcpkg](https://learn.microsoft.com/en-us/vcpkg/get_started/overview) or [conan](https://conan.io/), this line should be changed into `#include \u003cproxy/proxy.h\u003e`.\n- `struct Formattable : pro::facade_builder ... ::build {}`: Defines a facade type `Formattable`. The term \"facade\", formally defined as the [*ProFacade* requirements](https://microsoft.github.io/proxy/docs/ProFacade.html), is how the \"Proxy\" library models runtime abstraction. Specifically,\n  - [`pro::facade_builder`](https://microsoft.github.io/proxy/docs/basic_facade_builder.html): Provides capability to build a facade type at compile-time.\n  - [`support_format`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_format.html): Specifies the capability of formatting (via [standard formatting functions](https://en.cppreference.com/w/cpp/utility/format)).\n  - [`build`](https://microsoft.github.io/proxy/docs/basic_facade_builder/build.html): Builds the context into a facade type.\n- [`pro::proxy`](https://microsoft.github.io/proxy/docs/proxy.html)`\u003cFormattable\u003e p1 = \u0026str`: Creates a `proxy` object from a raw pointer of `std::string`. `p1` behaves like a raw pointer, and does not have ownership of the underlying `std::string`. If the lifetime of `str` ends before `p1`, `p1` becomes dangling.\n- `std::format(\"p1 = {}\\n\", *p1)`: This is how it works. `*p1` is formatted as \"Hello World\" because the capability was defined in the facade `Formattable`, so it works as if by calling `std::format(\"p1 = {}\\n\", str)`.\n- [`pro::proxy`](https://microsoft.github.io/proxy/docs/proxy.html)`\u003cFormattable\u003e p2 = `[`std::make_unique`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique)`\u003cint\u003e(123)`: Creates a [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr)`\u003cint\u003e` and converts to a `proxy`. Different from `p1`, `p2` has ownership of the underlying `int` because it is instantiated from a value of `std::unique_ptr`, and will call the destructor of `std::unique_ptr` when `p2` is destroyed, while `p1` does not have ownership of the underlying `int` because it is instantiated from a raw pointer. `p1` and `p2` are of the same type `pro::proxy\u003cFormattable\u003e`, which means you can have a function that returns `pro::proxy\u003cFormattable\u003e` without exposing any information about the implementation details to its caller.\n- `std::format(\"p2 = {}\\n\", *p2)`: Formats `*p2` as \"123\" with no surprises.\n- [`pro::proxy`](https://microsoft.github.io/proxy/docs/proxy.html)`\u003cFormattable\u003e p3 = `[`pro::make_proxy`](https://microsoft.github.io/proxy/docs/make_proxy.html)`\u003cFormattable\u003e(3.14159)`: Creates a `proxy` from a `double` without specifying the underlying pointer type. Specifically,\n  - Similar with `p2`, `p3` also has ownership of the underlying `double` value, but can effectively avoid heap allocation.\n  - Since the size of the underlying type (`double`) is known to be small (on major 32- or 64-bit platforms), [`pro::make_proxy`](https://microsoft.github.io/proxy/docs/make_proxy.html) realizes the fact at compile-time, and falls back to [`pro::make_proxy_inplace`](https://microsoft.github.io/proxy/docs/make_proxy_inplace.html), which guarantees no heap allocation.\n  - The \"Proxy\" library explicitly defines when heap allocation occurs or not to avoid users falling into performance hell, which is different from [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function) and other existing polymorphic wrappers in the standard.\n- `std::format(\"p3 = {:.2f}\\n\", *p3)`: Formats `*p3` as \"3.14\" as per the [standard format specification](https://en.cppreference.com/w/cpp/utility/format/spec) with no surprises.\n- When `main` returns, `p2` and `p3` will destroy the underlying objects, while `p1` does nothing because it holds a raw pointer that does not have ownership of the underlying `std::string`.\n\n### Hello World (Stream Version)\n\nIn the previous \"Hello Word\" example, we demonstrated how `proxy` could manage different types of objects and be formatted with `std::format`. While `std::format` is not the only option to print objects in C++, can we simply make `proxy` work with `std::cout`? The answer is \"yes\". The previous example is equivalent to the following implementation ([run](https://godbolt.org/z/q1b14WGff)):\n\n```cpp\n#include \u003ciomanip\u003e\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n\n#include \"proxy.h\"\n\nstruct Streamable : pro::facade_builder\n    ::add_convention\u003cpro::operator_dispatch\u003c\"\u003c\u003c\", true\u003e, std::ostream\u0026(std::ostream\u0026 out) const\u003e\n    ::build {};\n\nint main() {\n  std::string str = \"Hello World\";\n  pro::proxy\u003cStreamable\u003e p1 = \u0026str;\n  std::cout \u003c\u003c \"p1 = \" \u003c\u003c *p1 \u003c\u003c \"\\n\";  // Prints \"p1 = Hello World\"\n\n  pro::proxy\u003cStreamable\u003e p2 = std::make_unique\u003cint\u003e(123);\n  std::cout \u003c\u003c \"p2 = \" \u003c\u003c *p2 \u003c\u003c \"\\n\";  // Prints \"p2 = 123\"\n\n  pro::proxy\u003cStreamable\u003e p3 = pro::make_proxy\u003cStreamable\u003e(3.14159);\n  std::cout \u003c\u003c \"p3 = \" \u003c\u003c std::fixed \u003c\u003c std::setprecision(2) \u003c\u003c *p3 \u003c\u003c \"\\n\";  // Prints \"p3 = 3.14\"\n}\n```\n\nHere is a step-by-step explanation:\n\n- `#include \u003ciostream\u003e`: For [`std::setprecision`](https://en.cppreference.com/w/cpp/io/manip/setprecision).\n- `#include \u003ciostream\u003e`: For [`std::cout`](https://en.cppreference.com/w/cpp/io/cout).\n- `#include \u003cstring\u003e`: For [`std::string`](https://en.cppreference.com/w/cpp/string/basic_string).\n- `#include \"proxy.h\"`: For the \"Proxy\" library.\n- `struct Streamable : pro::facade_builder ... ::build {}`: Defines a facade type `Streamable`. Specifically,\n  - [`pro::facade_builder`](https://microsoft.github.io/proxy/docs/basic_facade_builder.html): Gets prepared to build another facade.\n  - [`add_convention`](https://microsoft.github.io/proxy/docs/basic_facade_builder/add_convention.html): Adds a generalized \"calling convention\", defined by a \"dispatch\" and several \"overloads\", to the build context.\n  - [`pro::operator_dispatch`](https://microsoft.github.io/proxy/docs/operator_dispatch.html)`\u003c\"\u003c\u003c\", true\u003e`: Specifies a dispatch for operator `\u003c\u003c` expressions where the primary operand (`proxy`) is on the right-hand side (specified by the second template parameter `true`). Note that polymorphism in the \"Proxy\" library is defined by expressions rather than member functions, which is different from C++ virtual functions or other OOP languages.\n  - `std::ostream\u0026(std::ostream\u0026 out) const`: The signature of the calling convention, similar with [`std::move_only_function`](https://en.cppreference.com/w/cpp/utility/functional/move_only_function). `const` specifies that the primary operand is `const`.\n  - [`build`](https://microsoft.github.io/proxy/docs/basic_facade_builder/build.html): Builds the context into a facade type.\n\n- [`pro::proxy`](https://microsoft.github.io/proxy/docs/proxy.html)`\u003cStreamable\u003e p1 = \u0026str`: Creates a `proxy` object from a raw pointer of `std::string`.\n- `std::cout \u003c\u003c *p1`: It prints \"Hello World\" because the calling convention is defined in the facade `Streamable`, so it works as if by calling `std::cout \u003c\u003c str`.\n- [`pro::proxy`](https://microsoft.github.io/proxy/docs/proxy.html)`\u003cStreamable\u003e p2 = `[`std::make_unique`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique)`\u003cint\u003e(123)`: Creates a [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr)`\u003cint\u003e` and converts to a `proxy`.\n- `std::cout \u003c\u003c *p2`: Prints \"123\" with no surprises.\n- [`pro::proxy`](https://microsoft.github.io/proxy/docs/proxy.html)`\u003cStreamable\u003e p3 = `[`pro::make_proxy`](https://microsoft.github.io/proxy/docs/make_proxy.html)`\u003cStreamable\u003e(3.14)`: Creates a `proxy` from a `double`.\n- `std::cout \u003c\u003c std::fixed \u003c\u003c std::setprecision(2) \u003c\u003c *p3;`: Prints \"3.14\" with no surprises.\n\n### More Expressions\n\nIn addition to the operator expressions demonstrated in the previous examples, the library supports almost all forms of expressions in C++ and can make them polymorphic. Specifically,\n\n- [macro `PRO_DEF_MEM_DISPATCH`](https://microsoft.github.io/proxy/docs/PRO_DEF_MEM_DISPATCH.html): Defines a dispatch type for member function call expressions, providing accessibility as member functions.\n- [macro `PRO_DEF_FREE_DISPATCH`](https://microsoft.github.io/proxy/docs/PRO_DEF_FREE_DISPATCH.html): Defines a dispatch type for free function call expressions, providing accessibility as free functions.\n- [macro `PRO_DEF_FREE_AS_MEM_DISPATCH`](https://microsoft.github.io/proxy/docs/PRO_DEF_FREE_AS_MEM_DISPATCH.html): Defines a dispatch type for free function call expressions, providing accessibility as member functions.\n- [class template `pro::operator_dispatch`](https://microsoft.github.io/proxy/docs/operator_dispatch.html): Dispatch type for operator expressions.\n- [class `explicit_conversion_dispatch` (aka. `conversion_dispatch`)](https://microsoft.github.io/proxy/docs/explicit_conversion_dispatch.html) and [class `implicit_conversion_dispatch`](https://microsoft.github.io/proxy/docs/implicit_conversion_dispatch.html): Dispatch type for conversion expressions.\n\nNote that some facilities are provided as macro, because C++ templates today do not support generating a function with an arbitrary name. Here is another example that makes member function call expressions polymorphic ([run](https://godbolt.org/z/xcEeYrjnY)):\n\n```cpp\n#include \u003ciostream\u003e\n#include \u003csstream\u003e\n\n#include \"proxy.h\"\n\nPRO_DEF_MEM_DISPATCH(MemDraw, Draw);\nPRO_DEF_MEM_DISPATCH(MemArea, Area);\n\nstruct Drawable : pro::facade_builder\n    ::add_convention\u003cMemDraw, void(std::ostream\u0026 output)\u003e\n    ::add_convention\u003cMemArea, double() noexcept\u003e\n    ::support_copy\u003cpro::constraint_level::nontrivial\u003e\n    ::build {};\n\nclass Rectangle {\n public:\n  Rectangle(double width, double height) : width_(width), height_(height) {}\n  Rectangle(const Rectangle\u0026) = default;\n\n  void Draw(std::ostream\u0026 out) const {\n    out \u003c\u003c \"{Rectangle: width = \" \u003c\u003c width_ \u003c\u003c \", height = \" \u003c\u003c height_ \u003c\u003c \"}\";\n  }\n  double Area() const noexcept { return width_ * height_; }\n\n private:\n  double width_;\n  double height_;\n};\n\nstd::string PrintDrawableToString(pro::proxy\u003cDrawable\u003e p) {\n  std::stringstream result;\n  result \u003c\u003c \"entity = \";\n  p-\u003eDraw(result);\n  result \u003c\u003c \", area = \" \u003c\u003c p-\u003eArea();\n  return std::move(result).str();\n}\n\nint main() {\n  pro::proxy\u003cDrawable\u003e p = pro::make_proxy\u003cDrawable, Rectangle\u003e(3, 5);\n  std::string str = PrintDrawableToString(p);\n  std::cout \u003c\u003c str \u003c\u003c \"\\n\";  // Prints \"entity = {Rectangle: width = 3, height = 5}, area = 15\"\n}\n```\n\nHere is a step-by-step explanation:\n\n- `#include \u003ciostream\u003e`: For [`std::cout`](https://en.cppreference.com/w/cpp/io/cout).\n- `#include \u003csstream\u003e`: For [`std::stringstream`](https://en.cppreference.com/w/cpp/io/basic_stringstream).\n- `#include \"proxy.h\"`: For the \"Proxy\" library.\n- [`PRO_DEF_MEM_DISPATCH`](https://microsoft.github.io/proxy/docs/PRO_DEF_MEM_DISPATCH.html)`(MemDraw, Draw)`: Defines a dispatch type `MemDraw` for expressions of calling member function `Draw`.\n- [`PRO_DEF_MEM_DISPATCH`](https://microsoft.github.io/proxy/docs/PRO_DEF_MEM_DISPATCH.html)`(MemArea, Area)`: Defines a dispatch type `MemArea` for expressions of calling member function `Area`.\n- `struct Drawable : pro::facade_builder ... ::build {}`: Defines a facade type `Drawable`. Specifically,\n  - [`add_convention`](https://microsoft.github.io/proxy/docs/basic_facade_builder/add_convention.html): Adds calling conventions to the build context.\n  - [`support_copy`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_copy.html)`\u003c`[`pro::constraint_level`](https://microsoft.github.io/proxy/docs/constraint_level.html)`::nontrivial\u003e`: Specifies the underlying pointer type shall be copyable, which also makes the resulting `proxy` type copyable.\n- `class Rectangle`: An implementation of `Drawable`.\n- Function `PrintDrawableToString`: Converts a `Drawable` into a `std::string`. Note that this is a function rather than a function template, which means it can generate [ABI](https://en.wikipedia.org/wiki/Application_binary_interface) in a larger build system.\n- `pro::proxy\u003cDrawable\u003e p = pro::make_proxy\u003cDrawable, Rectangle\u003e(3, 5)`: Creates a `proxy\u003cDrawable\u003e` object containing a `Rectangle`.\n- `std::string str = PrintDrawableToString(p)`: Converts `p` into a `std::string`, implicitly creates a copy of `p`.\n- `std::cout \u003c\u003c str`: Prints the string.\n\n### Other Useful Features\n\nThe \"Proxy\" library is a self-contained solution for runtime polymorphism in C++. There are many other capabilities documented in the [specifications](https://microsoft.github.io/proxy/docs/specifications.html). In addition to the features mentioned above, here is a curated list of the most popular features based on user feedback:\n\n- **Overloading**: [`facade_builder::add_convention`](https://microsoft.github.io/proxy/docs/basic_facade_builder/add_convention.html) is more powerful than demonstrated above. It can take any number of overload types (formally, any type meeting the [*ProOverload* requirements](https://microsoft.github.io/proxy/docs/ProOverload.html)) and perform standard overload resolution when invoking a `proxy`.\n- **Facade composition**: [`facade_builder::add_facade`](https://microsoft.github.io/proxy/docs/basic_facade_builder/add_facade.html) allows flexible composition of different abstractions.\n- **Concepts**: To facilitate template programming with \"Proxy\", 3 concepts are exported from a facade type. Namely, [`proxiable`](https://microsoft.github.io/proxy/docs/proxiable.html), [`proxiable_target`](https://microsoft.github.io/proxy/docs/proxiable_target.html) and [`inplace_proxiable_target`](https://microsoft.github.io/proxy/docs/inplace_proxiable_target.html).\n- **Allocator awareness**: [function template `allocate_proxy`](https://microsoft.github.io/proxy/docs/allocate_proxy.html) is able to create a `proxy` from a value with any custom allocator. In C++11, [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function) and [`std::packaged_task`](https://en.cppreference.com/w/cpp/thread/packaged_task) had constructors that accepted custom allocators for performance tuning, but these were [removed in C++17](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0302r1.html) because \"the semantics are unclear, and there are technical issues with storing an allocator in a type-erased context and then recovering that allocator later for any allocations needed during copy assignment\". These issues do not apply to `allocate_proxy`.\n- **Configurable constraints**: [`facade_builder`](https://microsoft.github.io/proxy/docs/basic_facade_builder.html) provides full support for constraints configuration, including memory layout (by [`restrict_layout`](https://microsoft.github.io/proxy/docs/basic_facade_builder/restrict_layout.html)), copyability (by [`support_copy`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_copy.html)), relocatability (by [`support_relocation`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_relocation.html)), and destructibility (by [`support_destruction`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_destruction.html)).\n- **Reflection**: `proxy` supports type-based compile-time reflection for runtime queries. Please refer to [`facade_builder::add_reflection`](https://microsoft.github.io/proxy/docs/basic_facade_builder/add_reflection.html) and [function template `proxy_reflect`](https://microsoft.github.io/proxy/docs/proxy_reflect.html) for more details.\n- **Non-owning proxy**: Although `proxy` can manage the lifetime of an object effectively, similar to a smart pointer, we sometimes want to dereference it before passing to a non-owning context. This has been implemented as an extension since 3.2.0. Please refer to [function template `make_proxy_view`](https://microsoft.github.io/proxy/docs/make_proxy_view.html), [alias template `proxy_view`, class template `observer_facade`](https://microsoft.github.io/proxy/docs/proxy_view.html) and [`facade_builder::support_view`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_view.html) for more details.\n- **RTTI**: [RTTI (run-time type information)](https://en.wikipedia.org/wiki/Run-time_type_information) provides \"weak\" reflection capability in C++ since the last century. Although it is not as powerful as reflection in some other languages (like `Object.GetType()` in C# or `Object.getClass()` in Java), it offers the basic infrastructure for type-safe casting at runtime. Since 3.2, \"RTTI for `proxy`\" has been implemented as an extension and allows users to opt-in for each facade definition. Please refer to [`facade_builder::support_rtti`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_rtti.html) for more details.\n- **Shared and weak ownership**: Although `proxy` can be created from a [`std::shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr), extensions are available to create `proxy` objects with shared and weak ownership in a more efficient way since 3.3.0. Please refer to [function template `make_proxy_shared`](https://microsoft.github.io/proxy/docs/make_proxy_shared.html), [`allocate_proxy_shared`](https://microsoft.github.io/proxy/docs/allocate_proxy_shared.html), [alias template `weak_proxy`, class template `weak_facade`](https://microsoft.github.io/proxy/docs/weak_proxy.html) and [`facade_builder::support_weak`](https://microsoft.github.io/proxy/docs/basic_facade_builder/support_weak.html) for more details.\n- **Weak dispatch**: When an object does not implement a convention, and we do not want it to trigger a hard compile error, it is allowed to specify a [`weak_dispatch`](https://microsoft.github.io/proxy/docs/weak_dispatch.html) that throws when invoked.\n\n## \u003ca name=\"compiler-req\"\u003eMinimum Requirements for Compilers\u003c/a\u003e\n\n| Family     | Minimum version | Required flags |\n| ---------- | --------------- | -------------- |\n| GCC        | 13.1            | -std=c++20     |\n| Clang      | 16.0.0          | -std=c++20     |\n| MSVC       | 19.31           | /std:c++20     |\n| NVIDIA HPC | 24.1            | -std=c++20     |\n\n## Build and Run Tests with CMake\n\n```\ngit clone https://github.com/microsoft/proxy.git\ncd proxy\ncmake -B build\ncmake --build build -j\nctest --test-dir build -j\n```\n\n## Related Resources\n\n- January, 2025: [Published ISO C++ proposal P3086R3: Proxy: A Pointer-Semantics-Based Polymorphism Library](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3086r3.pdf)\n- January, 2025: [Published ISO C++ proposal P3584R0: Enrich Facade Creation Facilities for the Pointer-Semantics-Based Polymorphism Library - Proxy](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3584r0.pdf)\n- November, 2024: [Analyzing the Performance of the “Proxy” Library](https://devblogs.microsoft.com/cppblog/analyzing-the-performance-of-the-proxy-library/)\n- September, 2024: [Published ISO C++ proposal P3401R0: Enrich Creation Functions for the Pointer-Semantics-Based Polymorphism Library - Proxy](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3401r0.pdf)\n- September, 2024: [Announcing the Proxy 3 Library for Dynamic Polymorphism](https://devblogs.microsoft.com/cppblog/announcing-the-proxy-3-library-for-dynamic-polymorphism/)\n- August, 2022: [proxy: Runtime Polymorphism Made Easier Than Ever](https://devblogs.microsoft.com/cppblog/proxy-runtime-polymorphism-made-easier-than-ever/)\n\n## Contributing\n\nThis project welcomes contributions and suggestions.  Most contributions require you to agree to a\nContributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us\nthe rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.\n\nWhen you submit a pull request, a CLA bot will automatically determine whether you need to provide\na CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions\nprovided by the bot. You will only need to do this once across all repos using our CLA.\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\nFor more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or\ncontact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\n\n## Trademarks\n\nThis project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft \ntrademarks or logos is subject to and must follow \n[Microsoft's Trademark \u0026 Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).\nUse of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.\nAny use of third-party trademarks or logos are subject to those third-party's policies.\n","funding_links":[],"categories":["Basic Utility"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicrosoft%2Fproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicrosoft%2Fproxy/lists"}