From 75df953d3b2ba8f71804553b309418a962e441ec Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Mon, 9 Jun 2025 19:43:48 +0800 Subject: [PATCH 1/3] Move proxy.h to v3 --- include/proxy/{ => v3}/proxy.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename include/proxy/{ => v3}/proxy.h (100%) diff --git a/include/proxy/proxy.h b/include/proxy/v3/proxy.h similarity index 100% rename from include/proxy/proxy.h rename to include/proxy/v3/proxy.h From 2764657008e919ea44e9e9961b5e25b4c1b7690c Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Mon, 9 Jun 2025 19:48:28 +0800 Subject: [PATCH 2/3] Backport compatibility --- CMakeLists.txt | 1 + docs/msft_lib_proxy.md | 1 + include/proxy/proxy.h | 9 + include/proxy/v3/proxy.h | 393 ++++++++++++++++++++++----------------- 4 files changed, 238 insertions(+), 166 deletions(-) create mode 100644 include/proxy/proxy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c8c041be..f615d7e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ target_sources(msft_proxy BASE_DIRS include FILES include/proxy/proxy.h + include/proxy/v3/proxy.h ) target_compile_features(msft_proxy INTERFACE cxx_std_20) diff --git a/docs/msft_lib_proxy.md b/docs/msft_lib_proxy.md index 4f642c1e..356078a7 100644 --- a/docs/msft_lib_proxy.md +++ b/docs/msft_lib_proxy.md @@ -8,6 +8,7 @@ Similar to the standard [feature test macros](https://en.cppreference.com/w/cpp/ | Version | Value of `__msft_lib_proxy` | | ------- | --------------------------- | +| 3.4.0 | `202505L` | | 3.3.0 | `202503L` | | 3.2.1 | `202502L` | | 3.2.0 | `202501L` | diff --git a/include/proxy/proxy.h b/include/proxy/proxy.h new file mode 100644 index 00000000..7ebd2f38 --- /dev/null +++ b/include/proxy/proxy.h @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#ifndef _MSFT_PROXY_ +#define _MSFT_PROXY_ + +#include "v3/proxy.h" // IWYU pragma: export + +#endif // _MSFT_PROXY_ diff --git a/include/proxy/v3/proxy.h b/include/proxy/v3/proxy.h index 02fde832..197bd086 100644 --- a/include/proxy/v3/proxy.h +++ b/include/proxy/v3/proxy.h @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#ifndef _MSFT_PROXY_ -#define _MSFT_PROXY_ +#ifndef _MSFT_PROXY3_ +#define _MSFT_PROXY3_ #include #include @@ -43,26 +43,26 @@ #endif // __cpp_exceptions >= 199711L #if __cpp_static_call_operator >= 202207L -#define ___PRO_STATIC_CALL(__R, ...) static __R operator()(__VA_ARGS__) +#define ___PRO3_STATIC_CALL(__R, ...) static __R operator()(__VA_ARGS__) #else -#define ___PRO_STATIC_CALL(__R, ...) __R operator()(__VA_ARGS__) const +#define ___PRO3_STATIC_CALL(__R, ...) __R operator()(__VA_ARGS__) const #endif // __cpp_static_call_operator >= 202207L #ifdef _MSC_VER -#define ___PRO_ENFORCE_EBO __declspec(empty_bases) +#define ___PRO3_ENFORCE_EBO __declspec(empty_bases) #else -#define ___PRO_ENFORCE_EBO +#define ___PRO3_ENFORCE_EBO #endif // _MSC_VER #ifdef NDEBUG -#define ___PRO_DEBUG(...) +#define ___PRO3_DEBUG(...) #else -#define ___PRO_DEBUG(...) __VA_ARGS__ +#define ___PRO3_DEBUG(...) __VA_ARGS__ #endif // NDEBUG -#define __msft_lib_proxy 202503L +#define __msft3_lib_proxy 202505L -namespace pro { +namespace pro::inline v3 { namespace details { @@ -127,7 +127,7 @@ template concept facade = details::basic_facade_traits::applicable; template struct proxy_indirect_accessor; -template class ___PRO_ENFORCE_EBO proxy; +template class ___PRO3_ENFORCE_EBO proxy; namespace details { @@ -483,14 +483,14 @@ struct refl_traits { struct copy_dispatch { template - ___PRO_STATIC_CALL(void, T&& self, proxy& rhs) + ___PRO3_STATIC_CALL(void, T&& self, proxy& rhs) noexcept(std::is_nothrow_constructible_v, T>) requires(std::is_constructible_v, T>) { std::construct_at(&rhs, std::forward(self)); } }; struct destroy_dispatch { template - ___PRO_STATIC_CALL(void, T& self) noexcept(std::is_nothrow_destructible_v) + ___PRO3_STATIC_CALL(void, T& self) noexcept(std::is_nothrow_destructible_v) requires(std::is_destructible_v) { std::destroy_at(&self); } }; template @@ -505,9 +505,9 @@ template using lifetime_meta_t = typename lifetime_meta_traits::type; template -class ___PRO_ENFORCE_EBO composite_accessor_impl : public As... { - template friend class pro::proxy; - template friend struct pro::proxy_indirect_accessor; +class ___PRO3_ENFORCE_EBO composite_accessor_impl : public As... { + template friend class pro::v3::proxy; + template friend struct pro::v3::proxy_indirect_accessor; composite_accessor_impl() noexcept = default; composite_accessor_impl(const composite_accessor_impl&) noexcept = default; @@ -934,7 +934,7 @@ class proxy : public details::facade_traits::direct_accessor, static_assert(_Traits::applicable); public: - proxy() noexcept { ___PRO_DEBUG(std::ignore = &_symbol_guard;) } + proxy() noexcept { ___PRO3_DEBUG(std::ignore = &_symbol_guard;) } proxy(std::nullptr_t) noexcept : proxy() {} proxy(const proxy&) noexcept requires(F::constraints.copyability == constraint_level::trivial) = default; @@ -1107,7 +1107,7 @@ class proxy : public details::facade_traits::direct_accessor, return result; } -___PRO_DEBUG( +___PRO3_DEBUG( static inline void _symbol_guard(proxy& self, const proxy& cself) noexcept { self.operator->(); *self; *std::move(self); cself.operator->(); *cself; *std::move(cself); @@ -1182,7 +1182,7 @@ class indirect_ptr { }; template -class ___PRO_ENFORCE_EBO allocated_ptr +class ___PRO3_ENFORCE_EBO allocated_ptr : private alloc_aware, public indirect_ptr> { public: template @@ -1204,7 +1204,7 @@ class ___PRO_ENFORCE_EBO allocated_ptr }; template -struct ___PRO_ENFORCE_EBO compact_ptr_storage +struct ___PRO3_ENFORCE_EBO compact_ptr_storage : alloc_aware, inplace_ptr { template explicit compact_ptr_storage(const Alloc& alloc, Args&&... args) @@ -1232,7 +1232,7 @@ class compact_ptr : public indirect_ptr> { struct shared_compact_ptr_storage_base { std::atomic_long ref_count = 1; }; template -struct ___PRO_ENFORCE_EBO shared_compact_ptr_storage +struct ___PRO3_ENFORCE_EBO shared_compact_ptr_storage : shared_compact_ptr_storage_base, alloc_aware, inplace_ptr { template explicit shared_compact_ptr_storage(const Alloc& alloc, Args&&... args) @@ -1524,120 +1524,125 @@ constexpr proxy make_proxy_shared(T&& value) #if __cpp_rtti >= 199711L class bad_proxy_cast : public std::bad_cast { public: - char const* what() const noexcept override { return "pro::bad_proxy_cast"; } + char const* what() const noexcept override + { return "pro::v3::bad_proxy_cast"; } }; #endif // __cpp_rtti >= 199711L -#define ___PRO_DIRECT_FUNC_IMPL(...) \ +#define ___PRO3_DIRECT_FUNC_IMPL(...) \ noexcept(noexcept(__VA_ARGS__)) requires(requires { __VA_ARGS__; }) \ { return __VA_ARGS__; } -#define ___PRO_DEF_MEM_ACCESSOR_TEMPLATE(__MACRO, ...) \ +#define ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE(__MACRO, ...) \ template \ - struct ___PRO_ENFORCE_EBO accessor { accessor() = delete; }; \ + struct ___PRO3_ENFORCE_EBO accessor { accessor() = delete; }; \ template \ requires(sizeof...(__Os) > 1u && (::std::is_constructible_v< \ accessor<__F, __IsDirect, __D, __Os>> && ...)) \ struct accessor<__F, __IsDirect, __D, __Os...> \ : accessor<__F, __IsDirect, __D, __Os>... \ { using accessor<__F, __IsDirect, __D, __Os>::__VA_ARGS__...; }; \ - __MACRO(, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(noexcept, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(&, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(& noexcept, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(&&, ::pro::access_proxy<__F>(::std::move(*this)), __VA_ARGS__); \ - __MACRO(&& noexcept, ::pro::access_proxy<__F>(::std::move(*this)), \ + __MACRO(, ::pro::v3::access_proxy<__F>(*this), __VA_ARGS__); \ + __MACRO(noexcept, ::pro::v3::access_proxy<__F>(*this), __VA_ARGS__); \ + __MACRO(&, ::pro::v3::access_proxy<__F>(*this), __VA_ARGS__); \ + __MACRO(& noexcept, ::pro::v3::access_proxy<__F>(*this), __VA_ARGS__); \ + __MACRO(&&, ::pro::v3::access_proxy<__F>(::std::move(*this)), \ __VA_ARGS__); \ - __MACRO(const, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(const noexcept, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(const&, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(const& noexcept, ::pro::access_proxy<__F>(*this), __VA_ARGS__); \ - __MACRO(const&&, ::pro::access_proxy<__F>(::std::move(*this)), \ + __MACRO(&& noexcept, ::pro::v3::access_proxy<__F>(::std::move(*this)), \ __VA_ARGS__); \ - __MACRO(const&& noexcept, ::pro::access_proxy<__F>(::std::move(*this)), \ - __VA_ARGS__); + __MACRO(const, ::pro::v3::access_proxy<__F>(*this), __VA_ARGS__); \ + __MACRO(const noexcept, ::pro::v3::access_proxy<__F>(*this), \ + __VA_ARGS__); \ + __MACRO(const&, ::pro::v3::access_proxy<__F>(*this), __VA_ARGS__); \ + __MACRO(const& noexcept, ::pro::v3::access_proxy<__F>(*this), \ + __VA_ARGS__); \ + __MACRO(const&&, ::pro::v3::access_proxy<__F>(::std::move(*this)), \ + __VA_ARGS__); \ + __MACRO(const&& noexcept, ::pro::v3::access_proxy<__F>( \ + ::std::move(*this)), __VA_ARGS__); -#define ___PRO_ADL_ARG ::pro::details::adl_accessor_arg_t<__F, __IsDirect> -#define ___PRO_DEF_FREE_ACCESSOR_TEMPLATE(__MACRO, ...) \ +#define ___PRO3_ADL_ARG ::pro::v3::details::adl_accessor_arg_t<__F, __IsDirect> +#define ___PRO3_DEF_FREE_ACCESSOR_TEMPLATE(__MACRO, ...) \ template \ - struct ___PRO_ENFORCE_EBO accessor { accessor() = delete; }; \ + struct ___PRO3_ENFORCE_EBO accessor { accessor() = delete; }; \ template \ requires(sizeof...(__Os) > 1u && (::std::is_constructible_v< \ accessor<__F, __IsDirect, __D, __Os>> && ...)) \ struct accessor<__F, __IsDirect, __D, __Os...> \ : accessor<__F, __IsDirect, __D, __Os>... {}; \ - __MACRO(,, ___PRO_ADL_ARG& __self, ::pro::access_proxy<__F>(__self), \ + __MACRO(,, ___PRO3_ADL_ARG& __self, ::pro::v3::access_proxy<__F>(__self), \ __VA_ARGS__); \ - __MACRO(noexcept, noexcept, ___PRO_ADL_ARG& __self, \ - ::pro::access_proxy<__F>(__self), __VA_ARGS__); \ - __MACRO(&,, ___PRO_ADL_ARG& __self, ::pro::access_proxy<__F>(__self), \ + __MACRO(noexcept, noexcept, ___PRO3_ADL_ARG& __self, \ + ::pro::v3::access_proxy<__F>(__self), __VA_ARGS__); \ + __MACRO(&,, ___PRO3_ADL_ARG& __self, ::pro::v3::access_proxy<__F>(__self), \ __VA_ARGS__); \ - __MACRO(& noexcept, noexcept, ___PRO_ADL_ARG& __self, \ - ::pro::access_proxy<__F>(__self), __VA_ARGS__); \ - __MACRO(&&,, ___PRO_ADL_ARG&& __self, ::pro::access_proxy<__F>( \ + __MACRO(& noexcept, noexcept, ___PRO3_ADL_ARG& __self, \ + ::pro::v3::access_proxy<__F>(__self), __VA_ARGS__); \ + __MACRO(&&,, ___PRO3_ADL_ARG&& __self, ::pro::v3::access_proxy<__F>( \ ::std::forward(__self)), __VA_ARGS__); \ - __MACRO(&& noexcept, noexcept, ___PRO_ADL_ARG&& __self, \ - ::pro::access_proxy<__F>(::std::forward(__self)), \ - __VA_ARGS__); \ - __MACRO(const,, const ___PRO_ADL_ARG& __self, \ - ::pro::access_proxy<__F>(__self), __VA_ARGS__); \ - __MACRO(const noexcept, noexcept, const ___PRO_ADL_ARG& __self, \ - ::pro::access_proxy<__F>(__self), __VA_ARGS__); \ - __MACRO(const&,, const ___PRO_ADL_ARG& __self, \ - ::pro::access_proxy<__F>(__self), __VA_ARGS__); \ - __MACRO(const& noexcept, noexcept, const ___PRO_ADL_ARG& __self, \ - ::pro::access_proxy<__F>(__self), __VA_ARGS__); \ - __MACRO(const&&,, const ___PRO_ADL_ARG&& __self, ::pro::access_proxy<__F>( \ - ::std::forward(__self)), __VA_ARGS__); \ - __MACRO(const&& noexcept, noexcept, const ___PRO_ADL_ARG&& __self, \ - ::pro::access_proxy<__F>(::std::forward(__self)), \ - __VA_ARGS__); - -#define ___PRO_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(...) \ - ___PRO_DEBUG( \ + __MACRO(&& noexcept, noexcept, ___PRO3_ADL_ARG&& __self, \ + ::pro::v3::access_proxy<__F>( \ + ::std::forward(__self)), __VA_ARGS__); \ + __MACRO(const,, const ___PRO3_ADL_ARG& __self, \ + ::pro::v3::access_proxy<__F>(__self), __VA_ARGS__); \ + __MACRO(const noexcept, noexcept, const ___PRO3_ADL_ARG& __self, \ + ::pro::v3::access_proxy<__F>(__self), __VA_ARGS__); \ + __MACRO(const&,, const ___PRO3_ADL_ARG& __self, \ + ::pro::v3::access_proxy<__F>(__self), __VA_ARGS__); \ + __MACRO(const& noexcept, noexcept, const ___PRO3_ADL_ARG& __self, \ + ::pro::v3::access_proxy<__F>(__self), __VA_ARGS__); \ + __MACRO(const&&,, const ___PRO3_ADL_ARG&& __self, \ + ::pro::v3::access_proxy<__F>( \ + ::std::forward(__self)), __VA_ARGS__); \ + __MACRO(const&& noexcept, noexcept, const ___PRO3_ADL_ARG&& __self, \ + ::pro::v3::access_proxy<__F>( \ + ::std::forward(__self)), __VA_ARGS__); + +#define ___PRO3_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(...) \ + ___PRO3_DEBUG( \ accessor() noexcept { ::std::ignore = &accessor::__VA_ARGS__; }) -#define ___PRO_EXPAND_IMPL(__X) __X -#define ___PRO_EXPAND_MACRO_IMPL(__MACRO, __1, __2, __3, __NAME, ...) \ +#define ___PRO3_EXPAND_IMPL(__X) __X +#define ___PRO3_EXPAND_MACRO_IMPL(__MACRO, __1, __2, __3, __NAME, ...) \ __MACRO##_##__NAME -#define ___PRO_EXPAND_MACRO(__MACRO, ...) \ - ___PRO_EXPAND_IMPL(___PRO_EXPAND_MACRO_IMPL( \ +#define ___PRO3_EXPAND_MACRO(__MACRO, ...) \ + ___PRO3_EXPAND_IMPL(___PRO3_EXPAND_MACRO_IMPL( \ __MACRO, __VA_ARGS__, 3, 2)(__VA_ARGS__)) -#define ___PRO_DEF_MEM_ACCESSOR(__Q, __SELF, ...) \ +#define ___PRO3_DEF_MEM_ACCESSOR(__Q, __SELF, ...) \ template \ struct accessor<__F, __IsDirect, __D, __R(__Args...) __Q> { \ - ___PRO_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ + ___PRO3_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ __R __VA_ARGS__(__Args... __args) __Q { \ - return ::pro::proxy_invoke<__IsDirect, __D, __R(__Args...) __Q>( \ + return ::pro::v3::proxy_invoke<__IsDirect, __D, __R(__Args...) __Q>( \ __SELF, ::std::forward<__Args>(__args)...); \ } \ } -#define ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \ +#define ___PRO3_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \ struct __NAME { \ template \ - ___PRO_STATIC_CALL(decltype(auto), __T&& __self, __Args&&... __args) \ - ___PRO_DIRECT_FUNC_IMPL(::std::forward<__T>(__self) \ + ___PRO3_STATIC_CALL(decltype(auto), __T&& __self, __Args&&... __args) \ + ___PRO3_DIRECT_FUNC_IMPL(::std::forward<__T>(__self) \ .__FUNC(::std::forward<__Args>(__args)...)) \ - ___PRO_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_MEM_ACCESSOR, __FNAME) \ + ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE(___PRO3_DEF_MEM_ACCESSOR, __FNAME) \ } -#define ___PRO_DEF_MEM_DISPATCH_2(__NAME, __FUNC) \ - ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FUNC) -#define ___PRO_DEF_MEM_DISPATCH_3(__NAME, __FUNC, __FNAME) \ - ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) -#define PRO_DEF_MEM_DISPATCH(__NAME, ...) \ - ___PRO_EXPAND_MACRO(___PRO_DEF_MEM_DISPATCH, __NAME, __VA_ARGS__) - -#define ___PRO_DEF_FREE_ACCESSOR(__Q, __NE, __SELF_ARG, __SELF, ...) \ +#define ___PRO3_DEF_MEM_DISPATCH_2(__NAME, __FUNC) \ + ___PRO3_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FUNC) +#define ___PRO3_DEF_MEM_DISPATCH_3(__NAME, __FUNC, __FNAME) \ + ___PRO3_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) +#define PRO3_DEF_MEM_DISPATCH(__NAME, ...) \ + ___PRO3_EXPAND_MACRO(___PRO3_DEF_MEM_DISPATCH, __NAME, __VA_ARGS__) + +#define ___PRO3_DEF_FREE_ACCESSOR(__Q, __NE, __SELF_ARG, __SELF, ...) \ template \ struct accessor<__F, __IsDirect, __D, __R(__Args...) __Q> { \ friend __R __VA_ARGS__(__SELF_ARG, __Args... __args) __NE { \ - return ::pro::proxy_invoke<__IsDirect, __D, __R(__Args...) __Q>( \ + return ::pro::v3::proxy_invoke<__IsDirect, __D, __R(__Args...) __Q>( \ __SELF, ::std::forward<__Args>(__args)...); \ } \ -___PRO_DEBUG( \ +___PRO3_DEBUG( \ accessor() noexcept { ::std::ignore = &_symbol_guard; } \ \ private: \ @@ -1647,35 +1652,35 @@ ___PRO_DEBUG( \ } \ ) \ } -#define ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \ +#define ___PRO3_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \ struct __NAME { \ template \ - ___PRO_STATIC_CALL(decltype(auto), __T&& __self, __Args&&... __args) \ - ___PRO_DIRECT_FUNC_IMPL(__FUNC(::std::forward<__T>(__self), \ + ___PRO3_STATIC_CALL(decltype(auto), __T&& __self, __Args&&... __args) \ + ___PRO3_DIRECT_FUNC_IMPL(__FUNC(::std::forward<__T>(__self), \ ::std::forward<__Args>(__args)...)) \ - ___PRO_DEF_FREE_ACCESSOR_TEMPLATE(___PRO_DEF_FREE_ACCESSOR, __FNAME) \ + ___PRO3_DEF_FREE_ACCESSOR_TEMPLATE(___PRO3_DEF_FREE_ACCESSOR, __FNAME) \ } -#define ___PRO_DEF_FREE_DISPATCH_2(__NAME, __FUNC) \ - ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FUNC) -#define ___PRO_DEF_FREE_DISPATCH_3(__NAME, __FUNC, __FNAME) \ - ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) -#define PRO_DEF_FREE_DISPATCH(__NAME, ...) \ - ___PRO_EXPAND_MACRO(___PRO_DEF_FREE_DISPATCH, __NAME, __VA_ARGS__) - -#define ___PRO_DEF_FREE_AS_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \ +#define ___PRO3_DEF_FREE_DISPATCH_2(__NAME, __FUNC) \ + ___PRO3_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FUNC) +#define ___PRO3_DEF_FREE_DISPATCH_3(__NAME, __FUNC, __FNAME) \ + ___PRO3_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) +#define PRO3_DEF_FREE_DISPATCH(__NAME, ...) \ + ___PRO3_EXPAND_MACRO(___PRO3_DEF_FREE_DISPATCH, __NAME, __VA_ARGS__) + +#define ___PRO3_DEF_FREE_AS_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \ struct __NAME { \ template \ - ___PRO_STATIC_CALL(decltype(auto), __T&& __self, __Args&&... __args) \ - ___PRO_DIRECT_FUNC_IMPL(__FUNC(::std::forward<__T>(__self), \ + ___PRO3_STATIC_CALL(decltype(auto), __T&& __self, __Args&&... __args) \ + ___PRO3_DIRECT_FUNC_IMPL(__FUNC(::std::forward<__T>(__self), \ ::std::forward<__Args>(__args)...)) \ - ___PRO_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_MEM_ACCESSOR, __FNAME) \ + ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE(___PRO3_DEF_MEM_ACCESSOR, __FNAME) \ } -#define ___PRO_DEF_FREE_AS_MEM_DISPATCH_2(__NAME, __FUNC) \ - ___PRO_DEF_FREE_AS_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FUNC) -#define ___PRO_DEF_FREE_AS_MEM_DISPATCH_3(__NAME, __FUNC, __FNAME) \ - ___PRO_DEF_FREE_AS_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) -#define PRO_DEF_FREE_AS_MEM_DISPATCH(__NAME, ...) \ - ___PRO_EXPAND_MACRO(___PRO_DEF_FREE_AS_MEM_DISPATCH, __NAME, __VA_ARGS__) +#define ___PRO3_DEF_FREE_AS_MEM_DISPATCH_2(__NAME, __FUNC) \ + ___PRO3_DEF_FREE_AS_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FUNC) +#define ___PRO3_DEF_FREE_AS_MEM_DISPATCH_3(__NAME, __FUNC, __FNAME) \ + ___PRO3_DEF_FREE_AS_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) +#define PRO3_DEF_FREE_AS_MEM_DISPATCH(__NAME, ...) \ + ___PRO3_EXPAND_MACRO(___PRO3_DEF_FREE_AS_MEM_DISPATCH, __NAME, __VA_ARGS__) namespace details { @@ -1686,7 +1691,7 @@ using adl_accessor_arg_t = #define ___PRO_DEF_CAST_ACCESSOR(Q, SELF, ...) \ template \ struct accessor<__F, __IsDirect, __D, T() Q> { \ - ___PRO_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(operator T) \ + ___PRO3_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(operator T) \ explicit(Expl) operator T() Q { \ if constexpr (Nullable) { \ if (!SELF.has_value()) { return nullptr; } \ @@ -1696,14 +1701,14 @@ using adl_accessor_arg_t = } template struct cast_dispatch_base { - ___PRO_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_CAST_ACCESSOR, + ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_CAST_ACCESSOR, operator typename overload_traits<__Os>::return_type) }; #undef ___PRO_DEF_CAST_ACCESSOR struct upward_conversion_dispatch : cast_dispatch_base { template - ___PRO_STATIC_CALL(T&&, T&& self) noexcept { return std::forward(self); } + ___PRO3_STATIC_CALL(T&&, T&& self) noexcept { return std::forward(self); } }; template @@ -1877,7 +1882,7 @@ using merge_facade_conv_t = typename add_upward_conversion_conv< struct proxy_view_dispatch : cast_dispatch_base { template - ___PRO_STATIC_CALL(auto, T& value) noexcept + ___PRO3_STATIC_CALL(auto, T& value) noexcept requires(requires { { std::addressof(*value) } noexcept; }) { return observer_ptr @@ -1970,7 +1975,7 @@ sign(const char (&str)[N]) -> sign; struct weak_conversion_dispatch : cast_dispatch_base { template - ___PRO_STATIC_CALL(auto, const P& self) noexcept + ___PRO3_STATIC_CALL(auto, const P& self) noexcept requires( requires(const typename P::weak_type& w) { { w.lock() } noexcept -> std::same_as

; } && @@ -2001,7 +2006,7 @@ template auto weak_lock_impl(const P& self) noexcept requires(requires { static_cast(self.lock()); }) { return nullable_ptr_adapter{self.lock()}; } -PRO_DEF_FREE_AS_MEM_DISPATCH(weak_mem_lock, weak_lock_impl, lock); +PRO3_DEF_FREE_AS_MEM_DISPATCH(weak_mem_lock, weak_lock_impl, lock); #if __STDC_HOSTED__ template struct format_overload_traits; @@ -2025,7 +2030,7 @@ struct format_dispatch { // std::formatter by std::is_default_constructible_v as per // [format.formatter.spec]. template - ___PRO_STATIC_CALL(OutIt, const T& self, std::basic_string_view spec, + ___PRO3_STATIC_CALL(OutIt, const T& self, std::basic_string_view spec, std::basic_format_context& fc) requires( #if __cpp_lib_format_ranges >= 202207L @@ -2099,7 +2104,7 @@ struct proxy_cast_accessor_impl { void(proxy_cast_context) Q> {} struct proxy_cast_dispatch { template - ___PRO_STATIC_CALL(void, T&& self, proxy_cast_context ctx) { + ___PRO3_STATIC_CALL(void, T&& self, proxy_cast_context ctx) { if (typeid(T) == *ctx.type_ptr) { if (ctx.is_ref) { if constexpr (std::is_lvalue_reference_v) { @@ -2115,7 +2120,7 @@ struct proxy_cast_dispatch { } } } - ___PRO_DEF_FREE_ACCESSOR_TEMPLATE(___PRO_DEF_PROXY_CAST_ACCESSOR) + ___PRO3_DEF_FREE_ACCESSOR_TEMPLATE(___PRO_DEF_PROXY_CAST_ACCESSOR) }; #undef ___PRO_DEF_PROXY_CAST_ACCESSOR @@ -2134,7 +2139,7 @@ struct proxy_typeid_reflector { const proxy_typeid_reflector& refl = proxy_reflect(p); return *refl.info; } -___PRO_DEBUG( +___PRO3_DEBUG( accessor() noexcept { std::ignore = &_symbol_guard; } private: @@ -2268,13 +2273,13 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_LEFT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor<__F, __IsDirect, __D, R() Q> { \ - ___PRO_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ + ___PRO3_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ R __VA_ARGS__() Q { return proxy_invoke<__IsDirect, __D, R() Q>(SELF); } \ } #define ___PRO_DEF_LHS_ANY_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor<__F, __IsDirect, __D, R(Args...) Q> { \ - ___PRO_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ + ___PRO3_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ R __VA_ARGS__(Args... args) Q { \ return proxy_invoke<__IsDirect, __D, R(Args...) Q>( \ SELF, std::forward(args)...); \ @@ -2285,19 +2290,19 @@ struct operator_dispatch; #define ___PRO_DEF_LHS_ALL_OP_ACCESSOR ___PRO_DEF_LHS_ANY_OP_ACCESSOR #define ___PRO_LHS_LEFT_OP_DISPATCH_BODY_IMPL(...) \ template \ - ___PRO_STATIC_CALL(decltype(auto), T&& self) \ - ___PRO_DIRECT_FUNC_IMPL(__VA_ARGS__ std::forward(self)) + ___PRO3_STATIC_CALL(decltype(auto), T&& self) \ + ___PRO3_DIRECT_FUNC_IMPL(__VA_ARGS__ std::forward(self)) #define ___PRO_LHS_UNARY_OP_DISPATCH_BODY_IMPL(...) \ template \ - ___PRO_STATIC_CALL(decltype(auto), T&& self) \ - ___PRO_DIRECT_FUNC_IMPL(__VA_ARGS__ std::forward(self)) \ + ___PRO3_STATIC_CALL(decltype(auto), T&& self) \ + ___PRO3_DIRECT_FUNC_IMPL(__VA_ARGS__ std::forward(self)) \ template \ - ___PRO_STATIC_CALL(decltype(auto), T&& self, int) \ - ___PRO_DIRECT_FUNC_IMPL(std::forward(self) __VA_ARGS__) + ___PRO3_STATIC_CALL(decltype(auto), T&& self, int) \ + ___PRO3_DIRECT_FUNC_IMPL(std::forward(self) __VA_ARGS__) #define ___PRO_LHS_BINARY_OP_DISPATCH_BODY_IMPL(...) \ template \ - ___PRO_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ - ___PRO_DIRECT_FUNC_IMPL( \ + ___PRO3_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ + ___PRO3_DIRECT_FUNC_IMPL( \ std::forward(self) __VA_ARGS__ std::forward(arg)) #define ___PRO_LHS_ALL_OP_DISPATCH_BODY_IMPL(...) \ ___PRO_LHS_LEFT_OP_DISPATCH_BODY_IMPL(__VA_ARGS__) \ @@ -2306,7 +2311,7 @@ struct operator_dispatch; template <> \ struct operator_dispatch<#__VA_ARGS__, false> { \ ___PRO_LHS_##TYPE##_OP_DISPATCH_BODY_IMPL(__VA_ARGS__) \ - ___PRO_DEF_MEM_ACCESSOR_TEMPLATE( \ + ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE( \ ___PRO_DEF_LHS_##TYPE##_OP_ACCESSOR, operator __VA_ARGS__) \ }; @@ -2317,7 +2322,7 @@ struct operator_dispatch; return proxy_invoke<__IsDirect, __D, R(Arg) Q>( \ SELF, std::forward(arg)); \ } \ -___PRO_DEBUG( \ +___PRO3_DEBUG( \ accessor() noexcept { std::ignore = &_symbol_guard; } \ \ private: \ @@ -2331,10 +2336,10 @@ ___PRO_DEBUG( \ template <> \ struct operator_dispatch<#__VA_ARGS__, true> { \ template \ - ___PRO_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ - ___PRO_DIRECT_FUNC_IMPL( \ + ___PRO3_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ + ___PRO3_DIRECT_FUNC_IMPL( \ std::forward(arg) __VA_ARGS__ std::forward(self)) \ - ___PRO_DEF_FREE_ACCESSOR_TEMPLATE( \ + ___PRO3_DEF_FREE_ACCESSOR_TEMPLATE( \ ___PRO_DEF_RHS_OP_ACCESSOR, __VA_ARGS__) \ }; @@ -2349,7 +2354,7 @@ ___PRO_DEBUG( \ #define ___PRO_DEF_LHS_ASSIGNMENT_OP_ACCESSOR(Q, SELF, ...) \ template \ struct accessor<__F, __IsDirect, __D, R(Arg) Q> { \ - ___PRO_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ + ___PRO3_GEN_DEBUG_SYMBOL_FOR_MEM_ACCESSOR(__VA_ARGS__) \ decltype(auto) __VA_ARGS__(Arg arg) Q { \ proxy_invoke<__IsDirect, __D, R(Arg) Q>(SELF, std::forward(arg)); \ if constexpr (__IsDirect) { \ @@ -2366,7 +2371,7 @@ ___PRO_DEBUG( \ proxy_invoke<__IsDirect, __D, R(Arg&) Q>(SELF, arg); \ return arg; \ } \ -___PRO_DEBUG( \ +___PRO3_DEBUG( \ accessor() noexcept { std::ignore = &_symbol_guard; } \ \ private: \ @@ -2378,20 +2383,20 @@ ___PRO_DEBUG( \ template <> \ struct operator_dispatch<#__VA_ARGS__, false> { \ template \ - ___PRO_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ - ___PRO_DIRECT_FUNC_IMPL(std::forward(self) __VA_ARGS__ \ + ___PRO3_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ + ___PRO3_DIRECT_FUNC_IMPL(std::forward(self) __VA_ARGS__ \ std::forward(arg)) \ - ___PRO_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_LHS_ASSIGNMENT_OP_ACCESSOR, \ + ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_LHS_ASSIGNMENT_OP_ACCESSOR, \ operator __VA_ARGS__) \ }; \ template <> \ struct operator_dispatch<#__VA_ARGS__, true> { \ template \ - ___PRO_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ - ___PRO_DIRECT_FUNC_IMPL( \ + ___PRO3_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) \ + ___PRO3_DIRECT_FUNC_IMPL( \ std::forward(arg) __VA_ARGS__ std::forward(self)) \ - ___PRO_DEF_FREE_ACCESSOR_TEMPLATE(___PRO_DEF_RHS_ASSIGNMENT_OP_ACCESSOR, \ - __VA_ARGS__) \ + ___PRO3_DEF_FREE_ACCESSOR_TEMPLATE( \ + ___PRO_DEF_RHS_ASSIGNMENT_OP_ACCESSOR, __VA_ARGS__) \ }; ___PRO_EXTENDED_BINARY_OP_DISPATCH_IMPL(+) @@ -2432,24 +2437,24 @@ ___PRO_BINARY_OP_DISPATCH_IMPL(->*) template <> struct operator_dispatch<"()", false> { template - ___PRO_STATIC_CALL(decltype(auto), T&& self, Args&&... args) - ___PRO_DIRECT_FUNC_IMPL( + ___PRO3_STATIC_CALL(decltype(auto), T&& self, Args&&... args) + ___PRO3_DIRECT_FUNC_IMPL( std::forward(self)(std::forward(args)...)) - ___PRO_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_LHS_ANY_OP_ACCESSOR, operator()) + ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_LHS_ANY_OP_ACCESSOR, operator()) }; template <> struct operator_dispatch<"[]", false> { #if __cpp_multidimensional_subscript >= 202110L template - ___PRO_STATIC_CALL(decltype(auto), T&& self, Args&&... args) - ___PRO_DIRECT_FUNC_IMPL( + ___PRO3_STATIC_CALL(decltype(auto), T&& self, Args&&... args) + ___PRO3_DIRECT_FUNC_IMPL( std::forward(self)[std::forward(args)...]) #else template - ___PRO_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) - ___PRO_DIRECT_FUNC_IMPL(std::forward(self)[std::forward(arg)]) + ___PRO3_STATIC_CALL(decltype(auto), T&& self, Arg&& arg) + ___PRO3_DIRECT_FUNC_IMPL(std::forward(self)[std::forward(arg)]) #endif // __cpp_multidimensional_subscript >= 202110L - ___PRO_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_LHS_ANY_OP_ACCESSOR, operator[]) + ___PRO3_DEF_MEM_ACCESSOR_TEMPLATE(___PRO_DEF_LHS_ANY_OP_ACCESSOR, operator[]) }; #undef ___PRO_ASSIGNMENT_OP_DISPATCH_IMPL @@ -2473,25 +2478,26 @@ struct operator_dispatch<"[]", false> { struct implicit_conversion_dispatch : details::cast_dispatch_base { template - ___PRO_STATIC_CALL(T&&, T&& self) noexcept { return std::forward(self); } + ___PRO3_STATIC_CALL(T&&, T&& self) noexcept { return std::forward(self); } }; struct explicit_conversion_dispatch : details::cast_dispatch_base { template - ___PRO_STATIC_CALL(auto, T&& self) noexcept + ___PRO3_STATIC_CALL(auto, T&& self) noexcept { return details::explicit_conversion_adapter{std::forward(self)}; } }; using conversion_dispatch = explicit_conversion_dispatch; class not_implemented : public std::exception { public: - char const* what() const noexcept override { return "pro::not_implemented"; } + char const* what() const noexcept override + { return "pro::v3::not_implemented"; } }; template struct weak_dispatch : D { using D::operator(); template - [[noreturn]] ___PRO_STATIC_CALL(details::wildcard, std::nullptr_t, Args&&...) + [[noreturn]] ___PRO3_STATIC_CALL(details::wildcard, std::nullptr_t, Args&&...) { ___PRO_THROW(not_implemented{}); } }; @@ -2500,8 +2506,9 @@ struct weak_dispatch : D { "Use pro::weak_dispatch<" #__D "> instead.")]] __NAME : __D { \ using __D::operator(); \ template \ - ___PRO_STATIC_CALL(decltype(auto), ::std::nullptr_t, __Args&&... __args) \ - ___PRO_DIRECT_FUNC_IMPL(__FUNC(::std::forward<__Args>(__args)...)) \ + ___PRO3_STATIC_CALL(decltype(auto), \ + ::std::nullptr_t, __Args&&... __args) \ + ___PRO3_DIRECT_FUNC_IMPL(__FUNC(::std::forward<__Args>(__args)...)) \ } } // namespace pro @@ -2509,10 +2516,11 @@ struct weak_dispatch : D { #if __STDC_HOSTED__ namespace std { -template - requires(pro::details::facade_traits::template is_invocable>) -struct formatter, CharT> { +template + requires(pro::v3::details::facade_traits::template is_invocable< + false, pro::v3::details::format_dispatch, + pro::v3::details::format_overload_t>) +struct formatter, CharT> { constexpr auto parse(basic_format_parse_context& pc) { for (auto it = pc.begin(); it != pc.end(); ++it) { if (*it == '}') { @@ -2524,12 +2532,12 @@ struct formatter, CharT> { } template - OutIt format(const pro::proxy_indirect_accessor& ia, + OutIt format(const pro::v3::proxy_indirect_accessor& ia, basic_format_context& fc) const { - auto& p = pro::access_proxy(ia); + auto& p = pro::v3::access_proxy(ia); if (!p.has_value()) { ___PRO_THROW(format_error{"null proxy"}); } - return pro::proxy_invoke>(p, spec_, fc); + return pro::v3::proxy_invoke>(p, spec_, fc); } private: @@ -2539,7 +2547,60 @@ struct formatter, CharT> { } // namespace std #endif // __STDC_HOSTED__ +// Version-less macro aliases + +#define ___PRO3_AMBIGUOUS_MACRO_DIAGNOSTIC_ASSERT(__NAME, \ + __VERSION_QUALIFIED_NAME) \ + static_assert(false, "The use of macro `" #__NAME "` is ambiguous. \ +Are multiple different versions of Proxy library included at the same time?\n\ +Note: To resolve this error: \n\ +- Either make sure that only one version of Proxy library is included within this file.\n\ +- Or use the `" #__VERSION_QUALIFIED_NAME \ + "` macro (note the `3` suffix) to explicitly \ +stick to a specific major version of the Proxy library.") + +#ifdef __msft_lib_proxy +#undef __msft_lib_proxy +#define __msft_lib_proxy \ + [] { \ + ___PRO3_AMBIGUOUS_MACRO_DIAGNOSTIC_ASSERT(__msft_lib_proxy, \ + __msft_lib_proxy3); \ + return 0L; \ + }() +#else +#define __msft_lib_proxy __msft_lib_proxy3 +#endif // __msft_lib_proxy + +#ifdef PRO_DEF_MEM_DISPATCH +#undef PRO_DEF_MEM_DISPATCH +#define PRO_DEF_MEM_DISPATCH(...) \ + ___PRO3_AMBIGUOUS_MACRO_DIAGNOSTIC_ASSERT(PRO_DEF_MEM_DISPATCH, \ + PRO3_DEF_MEM_DISPATCH) +#else +#define PRO_DEF_MEM_DISPATCH(name, ...) PRO3_DEF_MEM_DISPATCH(name, __VA_ARGS__) +#endif // PRO_DEF_MEM_DISPATCH + +#ifdef PRO_DEF_FREE_DISPATCH +#undef PRO_DEF_FREE_DISPATCH +#define PRO_DEF_FREE_DISPATCH(...) \ + ___PRO3_AMBIGUOUS_MACRO_DIAGNOSTIC_ASSERT(PRO_DEF_FREE_DISPATCH, \ + PRO3_DEF_FREE_DISPATCH) +#else +#define PRO_DEF_FREE_DISPATCH(name, ...) \ + PRO3_DEF_FREE_DISPATCH(name, __VA_ARGS__) +#endif // PRO_DEF_FREE_DISPATCH + +#ifdef PRO_DEF_FREE_AS_MEM_DISPATCH +#undef PRO_DEF_FREE_AS_MEM_DISPATCH +#define PRO_DEF_FREE_AS_MEM_DISPATCH(...) \ + ___PRO3_AMBIGUOUS_MACRO_DIAGNOSTIC_ASSERT(PRO_DEF_FREE_AS_MEM_DISPATCH, \ + PRO3_DEF_FREE_AS_MEM_DISPATCH) +#else +#define PRO_DEF_FREE_AS_MEM_DISPATCH(name, ...) \ + PRO3_DEF_FREE_AS_MEM_DISPATCH(name, __VA_ARGS__) +#endif // PRO_DEF_FREE_AS_MEM_DISPATCH + #undef ___PRO_THROW #undef ___PRO_NO_UNIQUE_ADDRESS_ATTRIBUTE -#endif // _MSFT_PROXY_ +#endif // _MSFT_PROXY3_ From 93ca993a650436a98b7732927fb1d4eda63e9607 Mon Sep 17 00:00:00 2001 From: Mingxin Wang Date: Mon, 9 Jun 2025 19:57:22 +0800 Subject: [PATCH 3/3] Fix macro --- include/proxy/v3/proxy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/proxy/v3/proxy.h b/include/proxy/v3/proxy.h index 197bd086..79f5d2c6 100644 --- a/include/proxy/v3/proxy.h +++ b/include/proxy/v3/proxy.h @@ -60,7 +60,7 @@ #define ___PRO3_DEBUG(...) __VA_ARGS__ #endif // NDEBUG -#define __msft3_lib_proxy 202505L +#define __msft_lib_proxy3 202505L namespace pro::inline v3 {