diff --git a/CMakeLists.txt b/CMakeLists.txt index ae1ffdc..60e796c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.28) -project(msft_proxy4 VERSION 4.0.1 LANGUAGES CXX) +project(msft_proxy4 VERSION 4.0.2 LANGUAGES CXX) add_library(msft_proxy4 INTERFACE) set_target_properties(msft_proxy4 PROPERTIES EXPORT_NAME proxy) add_library(msft_proxy4::proxy ALIAS msft_proxy4) diff --git a/LICENSE b/LICENSE index 84c4f3f..6f07338 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2022-2026 Microsoft Corporation. + Copyright (c) 2026-Present Next Gen C++ Foundation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 75737c1..2b34a01 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ If so, this library is for you. "Proxy" is a modern C++ library that helps you use polymorphism (a way to use different types of objects interchangeably) without needing inheritance. -"Proxy" was created by Microsoft engineers and incubated at Microsoft from 2018 to Feb 2026, and has been used in the Windows operating system since 2022. It is now maintained by the Next Gen C++ Foundation (ngcpp). This repository was ported from https://github.com/microsoft/proxy, where more historical releases can be found. 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: +"Proxy" was created by Microsoft engineers and incubated at Microsoft from 2018 to Feb 2026, and has been used in the Windows operating system since 2022. It is now maintained by the Next Gen C++ Foundation (ngcpp). This repository was ported from [microsoft/proxy](https://github.com/microsoft/proxy), where more historical releases can be found. 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: - **Portable**: "Proxy" was implemented as a header-only 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. - **Non-intrusive**: An implementation type is no longer required to inherit from an abstract binding. diff --git a/benchmarks/proxy_creation_benchmark.cpp b/benchmarks/proxy_creation_benchmark.cpp index 11d8b29..dc7ccda 100644 --- a/benchmarks/proxy_creation_benchmark.cpp +++ b/benchmarks/proxy_creation_benchmark.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/benchmarks/proxy_operation_benchmark.cpp b/benchmarks/proxy_operation_benchmark.cpp index dbb3053..9c21576 100644 --- a/benchmarks/proxy_operation_benchmark.cpp +++ b/benchmarks/proxy_operation_benchmark.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/benchmarks/proxy_operation_benchmark_context.cpp b/benchmarks/proxy_operation_benchmark_context.cpp index fedcef6..7ab293d 100644 --- a/benchmarks/proxy_operation_benchmark_context.cpp +++ b/benchmarks/proxy_operation_benchmark_context.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include "proxy_operation_benchmark_context.h" diff --git a/benchmarks/proxy_operation_benchmark_context.h b/benchmarks/proxy_operation_benchmark_context.h index 53bf0f1..d0566c7 100644 --- a/benchmarks/proxy_operation_benchmark_context.h +++ b/benchmarks/proxy_operation_benchmark_context.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/docs/resources/icon.png b/docs/resources/icon.png index 5b2ea19..bc87464 100644 Binary files a/docs/resources/icon.png and b/docs/resources/icon.png differ diff --git a/docs/spec/msft_lib_proxy.md b/docs/spec/msft_lib_proxy.md index b3c8593..71612e6 100644 --- a/docs/spec/msft_lib_proxy.md +++ b/docs/spec/msft_lib_proxy.md @@ -10,6 +10,7 @@ Starting with 3.0.0, Proxy ships a feature-test macro that encodes the library v | Version | Value of `__msft_lib_proxy` | | ------- | --------------------------- | +| 4.0.2 | `202603L` | | 4.0.1 | `202510L` | | 4.0.0 | `202508L` | | 3.4.0 | `202505L` | diff --git a/include/proxy/proxy.h b/include/proxy/proxy.h index d840382..fa2b431 100644 --- a/include/proxy/proxy.h +++ b/include/proxy/proxy.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #ifndef MSFT_PROXY_PROXY_H_ diff --git a/include/proxy/proxy_fmt.h b/include/proxy/proxy_fmt.h index 1d3b154..5dbbbcd 100644 --- a/include/proxy/proxy_fmt.h +++ b/include/proxy/proxy_fmt.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #ifndef MSFT_PROXY_PROXY_FMT_H_ diff --git a/include/proxy/proxy_macros.h b/include/proxy/proxy_macros.h index 953e7dd..cba1bdf 100644 --- a/include/proxy/proxy_macros.h +++ b/include/proxy/proxy_macros.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #ifndef MSFT_PROXY_PROXY_MACROS_H_ diff --git a/include/proxy/v4/proxy.h b/include/proxy/v4/proxy.h index 0a6eccc..ae9903f 100644 --- a/include/proxy/v4/proxy.h +++ b/include/proxy/v4/proxy.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #ifndef MSFT_PROXY_V4_PROXY_H_ @@ -1288,10 +1289,26 @@ struct converter { template operator T() && noexcept( std::is_nothrow_invocable_r_v>) - requires(std::is_invocable_r_v>) + requires(std::is_invocable_r_v> && + !std::is_invocable_r_v> && + !std::is_invocable_r_v>) { return std::move(f_)(std::in_place_type); } + template + operator T&() && noexcept( + std::is_nothrow_invocable_r_v>) + requires(std::is_invocable_r_v>) + { + return std::move(f_)(std::in_place_type); + } + template + operator T&&() && noexcept( + std::is_nothrow_invocable_r_v>) + requires(std::is_invocable_r_v>) + { + return std::move(f_)(std::in_place_type); + } private: F f_; @@ -2346,14 +2363,29 @@ struct sign { template sign(const char (&str)[N]) -> sign; -struct wildcard { - wildcard() = delete; +// When std::reference_constructs_from_temporary_v (C++23) is not available, we +// fall back to a conservative approximation that disallows binding a temporary +// to a reference type if the source type is not a reference or if the source +// and target reference types are not compatible. +template +concept explicitly_convertible = + std::is_constructible_v && +#if __cpp_lib_reference_from_temporary >= 202202L + !std::reference_constructs_from_temporary_v; +#else + (!std::is_reference_v || + (std::is_reference_v && + std::is_convertible_v>, + std::add_pointer_t>>)); +#endif // __cpp_lib_reference_from_temporary >= 202202L +struct noreturn_conversion { template - [[noreturn]] operator T() const { + [[noreturn]] PRO4D_STATIC_CALL(T, std::in_place_type_t) { PROD_UNREACHABLE(); } }; +using wildcard = converter; } // namespace details @@ -2577,9 +2609,9 @@ struct explicit_conversion_dispatch : details::cast_dispatch_base { PRO4D_STATIC_CALL(auto, T&& self) noexcept { return details::converter{ [&self](std::in_place_type_t) noexcept( - std::is_nothrow_constructible_v) - requires(std::is_constructible_v) - { return U{std::forward(self)}; }}; + std::is_nothrow_constructible_v) -> U + requires(details::explicitly_convertible < T &&, U >) + { return static_cast(std::forward(self)); }}; } }; using conversion_dispatch = explicit_conversion_dispatch; diff --git a/include/proxy/v4/proxy_fmt.h b/include/proxy/v4/proxy_fmt.h index 5587b8f..378310c 100644 --- a/include/proxy/v4/proxy_fmt.h +++ b/include/proxy/v4/proxy_fmt.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #ifndef MSFT_PROXY_V4_PROXY_FMT_H_ diff --git a/include/proxy/v4/proxy_macros.h b/include/proxy/v4/proxy_macros.h index 3590ddf..74ad2f4 100644 --- a/include/proxy/v4/proxy_macros.h +++ b/include/proxy/v4/proxy_macros.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #ifndef MSFT_PROXY_V4_PROXY_MACROS_H_ @@ -28,7 +29,7 @@ #define PRO4D_DEBUG(...) __VA_ARGS__ #endif // NDEBUG -#define __msft_lib_proxy4 202510L +#define __msft_lib_proxy4 202603L #define PRO4D_DIRECT_FUNC_IMPL(...) \ noexcept(noexcept(__VA_ARGS__)) \ diff --git a/meson.build b/meson.build index d909e1a..5905e86 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'msft_proxy4', 'cpp', - version: '4.0.1', + version: '4.0.2', license: 'MIT', license_files: 'LICENSE', meson_version: '>=1.3', diff --git a/mkdocs.yml b/mkdocs.yml index 06eed02..556f54a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,7 +2,7 @@ site_name: Proxy 4 site_url: https://ngcpp.github.io/proxy site_description: Next Generation Polymorphism in C++ -copyright: Copyright (c) 2022-2026 Microsoft Corporation +copyright: Copyright (c) 2022-2026 Microsoft Corporation
Copyright (c) 2026-Present Next Gen C++ Foundation repo_url: https://github.com/ngcpp/proxy/ edit_uri: "" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 127c21b..ff508a3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,6 +12,7 @@ include(GoogleTest) add_executable(msft_proxy_tests proxy_creation_tests.cpp + proxy_details_tests.cpp proxy_dispatch_tests.cpp proxy_fmt_format_tests.cpp proxy_format_tests.cpp diff --git a/tests/proxy_creation_tests.cpp b/tests/proxy_creation_tests.cpp index b93727c..d88dc24 100644 --- a/tests/proxy_creation_tests.cpp +++ b/tests/proxy_creation_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include "utils.h" diff --git a/tests/proxy_details_tests.cpp b/tests/proxy_details_tests.cpp new file mode 100644 index 0000000..a10cd4f --- /dev/null +++ b/tests/proxy_details_tests.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2026-Present Next Gen C++ Foundation. +// Licensed under the MIT License. + +#include + +namespace proxy_details_tests_details { + +struct Base { + int v; +}; +struct Derived : Base {}; + +static_assert(pro::details::explicitly_convertible); +static_assert(pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); +static_assert(pro::details::explicitly_convertible); +static_assert(pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); +static_assert(pro::details::explicitly_convertible); +static_assert(pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); +static_assert( + pro::details::explicitly_convertible); +static_assert(pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); +static_assert(!pro::details::explicitly_convertible); + +} // namespace proxy_details_tests_details diff --git a/tests/proxy_dispatch_tests.cpp b/tests/proxy_dispatch_tests.cpp index 0e66170..1dde852 100644 --- a/tests/proxy_dispatch_tests.cpp +++ b/tests/proxy_dispatch_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include @@ -783,11 +784,13 @@ TEST(ProxyDispatchTests, TestRhsOpPtrToMem) { TEST(ProxyDispatchTests, TestIndirectConversion) { struct TestFacade - : pro::facade_builder::add_convention::build {}; + : pro::facade_builder // + ::add_convention // + ::build {}; short v = 123; pro::proxy p = &v; - ASSERT_EQ(static_cast(*p), 123); + static_cast(*p) = 456; + ASSERT_EQ(static_cast(*p), 456); } TEST(ProxyDispatchTests, TestDirectConversion) { diff --git a/tests/proxy_fmt_format_tests.cpp b/tests/proxy_fmt_format_tests.cpp index 7467c23..7a4a93e 100644 --- a/tests/proxy_fmt_format_tests.cpp +++ b/tests/proxy_fmt_format_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/tests/proxy_format_tests.cpp b/tests/proxy_format_tests.cpp index 4860b25..848cef0 100644 --- a/tests/proxy_format_tests.cpp +++ b/tests/proxy_format_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/tests/proxy_integration_tests.cpp b/tests/proxy_integration_tests.cpp index 7f2fb6d..d54d415 100644 --- a/tests/proxy_integration_tests.cpp +++ b/tests/proxy_integration_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/tests/proxy_invocation_tests.cpp b/tests/proxy_invocation_tests.cpp index 5dd57ce..69eacd0 100644 --- a/tests/proxy_invocation_tests.cpp +++ b/tests/proxy_invocation_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/tests/proxy_lifetime_tests.cpp b/tests/proxy_lifetime_tests.cpp index 91942e8..24d5e49 100644 --- a/tests/proxy_lifetime_tests.cpp +++ b/tests/proxy_lifetime_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include "utils.h" diff --git a/tests/proxy_reflection_tests.cpp b/tests/proxy_reflection_tests.cpp index ecbf6cd..ab24402 100644 --- a/tests/proxy_reflection_tests.cpp +++ b/tests/proxy_reflection_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include "utils.h" diff --git a/tests/proxy_regression_tests.cpp b/tests/proxy_regression_tests.cpp index 5c21917..d338908 100644 --- a/tests/proxy_regression_tests.cpp +++ b/tests/proxy_regression_tests.cpp @@ -1,8 +1,17 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(push) +#pragma warning( \ + disable : 4702) // False alarm from MSVC: warning C4702: unreachable code +#endif // defined(_MSC_VER) && !defined(__clang__) #include +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif // defined(_MSC_VER) && !defined(__clang__) #include namespace proxy_regression_tests_details { @@ -39,6 +48,8 @@ struct Range : pro::facade_builder // ::template add_convention>()> // ::build {}; +PRO_DEF_MEM_DISPATCH(MemFun, Fun); + } // namespace proxy_regression_tests_details namespace details = proxy_regression_tests_details; @@ -69,3 +80,16 @@ TEST(ProxyRegressionTests, TestProxiableSelfDependency) { } EXPECT_EQ(expected, original); } + +// https://github.com/ngcpp/proxy/issues/10 +TEST(ProxyRegressionTests, TestWeakDispatchReferenceReturningOverload) { + struct MyFacade + : pro::facade_builder // + ::add_convention, int&()> // + ::build {}; + static_assert(pro::proxiable); + + int v = 123; + pro::proxy p = &v; + EXPECT_THROW(p->Fun(), pro::not_implemented); +} diff --git a/tests/proxy_rtti_tests.cpp b/tests/proxy_rtti_tests.cpp index 3965ca2..1545939 100644 --- a/tests/proxy_rtti_tests.cpp +++ b/tests/proxy_rtti_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include diff --git a/tests/proxy_traits_tests.cpp b/tests/proxy_traits_tests.cpp index 51ef045..0f092e6 100644 --- a/tests/proxy_traits_tests.cpp +++ b/tests/proxy_traits_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include "utils.h" diff --git a/tests/proxy_view_tests.cpp b/tests/proxy_view_tests.cpp index 9dbf3c5..f47f5b0 100644 --- a/tests/proxy_view_tests.cpp +++ b/tests/proxy_view_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include "utils.h" diff --git a/tests/utils.h b/tests/utils.h index 8ad7fac..000b356 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #ifndef _MSFT_PROXY_TEST_UTILS_ diff --git a/tools/report_generator/main.cpp b/tools/report_generator/main.cpp index 9e47a46..a83dcde 100644 --- a/tools/report_generator/main.cpp +++ b/tools/report_generator/main.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2022-2026 Microsoft Corporation. +// Copyright (c) 2026-Present Next Gen C++ Foundation. // Licensed under the MIT License. #include