diff --git a/src/core_test/utility/exposer.h b/src/core_test/utility/exposer.h index f959df2..875ee1b 100644 --- a/src/core_test/utility/exposer.h +++ b/src/core_test/utility/exposer.h @@ -15,25 +15,76 @@ struct Exposer { #define COMBINE_IMPL(x, y) x##y -#define COMBINE(x, y) COMBINE_IMPL(x, y) - -#define UNIQUE_TAG COMBINE(Tag, __COUNTER__) - -#define FORCE_ACCESS_VAR_IMPL(Class, Type, Member, Tag) \ - namespace exposer { \ - struct Tag {}; \ - template struct Exposer; \ - constexpr Type Class::* fetch(Tag); \ - constexpr Type& Class##_##Member(Class &c) { \ - return c.*fetch(Tag{}); \ - } \ - constexpr const Type& Class##_##Member(const Class &c) { \ - return c.*fetch(Tag{}); \ - } \ - constexpr Type Class##_##Member(Class &&c) { \ - return c.*fetch(Tag{}); \ - } \ - } - -#define FORCE_ACCESS_VAR(Class, Type, Member) \ - FORCE_ACCESS_VAR_IMPL(Class, Type, Member, UNIQUE_TAG) +#define HELPER(x) COMBINE_IMPL(Helper_, x) + +#define PROTO(x) COMBINE_IMPL(Proto_, x) + +#define FORCE_ACCESS_VAR_IMPL(Class, Type, Member, Tag) \ + struct HELPER(Tag) {}; \ + template struct Exposer; \ + constexpr Type Class::* fetch(HELPER(Tag)); \ + constexpr Type Class##_##Member(Class &&c) { \ + return c.*fetch(HELPER(Tag){}); \ + } \ + constexpr Type& Class##_##Member(Class &c) { \ + return c.*fetch(HELPER(Tag){}); \ + } \ + constexpr const Type& Class##_##Member(const Class &c) { \ + return c.*fetch(HELPER(Tag){}); \ + } + +#define FORCE_ACCESS_CONST_VAR_IMPL(Class, Type, Member, Tag) \ + struct HELPER(Tag) {}; \ + template struct Exposer; \ + constexpr const Type Class::* fetch(HELPER(Tag)); \ + constexpr Type Class##_##Member(Class &&c) { \ + return c.*fetch(HELPER(Tag){}); \ + } \ + constexpr const Type& Class##_##Member(Class &c) { \ + return c.*fetch(HELPER(Tag){}); \ + } \ + constexpr const Type& Class##_##Member(const Class &c) { \ + return c.*fetch(HELPER(Tag){}); \ + } + +#define FORCE_ACCESS_FUNC_IMPL(Class, Proto, Member, Tag) \ + struct HELPER(Tag) {}; \ + using PROTO(Tag) = Proto; \ + template struct Exposer; \ + constexpr PROTO(Tag) Class::* fetch(HELPER(Tag)); \ + template \ + requires std::is_same_v, Class> \ + constexpr decltype(auto) Class##_##Member(C &&c, Args &&...args) { \ + return (std::forward(c).*fetch(HELPER(Tag){}))(std::forward(args)...); \ + } + +#define FORCE_ACCESS_CONST_FUNC_IMPL(Class, Proto, Member, Tag) \ + struct HELPER(Tag) {}; \ + using PROTO(Tag) = Proto const; \ + template struct Exposer; \ + constexpr PROTO(Tag) Demo::* fetch(HELPER(Tag)); \ + template \ + requires std::is_same_v>, Class> \ + constexpr decltype(auto) Class##_##Member(C &&c, Args &&...args) { \ + return (std::forward(c).*fetch(HELPER(Tag){}))(std::forward(args)...); \ + } + +#define FORCE_ACCESS_VAR(Class, Type, Member) \ + namespace exposer { \ + FORCE_ACCESS_VAR_IMPL(Class, Type, Member, __COUNTER__) \ + } + +#define FORCE_ACCESS_CONST_VAR(Class, Type, Member) \ + namespace exposer { \ + FORCE_ACCESS_CONST_VAR_IMPL(Class, Type, Member, __COUNTER__) \ + } + +#define FORCE_ACCESS_FUNC(Class, Proto, Member) \ + namespace exposer { \ + FORCE_ACCESS_FUNC_IMPL(Class, Proto, Member, __COUNTER__) \ + } + +#define FORCE_ACCESS_CONST_FUNC(Class, Proto, Member) \ + namespace exposer { \ + FORCE_ACCESS_CONST_FUNC_IMPL(Class, Proto, Member, __COUNTER__) \ + }