diff --git a/README.md b/README.md index bb9c68b..bbe1057 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Standard](https://img.shields.io/badge/C%2B%2B-20%2B-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B20) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) -An experimental C++ library and generation tool for enabling static structural +An experimental C++ library and code generation tool for static structural subtyping (duck typing) with value semantics. ## Overview @@ -15,26 +15,26 @@ components, makes it impossible to retroactively apply interfaces to third-party types, and typically forces reference semantics (e.g., `std::unique_ptr`). Inspired by Python's `Protocol` (PEP 544), this repository explores bringing a -similar paradigm to C++. By utilizing AST parsing (via Clang) and code -generation, we can automatically synthesize type-erased wrappers that accept any -type structurally conforming to an interface. +similar paradigm to C++. By using AST parsing (via Clang) and code generation, +the tool synthesizes type-erased wrappers that accept any type structurally +conforming to an interface, without inheritance. -Crucially, these protocols maintain deep-copy value semantics, strict -`const`-propagation, and allocator awareness, aligning heavily with the -principles of `jbcoe/value_types` (P3019). +These protocols maintain deep-copy value semantics, strict `const`-propagation, +and allocator awareness, consistent with the design of `jbcoe/value_types` +(P3019). ## Standardization -As C++ reflection (P2996) matures and advanced code injection capabilities are -added in future standards (C++29+), the generation process demonstrated here via -`py_cppmodel` will be achievable natively within the language. +As C++ reflection (P2996) matures and code injection is added in future +standards (C++29+), the generation approach demonstrated here via `py_cppmodel` +will be achievable natively within the language. -A draft proposal detailing this feature can be found in `proposals/DRAFT.md`. +A draft proposal is available in `DRAFT.md`. ## Use -Unlike traditional polymorphism, the interface is just a struct. No `virtual` -keywords, no `= 0`, and no base classes. +The interface is a plain struct with no `virtual` keywords, no `= 0`, and no base +classes. ```cpp #pragma once @@ -52,7 +52,7 @@ struct B { } // namespace xyz ``` -Write your concrete type. It does not need to inherit from `xyz::B`. It only +Write your concrete type. It does not need to inherit from `xyz::B`; it only needs to structurally provide the methods defined in the interface. ```cpp @@ -75,9 +75,8 @@ class MyImplementation { } // namespace xyz ``` -We can now use `xyz::protocol`, an automatically generated type-erased -wrapper. It copies deeply, propagates `const` correctly, and supports custom -allocators. +`xyz::protocol` is an automatically generated type-erased wrapper. It +copies deeply, propagates `const` correctly, and supports custom allocators. ```cpp #include "generated/protocol_B.h" @@ -102,7 +101,7 @@ int main() { ``` The generated wrapper uses C++20 concepts and `requires` clauses: any structural -mismatch emits clear, pinpointed compile-time errors rather than deeply nested +mismatch produces clear, pinpointed compile-time errors rather than deeply nested template instantiation failures. ```cpp @@ -123,9 +122,8 @@ class BadImplementation { Alongside `protocol`, the code generator also produces a `protocol_view` specialization. While `protocol` manages the lifecycle of the underlying object -(with deep-copy value semantics), `protocol_view` provides a lightweight, -non-owning reference. It functions similarly to `std::string_view` or -`std::span` but for protocols. +(with deep-copy value semantics), `protocol_view` is a lightweight, non-owning +reference, analogous to `std::string_view` or `std::span`, but for protocols. ```cpp // `view` observes the object without owning or copying it. @@ -142,35 +140,32 @@ int main() { inspect(impl); xyz::protocol p(std::in_place_type); - // Implicitly constructs a view over `p` as the protocol itself satisfies the requirements! + // Implicitly constructs a view over `p` as the protocol itself satisfies the requirements. inspect(p); return 0; } ``` -A `protocol_view` provides true zero-overhead duck-typing at function -boundaries, decoupling types while avoiding the cost of allocations and deep -copies. +`protocol_view` provides non-owning, allocation-free structural dispatch at +function boundaries, avoiding deep copies while dispatching through a +lightweight indirection. ## Implementation Details and Benchmarks -The `protocol` code generator supports two different underlying dispatch -strategies: +The code generator supports two dispatch strategies: 1. Virtual Dispatch (Default): Generates a traditional C++ polymorphic class hierarchy with `virtual` methods. The type-erased wrapper heap-allocates a control block derived from a common interface. -2. Explicit Manual Vtables: Generates a struct-of-function-pointers representing - the vtable. This approach manually manages type-erasure and dispatch via - pointer indirection. +2. Manual Vtables: Generates a struct-of-function-pointers representing the + vtable, managing type-erasure and dispatch via pointer indirection. Both implementations enforce identical constraints (value semantics, `const` -correctness, and custom allocators). The library builds both versions to ensure -they are strictly equivalent and offers a `protocol_benchmark` target to -directly compare their performance for allocations, copies, moves, and member -function calls. +correctness, and custom allocators). The library builds both versions to verify +equivalence and provides a `protocol_benchmark` target for directly comparing +their performance across allocations, copies, moves, and member function calls. ```bash # Build and run the benchmark comparing the two implementations @@ -179,9 +174,8 @@ function calls. ## Contributing and Development -For instructions on how to build, test, and contribute to this project, as well -as a deeper look into the code generation architecture, please refer to the -[Developer Guide](CONTRIBUTING.md). +For build instructions, testing, contributing guidelines, and a deeper look into +the code generation architecture, see the [Developer Guide](CONTRIBUTING.md). ## References