diff --git a/README.md b/README.md index 6594e5f9..c8ba2c1a 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,8 @@ class Rectangle { std::string PrintDrawableToString(pro::proxy p) { std::stringstream result; result << "shape = "; - p.Draw(result); // Polymorphic call - result << ", area = " << p.Area(); // Polymorphic call + p->Draw(result); // Polymorphic call + result << ", area = " << p->Area(); // Polymorphic call return std::move(result).str(); } @@ -76,11 +76,11 @@ struct Logger : pro::facade_builder // Client - Consumer void MyVerboseFunction(pro::proxy logger) { - logger.Log("hello"); + logger->Log("hello"); try { throw std::runtime_error{"runtime error!"}; } catch (const std::exception& e) { - logger.Log("world", e); + logger->Log("world", e); } } @@ -133,11 +133,11 @@ int main() { puts(""); }; MyFunction p0{&f}; - p0(123); // Prints "f() called. Args: 123:i," (assuming GCC) + (*p0)(123); // Prints "f() called. Args: 123:i," (assuming GCC) MyMoveOnlyFunction p1{&f}; - p1(); // Prints "f() called. Args:" - p1(456); // Prints "f() called. Args: 456:i," - p1(1.2); // Prints "f() called. Args: 1.2:d," + (*p1)(); // Prints "f() called. Args:" + (*p1)(456); // Prints "f() called. Args: 456:i," + (*p1)(1.2); // Prints "f() called. Args: 1.2:d," return 0; } ``` diff --git a/proxy.h b/proxy.h index de470900..8483c15f 100644 --- a/proxy.h +++ b/proxy.h @@ -13,6 +13,18 @@ #include #include +#if __has_cpp_attribute(msvc::no_unique_address) +#define ___PRO_NO_UNIQUE_ADDRESS_ATTRIBUTE msvc::no_unique_address +#elif __has_cpp_attribute(no_unique_address) +#define ___PRO_NO_UNIQUE_ADDRESS_ATTRIBUTE no_unique_address +#else +#error "Proxy requires C++20 attribute no_unique_address" +#endif + +#define ___PRO_DIRECT_FUNC_IMPL(...) \ + noexcept(noexcept(__VA_ARGS__)) requires(requires { __VA_ARGS__; }) \ + { return __VA_ARGS__; } + namespace pro { enum class constraint_level { none, nontrivial, nothrow, trivial }; @@ -38,6 +50,21 @@ template struct lazy_eval_traits : std::type_identity {}; template using lazy_eval_t = typename lazy_eval_traits::type; +enum class qualifier_type { lv, const_lv, rv, const_rv }; +template struct add_qualifier_traits; +template +struct add_qualifier_traits : std::type_identity {}; +template +struct add_qualifier_traits + : std::type_identity {}; +template +struct add_qualifier_traits : std::type_identity {}; +template +struct add_qualifier_traits + : std::type_identity {}; +template +using add_qualifier_t = typename add_qualifier_traits::type; + template