diff --git a/proxy.h b/proxy.h index 6d353634..6420f7dc 100644 --- a/proxy.h +++ b/proxy.h @@ -1040,6 +1040,13 @@ using facade_builder = details::facade_builder_impl, std::tuple<>, .relocatability = details::invalid_cl, .destructibility = details::invalid_cl}>; +#define ___PRO_EXPAND_IMPL(__X) __X +#define ___PRO_EXPAND_MACRO_IMPL(__MACRO, __1, __2, __3, __4, __NAME, ...) \ + __MACRO ## _ ## __NAME +#define ___PRO_EXPAND_MACRO(__MACRO, ...) \ + ___PRO_EXPAND_IMPL(___PRO_EXPAND_MACRO_IMPL( \ + __MACRO, __VA_ARGS__, 4, 3, 2)(__VA_ARGS__)) + #define ___PRO_DIRECT_FUNC_IMPL(...) \ noexcept(noexcept(__VA_ARGS__)) requires(requires { __VA_ARGS__; }) \ { return __VA_ARGS__; } @@ -1049,7 +1056,7 @@ using facade_builder = details::facade_builder_impl, std::tuple<>, decltype(auto) operator()(::std::nullptr_t, __Args&&... __args) \ ___PRO_DIRECT_FUNC_IMPL(__DEFFUNC(::std::forward<__Args>(__args)...)) -#define ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, ...) \ +#define ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC, __FNAME, ...) \ struct __NAME { \ using __name = __NAME; \ template \ @@ -1059,15 +1066,24 @@ using facade_builder = details::facade_builder_impl, std::tuple<>, template \ struct accessor { \ template \ - decltype(auto) __FUNC(__Args&&... __args) const \ + decltype(auto) __FNAME(__Args&&... __args) const \ ___PRO_DIRECT_FUNC_IMPL(::pro::proxy_invoke<__name>( \ static_cast<::pro::details::lazy_eval_t>(*this), ::std::forward<__Args>(__args)...)) \ }; \ __VA_ARGS__ \ } +#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_4(__NAME, __FUNC, __FNAME, __DEFFUNC) \ + ___PRO_DEF_MEM_DISPATCH_IMPL( \ + __NAME, __FUNC, __FNAME, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) +#define PRO_DEF_MEM_DISPATCH(__NAME, ...) \ + ___PRO_EXPAND_MACRO(___PRO_DEF_MEM_DISPATCH, __NAME, __VA_ARGS__) -#define ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FNAME, __FUNC, ...) \ +#define ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME, ...) \ struct __NAME { \ using __name = __NAME; \ template \ @@ -1083,20 +1099,15 @@ using facade_builder = details::facade_builder_impl, std::tuple<>, }; \ __VA_ARGS__ \ } - -#define PRO_DEF_MEM_DISPATCH(__NAME, __FUNC) \ - ___PRO_DEF_MEM_DISPATCH_IMPL(__NAME, __FUNC) - -#define PRO_DEF_MEM_DISPATCH_WITH_DEFAULT(__NAME, __FUNC, __DEFFUNC) \ - ___PRO_DEF_MEM_DISPATCH_IMPL( \ - __NAME, __FUNC, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) - -#define PRO_DEF_FREE_DISPATCH(__NAME, __FNAME, __FUNC) \ - ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FNAME, __FUNC) - -#define PRO_DEF_FREE_DISPATCH_WITH_DEFAULT(__NAME, __FNAME, __FUNC, __DEFFUNC) \ +#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_4(__NAME, __FUNC, __FNAME, __DEFFUNC) \ ___PRO_DEF_FREE_DISPATCH_IMPL( \ - __NAME, __FNAME, __FUNC, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) + __NAME, __FUNC, __FNAME, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) +#define PRO_DEF_FREE_DISPATCH(__NAME, ...) \ + ___PRO_EXPAND_MACRO(___PRO_DEF_FREE_DISPATCH, __NAME, __VA_ARGS__) namespace details { @@ -1354,7 +1365,7 @@ using op_dispatch_accessor = typename op_dispatch_traits } // namespace details -#define ___PRO_DEF_OPERATOR_DISPATCH_IMPL(__NAME, __SIGN, __POS, ...) \ +#define ___PRO_DEF_OPERATOR_DISPATCH_IMPL(__NAME, __POS, __SIGN, ...) \ struct __NAME : ::pro::details::op_dispatch_base< \ __SIGN, ::pro::details::sign_pos_type::__POS> { \ using ::pro::details::op_dispatch_base< \ @@ -1364,6 +1375,18 @@ using op_dispatch_accessor = typename op_dispatch_traits __SIGN, ::pro::details::sign_pos_type::__POS, __NAME, __P>; \ __VA_ARGS__ \ }; +#define ___PRO_DEF_OPERATOR_DISPATCH_3(__NAME, __POS, __SIGN) \ + ___PRO_DEF_OPERATOR_DISPATCH_IMPL(__NAME, __POS, __SIGN) +#define ___PRO_DEF_OPERATOR_DISPATCH_4(__NAME, __POS, __SIGN, __DEFFUNC) \ + ___PRO_DEF_OPERATOR_DISPATCH_IMPL( \ + __NAME, __POS, __SIGN, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) +#define PRO_DEF_OPERATOR_DISPATCH(__NAME, ...) \ + ___PRO_EXPAND_MACRO(___PRO_DEF_OPERATOR_DISPATCH, __NAME, none, __VA_ARGS__) +#define PRO_DEF_PREFIX_OPERATOR_DISPATCH(__NAME, ...) \ + ___PRO_EXPAND_MACRO(___PRO_DEF_OPERATOR_DISPATCH, __NAME, left, __VA_ARGS__) +#define PRO_DEF_POSTFIX_OPERATOR_DISPATCH(__NAME, ...) \ + ___PRO_EXPAND_MACRO( \ + ___PRO_DEF_OPERATOR_DISPATCH, __NAME, right, __VA_ARGS__) #define ___PRO_DEF_CONVERTION_DISPATCH_IMPL(__NAME, __T, ...) \ struct __NAME { \ @@ -1379,36 +1402,13 @@ using op_dispatch_accessor = typename op_dispatch_traits }; \ __VA_ARGS__ \ } - -#define PRO_DEF_OPERATOR_DISPATCH(__NAME, __SIGN) \ - ___PRO_DEF_OPERATOR_DISPATCH_IMPL(__NAME, __SIGN, none) - -#define PRO_DEF_OPERATOR_DISPATCH_WITH_DEFAULT(__NAME, __SIGN, __DEFFUNC) \ - ___PRO_DEF_OPERATOR_DISPATCH_IMPL( \ - __NAME, __SIGN, none, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) - -#define PRO_DEF_PREFIX_OPERATOR_DISPATCH(__NAME, __SIGN) \ - ___PRO_DEF_OPERATOR_DISPATCH_IMPL(__NAME, __SIGN, left) - -#define PRO_DEF_PREFIX_OPERATOR_DISPATCH_WITH_DEFAULT( \ - __NAME, __SIGN, __DEFFUNC) \ - ___PRO_DEF_OPERATOR_DISPATCH_IMPL( \ - __NAME, __SIGN, left, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) - -#define PRO_DEF_POSTFIX_OPERATOR_DISPATCH(__NAME, __SIGN) \ - ___PRO_DEF_OPERATOR_DISPATCH_IMPL(__NAME, __SIGN, right) - -#define PRO_DEF_POSTFIX_OPERATOR_DISPATCH_WITH_DEFAULT( \ - __NAME, __SIGN, __DEFFUNC) \ - ___PRO_DEF_OPERATOR_DISPATCH_IMPL( \ - __NAME, __SIGN, right, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) - -#define PRO_DEF_CONVERTION_DISPATCH(__NAME, __T) \ +#define ___PRO_DEF_CONVERTION_DISPATCH_2(__NAME, __T) \ ___PRO_DEF_CONVERTION_DISPATCH_IMPL(__NAME, __T) - -#define PRO_DEF_CONVERTION_DISPATCH_WITH_DEFAULT(__NAME, __T, __DEFFUNC) \ +#define ___PRO_DEF_CONVERTION_DISPATCH_3(__NAME, __T, __DEFFUNC) \ ___PRO_DEF_CONVERTION_DISPATCH_IMPL( \ __NAME, __T, ___PRO_DEFAULT_DISPATCH_CALL_IMPL(__DEFFUNC)) +#define PRO_DEF_CONVERTION_DISPATCH(__NAME, ...) \ + ___PRO_EXPAND_MACRO(___PRO_DEF_CONVERTION_DISPATCH, __NAME, __VA_ARGS__) } // namespace pro diff --git a/tests/freestanding/proxy_freestanding_tests.cpp b/tests/freestanding/proxy_freestanding_tests.cpp index c315979f..10a609f2 100644 --- a/tests/freestanding/proxy_freestanding_tests.cpp +++ b/tests/freestanding/proxy_freestanding_tests.cpp @@ -17,7 +17,7 @@ unsigned GetDefaultHash() { return -1; } namespace spec { -PRO_DEF_FREE_DISPATCH_WITH_DEFAULT(FreeGetHash, GetHash, ::GetHash, ::GetDefaultHash); +PRO_DEF_FREE_DISPATCH(FreeGetHash, ::GetHash, GetHash, ::GetDefaultHash); struct Hashable : pro::facade_builder ::add_convention ::build {}; diff --git a/tests/proxy_invocation_tests.cpp b/tests/proxy_invocation_tests.cpp index a5196d60..7920fcf7 100644 --- a/tests/proxy_invocation_tests.cpp +++ b/tests/proxy_invocation_tests.cpp @@ -19,10 +19,15 @@ namespace spec { PRO_DEF_OPERATOR_DISPATCH(OpCall, "()"); +template +struct MovableCallable : pro::facade_builder + ::add_convention + ::build {}; + template struct Callable : pro::facade_builder ::support_copy - ::add_convention + ::add_facade> ::build {}; struct Wildcard { @@ -32,15 +37,15 @@ struct Wildcard { Wildcard NotImplemented(auto&&...) { throw std::runtime_error{ "Not implemented!" }; } -PRO_DEF_OPERATOR_DISPATCH_WITH_DEFAULT(WeakOpCall, "()", NotImplemented); +PRO_DEF_OPERATOR_DISPATCH(WeakOpCall, "()", NotImplemented); template struct WeakCallable : pro::facade_builder ::support_copy ::add_convention ::build {}; -PRO_DEF_FREE_DISPATCH(FreeSize, Size, std::ranges::size); -PRO_DEF_FREE_DISPATCH(FreeForEach, ForEach, std::ranges::for_each); +PRO_DEF_FREE_DISPATCH(FreeSize, std::ranges::size, Size); +PRO_DEF_FREE_DISPATCH(FreeForEach, std::ranges::for_each, ForEach); template struct Iterable : pro::facade_builder @@ -57,7 +62,7 @@ pro::proxy> AppendImpl(C& container, T&& v) { return &container; } -PRO_DEF_FREE_DISPATCH(FreeAppend, Append, AppendImpl); +PRO_DEF_FREE_DISPATCH(FreeAppend, AppendImpl, Append); template struct Container : pro::facade_builder @@ -65,7 +70,7 @@ struct Container : pro::facade_builder ::template add_convention>(T)> ::build {}; -PRO_DEF_MEM_DISPATCH_WITH_DEFAULT(MemAtWeak, at, NotImplemented); +PRO_DEF_MEM_DISPATCH(MemAtWeak, at, at, NotImplemented); struct ResourceDictionary : pro::facade_builder ::add_convention @@ -80,7 +85,7 @@ pro::proxy LockImpl(const std::weak_ptr& p) { return nullptr; } template -PRO_DEF_FREE_DISPATCH(FreeLock, Lock, LockImpl); +PRO_DEF_FREE_DISPATCH(FreeLock, LockImpl, Lock); template struct Weak : pro::facade_builder @@ -92,7 +97,7 @@ template auto GetWeakImpl(const std::shared_ptr& p) { return pro::make_proxy, std::weak_ptr>(p); } template -PRO_DEF_FREE_DISPATCH_WITH_DEFAULT(FreeGetWeak, GetWeak, GetWeakImpl, std::nullptr_t); +PRO_DEF_FREE_DISPATCH(FreeGetWeak, GetWeakImpl, GetWeak, std::nullptr_t); struct SharedStringable : pro::facade_builder ::add_facade diff --git a/tests/utils.h b/tests/utils.h index 908745ce..127c36a9 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -83,7 +83,7 @@ class LifetimeTracker { namespace spec { using std::to_string; -PRO_DEF_FREE_DISPATCH(FreeToString, ToString, to_string); +PRO_DEF_FREE_DISPATCH(FreeToString, to_string, ToString); struct Stringable : pro::facade_builder ::add_convention