Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

Commit 0b075c7

Browse files
authored
Implement symbol guard for free functions (#202)
1 parent b61bab4 commit 0b075c7

1 file changed

Lines changed: 54 additions & 4 deletions

File tree

proxy.h

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,14 +1466,30 @@ struct operator_dispatch;
14661466
operator __VA_ARGS__) \
14671467
};
14681468

1469+
#ifdef NDEBUG
1470+
#define ___PRO_DEF_RHS_OP_ACCESSOR(Q, NE, SELF, FW_SELF, ...) \
1471+
template <class F, class C, class R, class Arg> \
1472+
struct accessor<F, C, R(Arg) Q> { \
1473+
friend R operator __VA_ARGS__ (Arg arg, SELF) NE { \
1474+
return proxy_invoke<C, R(Arg) Q>( \
1475+
access_proxy<F>(FW_SELF), std::forward<Arg>(arg)); \
1476+
} \
1477+
}
1478+
#else
14691479
#define ___PRO_DEF_RHS_OP_ACCESSOR(Q, NE, SELF, FW_SELF, ...) \
14701480
template <class F, class C, class R, class Arg> \
14711481
struct accessor<F, C, R(Arg) Q> { \
1472-
friend R __VA_ARGS__ (Arg arg, SELF) NE { \
1482+
accessor() noexcept { std::ignore = &accessor::_symbol_guard; } \
1483+
friend R operator __VA_ARGS__ (Arg arg, SELF) NE { \
14731484
return proxy_invoke<C, R(Arg) Q>( \
14741485
access_proxy<F>(FW_SELF), std::forward<Arg>(arg)); \
14751486
} \
1487+
\
1488+
private: \
1489+
static inline R _symbol_guard(Arg arg, SELF) NE \
1490+
{ return std::forward<Arg>(arg) __VA_ARGS__ FW_SELF; } \
14761491
}
1492+
#endif // NDEBUG
14771493
#define ___PRO_RHS_OP_DISPATCH_IMPL(...) \
14781494
template <> \
14791495
struct operator_dispatch<#__VA_ARGS__, true> { \
@@ -1482,7 +1498,7 @@ struct operator_dispatch;
14821498
___PRO_DIRECT_FUNC_IMPL(std::forward<Arg>(arg) __VA_ARGS__ \
14831499
std::forward<T>(self)) \
14841500
___PRO_DEF_FREE_ACCESSOR_TEMPLATE(___PRO_DEF_RHS_OP_ACCESSOR, \
1485-
operator __VA_ARGS__) \
1501+
__VA_ARGS__) \
14861502
};
14871503

14881504
#define ___PRO_EXTENDED_BINARY_OP_DISPATCH_IMPL(...) \
@@ -1507,14 +1523,30 @@ struct operator_dispatch;
15071523
} \
15081524
} \
15091525
}
1526+
#ifdef NDEBUG
1527+
#define ___PRO_DEF_RHS_ASSIGNMENT_OP_ACCESSOR(Q, NE, SELF, FW_SELF, ...) \
1528+
template <class F, class C, class R, class Arg> \
1529+
struct accessor<F, C, R(Arg&) Q> { \
1530+
friend Arg& operator __VA_ARGS__ (Arg& arg, SELF) NE { \
1531+
proxy_invoke<C, R(Arg&) Q>(access_proxy<F>(FW_SELF), arg); \
1532+
return arg; \
1533+
} \
1534+
}
1535+
#else
15101536
#define ___PRO_DEF_RHS_ASSIGNMENT_OP_ACCESSOR(Q, NE, SELF, FW_SELF, ...) \
15111537
template <class F, class C, class R, class Arg> \
15121538
struct accessor<F, C, R(Arg&) Q> { \
1513-
friend Arg& __VA_ARGS__ (Arg& arg, SELF) NE { \
1539+
accessor() noexcept { std::ignore = &accessor::_symbol_guard; } \
1540+
friend Arg& operator __VA_ARGS__ (Arg& arg, SELF) NE { \
15141541
proxy_invoke<C, R(Arg&) Q>(access_proxy<F>(FW_SELF), arg); \
15151542
return arg; \
15161543
} \
1544+
\
1545+
private: \
1546+
static inline Arg& _symbol_guard(Arg& arg, SELF) NE \
1547+
{ return arg __VA_ARGS__ FW_SELF; } \
15171548
}
1549+
#endif // NDEBUG
15181550
#define ___PRO_ASSIGNMENT_OP_DISPATCH_IMPL(...) \
15191551
template <> \
15201552
struct operator_dispatch<#__VA_ARGS__, false> { \
@@ -1532,7 +1564,7 @@ struct operator_dispatch;
15321564
___PRO_DIRECT_FUNC_IMPL(std::forward<Arg>(arg) __VA_ARGS__ \
15331565
std::forward<T>(self)) \
15341566
___PRO_DEF_FREE_ACCESSOR_TEMPLATE(___PRO_DEF_RHS_ASSIGNMENT_OP_ACCESSOR, \
1535-
operator __VA_ARGS__) \
1567+
__VA_ARGS__) \
15361568
};
15371569

15381570
___PRO_EXTENDED_BINARY_OP_DISPATCH_IMPL(+)
@@ -1664,6 +1696,7 @@ struct conversion_dispatch {
16641696
#define PRO_DEF_MEM_DISPATCH(__NAME, ...) \
16651697
___PRO_EXPAND_MACRO(___PRO_DEF_MEM_DISPATCH, __NAME, __VA_ARGS__)
16661698

1699+
#ifdef NDEBUG
16671700
#define ___PRO_DEF_FREE_ACCESSOR(__Q, __NE, __SELF, __FW_SELF, ...) \
16681701
template <class __F, class __C, class __R, class... __Args> \
16691702
struct accessor<__F, __C, __R(__Args...) __Q> { \
@@ -1673,6 +1706,23 @@ struct conversion_dispatch {
16731706
::std::forward<__Args>(__args)...); \
16741707
} \
16751708
}
1709+
#else
1710+
#define ___PRO_DEF_FREE_ACCESSOR(__Q, __NE, __SELF, __FW_SELF, ...) \
1711+
template <class __F, class __C, class __R, class... __Args> \
1712+
struct accessor<__F, __C, __R(__Args...) __Q> { \
1713+
accessor() noexcept { ::std::ignore = &accessor::_symbol_guard; } \
1714+
friend __R __VA_ARGS__(__SELF, __Args... __args) __NE { \
1715+
return ::pro::proxy_invoke<__C, __R(__Args...) __Q>( \
1716+
::pro::access_proxy<__F>(__FW_SELF), \
1717+
::std::forward<__Args>(__args)...); \
1718+
} \
1719+
\
1720+
private: \
1721+
static inline __R _symbol_guard(__SELF, __Args... __args) __NE { \
1722+
return __VA_ARGS__(__FW_SELF, ::std::forward<__Args>(__args)...); \
1723+
} \
1724+
}
1725+
#endif // NDEBUG
16761726
#define ___PRO_DEF_FREE_DISPATCH_IMPL(__NAME, __FUNC, __FNAME) \
16771727
struct __NAME { \
16781728
template <class __T, class... __Args> \

0 commit comments

Comments
 (0)