Skip to content

Instantly share code, notes, and snippets.

@tylorr
Last active December 25, 2015 19:59
Show Gist options
  • Save tylorr/7031822 to your computer and use it in GitHub Desktop.
Save tylorr/7031822 to your computer and use it in GitHub Desktop.
struct binding_t {
typedef void(*invoke_t)(void* buffer);
typedef void(*copy_t)(void* dest, const void* source);
typedef void(*destruct_t)(void* buffer);
invoke_t invoke;
copy_t copy;
destruct_t destruct;
constexpr binding_t(invoke_t invoke, copy_t copy, destruct_t destruct) :
invoke(invoke), copy(copy), destruct(destruct) {}
};
template <typename TYPE>
void invoke(void* buffer) {
(*static_cast<TYPE*>(buffer))();
}
template <typename TYPE>
void copy(void* dest, const void* source) {
new (static_cast<TYPE*>(dest)) TYPE(*static_cast<const TYPE*>(source));
}
template <typename TYPE>
void destruct(void* buffer) {
static_cast<TYPE*>(buffer)->~TYPE();
}
template <typename TYPE>
struct binding_wrapper {
static constexpr binding_t binding{invoke<TYPE>, copy<TYPE>, destruct<TYPE>};
};
template<typename TYPE>
constexpr binding_t binding_wrapper<TYPE>::binding;
template<typename TYPE>
struct function {
union {
double alignme;
char buffer[sizeof(void*) * 3];
};
function() { }
function(const TYPE& bind) {
binding_wrapper<TYPE>::binding.copy(buffer, &bind);
}
function(const function &rhs) {
binding_wrapper<TYPE>::binding.copy(buffer, rhs.buffer);
}
~function() {
binding_wrapper<TYPE>::binding.destruct(buffer);
}
function &operator=(const function &rhs) {
if (this != &rhs) {
binding_wrapper<TYPE>::binding.destruct(buffer);
binding_wrapper<TYPE>::binding.copy(buffer, rhs.buffer);
}
return *this;
}
void operator()() {
binding_wrapper<TYPE>::binding.invoke(buffer);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment