Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 44 additions & 44 deletions proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,13 @@ using facade_builder = details::facade_builder_impl<std::tuple<>, 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__; }
Expand All @@ -1049,7 +1056,7 @@ using facade_builder = details::facade_builder_impl<std::tuple<>, 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 <class... __Args> \
Expand All @@ -1059,15 +1066,24 @@ using facade_builder = details::facade_builder_impl<std::tuple<>, std::tuple<>,
template <class __P> \
struct accessor { \
template <class... __Args> \
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<const __P&, \
__Args...>>(*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 <class... __Args> \
Expand All @@ -1083,20 +1099,15 @@ using facade_builder = details::facade_builder_impl<std::tuple<>, 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 {

Expand Down Expand Up @@ -1354,7 +1365,7 @@ using op_dispatch_accessor = typename op_dispatch_traits<SIGN, POS>

} // 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< \
Expand All @@ -1364,6 +1375,18 @@ using op_dispatch_accessor = typename op_dispatch_traits<SIGN, POS>
__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 { \
Expand All @@ -1379,36 +1402,13 @@ using op_dispatch_accessor = typename op_dispatch_traits<SIGN, POS>
}; \
__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

Expand Down
2 changes: 1 addition & 1 deletion tests/freestanding/proxy_freestanding_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<FreeGetHash, unsigned()>
::build {};
Expand Down
21 changes: 13 additions & 8 deletions tests/proxy_invocation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ namespace spec {

PRO_DEF_OPERATOR_DISPATCH(OpCall, "()");

template <class... Os>
struct MovableCallable : pro::facade_builder
::add_convention<OpCall, Os...>
::build {};

template <class... Os>
struct Callable : pro::facade_builder
::support_copy<pro::constraint_level::nontrivial>
::add_convention<OpCall, Os...>
::add_facade<MovableCallable<Os...>>
::build {};

struct Wildcard {
Expand All @@ -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 <class... Os>
struct WeakCallable : pro::facade_builder
::support_copy<pro::constraint_level::nontrivial>
::add_convention<WeakOpCall, Os...>
::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 <class T>
struct Iterable : pro::facade_builder
Expand All @@ -57,15 +62,15 @@ pro::proxy<Container<T>> AppendImpl(C& container, T&& v) {
return &container;
}

PRO_DEF_FREE_DISPATCH(FreeAppend, Append, AppendImpl);
PRO_DEF_FREE_DISPATCH(FreeAppend, AppendImpl, Append);

template <class T>
struct Container : pro::facade_builder
::add_facade<Iterable<T>>
::template add_convention<FreeAppend, pro::proxy<Container<T>>(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<MemAtWeak, std::string(int)>
Expand All @@ -80,7 +85,7 @@ pro::proxy<F> LockImpl(const std::weak_ptr<T>& p) {
return nullptr;
}
template <class F>
PRO_DEF_FREE_DISPATCH(FreeLock, Lock, LockImpl<F>);
PRO_DEF_FREE_DISPATCH(FreeLock, LockImpl<F>, Lock);

template <class F>
struct Weak : pro::facade_builder
Expand All @@ -92,7 +97,7 @@ template <class F, class T>
auto GetWeakImpl(const std::shared_ptr<T>& p) { return pro::make_proxy<Weak<F>, std::weak_ptr<T>>(p); }

template <class F>
PRO_DEF_FREE_DISPATCH_WITH_DEFAULT(FreeGetWeak, GetWeak, GetWeakImpl<F>, std::nullptr_t);
PRO_DEF_FREE_DISPATCH(FreeGetWeak, GetWeakImpl<F>, GetWeak, std::nullptr_t);

struct SharedStringable : pro::facade_builder
::add_facade<utils::spec::Stringable>
Expand Down
2 changes: 1 addition & 1 deletion tests/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<FreeToString, std::string()>
Expand Down