Skip to content

Instantly share code, notes, and snippets.

@lambdageek
Created September 25, 2018 18:54
Show Gist options
  • Save lambdageek/30e8c0ae162d061742b3a2a0664b944f to your computer and use it in GitHub Desktop.
Save lambdageek/30e8c0ae162d061742b3a2a0664b944f to your computer and use it in GitHub Desktop.
Ugly pointer to managed
#include <type_traits>
namespace mono {
namespace traits {
/// mono::traits::Managed<T>::value is true if T is a managed type.
/// In that case mono::traits::Managed<T>::type is defined to be T
template<typename T>
struct Managed {
// typedef typename T type;
static constexpr bool value = false;
};
}
namespace managed {
struct MonoObject {
void* vtable;
};
struct MonoLink : public MonoObject {
MonoLink *next;
int i;
};
} // namespace mono::managed
template<>
struct traits::Managed<managed::MonoObject> {
typedef managed::MonoObject type;
static constexpr bool value = true;
};
template<>
struct traits::Managed<managed::MonoLink> {
typedef managed::MonoLink type;
static constexpr bool value = true;
};
namespace handle {
template<typename T>
struct handle {
private:
T* ptr;
public:
explicit handle (T * p) : ptr (p) {}
~handle () {}
handle (const handle<T> & other) : ptr (other.ptr) {}
handle (handle<T> && other) : ptr (other.ptr) {}
handle<T>& operator= (const handle<T>& other) {
ptr = other.ptr;
return *this;
}
handle<T>& operator= (handle<T> && other) {
ptr = other.ptr;
return *this;
}
operator bool () {
return !!ptr;
}
// if managed, return a handle
template<typename U, typename R>
typename std::enable_if<traits::Managed<R>::value, const handle<R> >::type
get (R* U::* member) const {
return handle (ptr->*member);
}
// fallback if not a managed type
template<typename U, typename R>
const R
get (R U::* member) const {
return (ptr->*member);
}
};
}
} // namespace mono
using namespace mono::handle;
using namespace mono::managed;
void *foo (handle<MonoLink> h)
{
if (h) {
return foo (h.get (&MonoLink::next));
}
return nullptr;
}
int bar (handle<MonoLink> h)
{
if (h) {
return h.get (&MonoLink::i);
} else
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment