Last active
March 16, 2023 21:06
-
-
Save schaumb/38006411a6daf9a1374a391d6941761c to your computer and use it in GitHub Desktop.
access private c++17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ACCESS_PRIVATE_CPP17 | |
#define ACCESS_PRIVATE_CPP17 | |
#include <functional> | |
#define ACCESS_PRIVATE_IMPL(CLASS, NAME, CASTER, TYPE) \ | |
namespace { \ | |
namespace access_tag::CLASS {\ | |
template<class T>\ | |
struct NAME; \ | |
}\ | |
namespace private_access_detail { \ | |
template<class T> \ | |
using identity = T;\ | |
template<typename TagType, typename ...>\ | |
struct private_access_get;\ | |
\ | |
template<typename ...Ts> \ | |
struct private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...> {\ | |
friend constexpr auto getter(private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...>);\ | |
static constexpr auto get() {\ | |
return getter(private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...>{});\ | |
}\ | |
};\ | |
\ | |
template <auto PtrValue, typename TagType, typename ...>\ | |
struct private_access;\ | |
\ | |
template <auto PtrValue, typename ...Ts>\ | |
struct private_access<PtrValue, access_tag::CLASS::NAME<TYPE>, Ts...> \ | |
: private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...> {\ | |
friend constexpr auto getter(private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...>) { return PtrValue; }\ | |
};\ | |
}\ | |
template struct private_access_detail::private_access<CASTER(CLASS, TYPE, &CLASS::NAME), access_tag::CLASS::NAME<TYPE>>; \ | |
namespace access::CLASS {\ | |
template<class Obj, class ...Args>\ | |
constexpr static auto NAME(Obj&& obj, Args&& ...args)\ | |
-> std::invoke_result_t<\ | |
decltype(private_access_detail::private_access_get<access_tag::CLASS::NAME<TYPE>>::get()),\ | |
Obj, Args...\ | |
> {\ | |
return std::invoke(private_access_detail::private_access_get<access_tag::CLASS::NAME<TYPE>>::get(),\ | |
std::forward<Obj>(obj), std::forward<Args>(args)...);\ | |
} \ | |
}\ | |
} | |
#define IDENTITY(CLASS, TYPE, X) X | |
#define ACCESS_PRIVATE(CLASS, NAME) ACCESS_PRIVATE_IMPL(CLASS, NAME, IDENTITY, void) | |
#define CASTED(CLASS, TYPE, X) static_cast<private_access_detail::identity<TYPE> CLASS::*>(X) | |
#define ACCESS_PRIVATE_OVERLOADED(CLASS, NAME, OVERLOAD) ACCESS_PRIVATE_IMPL(CLASS, NAME, CASTED, OVERLOAD) | |
/* | |
Usage: | |
class Class { | |
int member; | |
void f() {} | |
void fun(int) {} | |
void fun(double) {} | |
}; | |
... | |
ACCESS_PRIVATE(Class, member) | |
ACCESS_PRIVATE(Class, f) | |
ACCESS_PRIVATE_OVERLOADED(Class, fun, void(int)) | |
ACCESS_PRIVATE_OVERLOADED(Class, fun, void(double)) | |
... | |
void any_fun() { | |
Class c; | |
[[maybe_unused]] int& mem = access::Class::member(c); | |
access::Class::f(c); | |
access::Class::fun(c, 5); | |
access::Class::fun(c, 5.4); | |
} | |
*/ | |
#endif // ACCESS_PRIVATE_CPP17 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment