Skip to content

Instantly share code, notes, and snippets.

@ming4883
Last active January 15, 2019 01:29
Show Gist options
  • Save ming4883/b5b64daecef97474d8ca48ab9722e68b to your computer and use it in GitHub Desktop.
Save ming4883/b5b64daecef97474d8ca48ab9722e68b to your computer and use it in GitHub Desktop.
#include <iostream>
template<typename Owner, typename MemType>
struct Attr {
typedef int Owner::*MemPtr;
MemPtr ptr;
Attr() {}
void Bind(MemPtr memptr) {
ptr = memptr;
}
Attr(const Attr& attr) {
ptr = attr.ptr;
}
void SetValue(Owner& inst, const MemType& val) {
inst.*ptr = val;
}
const MemType& GetValue(const Owner& inst) const {
return inst.*ptr;
}
};
template<class T>
struct GetMemPtrDataType { typedef T type; };
template<class Parent, class T>
struct GetMemPtrDataType<T Parent::*> { typedef T type; };
template<class T>
struct GetMemPtrOwnerType { typedef T type; };
template<class Parent, class T>
struct GetMemPtrOwnerType<T Parent::*> { typedef Parent type; };
template <typename MP>
auto MakeAttr() {
return Attr<
typename GetMemPtrOwnerType<MP>::type,
typename GetMemPtrDataType<MP>::type
>();
}
template <typename M>
auto MakeIntAttr() {
return Attr<M, int>();
}
class Magic {
public:
int a, b;
Magic() : a(0), b(0) {
}
};
int main() {
auto attr1 = MakeAttr<decltype(&Magic::a)>();
auto attr2 = MakeIntAttr<Magic>();
Magic m;
std::cout << "BEFORE: " << m.a << ", " << m.b << std::endl;
attr1.Bind(&Magic::a);
attr1.SetValue(m, 10);
attr2.Bind(&Magic::b);
attr2.SetValue(m, 20);
std::cout << "AFTER: " << m.a << ", " << m.b << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment