- No need to modify the target class
- No need to overwrite access specifiers with macros
- Not using dirty pointer-offset, making it more flexible on changes.
- Header-only
- Compile-time traits, zero runtime overhead.
- Only requires the name of the class and member(member type NOT required!)
- Can be useful when testing private/protected members or functions.
- C++14 or higher
Compiler | Minimum version |
---|---|
gcc | 6.0 |
clang | 8.0 |
MSVC | 19.14(below not tested) |
- Does not work on template type members.
- Does not work on overloaded functions.
Whole example can be found here
#include <iostream>
#include "access/access.hpp"
struct foo {
private:
std::string name = "hello";
int age = 27;
void print() {}
};
// Tag will be used when accessing private/protected/public data.
// One tag coresponds to one member of a class.
// After the tag is named, it has to be enabled using access::Accessor
using tag_foo_name = access::Tag<class foo_name>;
template struct access::Accessor<tag_foo_name, foo, decltype(&foo::name), &foo::name>;
int main() {
foo f;
// peek hidden data
std::cout << access::get<tag_foo_name>(f) << '\n'; // "hello"
// steal hidden data
access::get<tag_foo_name>(f) = "lupin";
std::cout << access::get<tag_foo_name>(f) << '\n'; // "lupin"
}
#include <iostream>
#include "access/access.hpp"
struct foo {
private:
std::string name = "hello";
int age = 27;
void print() {}
};
// simplified using macro
ACCESS_CREATE_TAG(my_tag_123, foo, age);
ACCESS_CREATE_UNIQUE_TAG(foo, age);
int main() {
foo f;
auto a = access::get<my_tag_123>(f); // named tag access
auto b = access::get<ACCESS_GET_UNIQUE_TAG(foo, age)>(h); // unnamed tag(unique) access
}
#include "access/access.hpp"
struct foo {
private:
std::string name = "hello";
int age = 27;
void print() {}
};
ACCESS_CREATE_TAG(tag_foo_print, foo, print);
int main() {
foo f;
// call hidden function
access::call<tag_foo_print>(f); // call directly
(f.*access::get<tag_foo_print>(f))(); // call manually after getting its pointer
}
#include "access/access.hpp"
struct foo {
private:
std::string name = "hello";
int age = 27;
void print() {}
};
ACCESS_CREATE_TAG(tag_foo_age, foo, print);
int main() {
foo f;
// get type of hidden data
static_assert(std::is_same<access::Type_t<tag_foo_age>, int>::value, "");
}