Skip to content

Instantly share code, notes, and snippets.

@paulgessinger
Last active February 6, 2023 16:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulgessinger/0909bd29a8068b770f969e08d196ab7f to your computer and use it in GitHub Desktop.
Save paulgessinger/0909bd29a8068b770f969e08d196ab7f to your computer and use it in GitHub Desktop.
#include <vector>
#include <iostream>
#include <string_view>
#include <memory>
struct A{
static constexpr auto name() { return std::string_view{"A"};}
};
struct B{
static constexpr auto name() { return std::string_view{"B"};}
};
struct C{
static constexpr auto name() { return std::string_view{"C"};}
};
using handler_type = void (*)(void*, size_t i);
using deleter_type = void (*)(void*);
template <typename T>
void handler(std::vector<T>& v, size_t i) {
std::cout << "handler for " << T::name() << ", index " << i << std::endl;
}
template <>
void handler<A>(std::vector<A>& v, size_t i) {
std::cout << "I AM THE A HANDLER " << i << std::endl;
}
struct ControlBlock {
void* vector{nullptr};
handler_type handler{nullptr};
deleter_type deleter{nullptr};
~ControlBlock() {
deleter(vector);
}
};
int main() {
std::vector<std::unique_ptr<ControlBlock>> blocks;
auto register_type = [&](auto t) {
using T = std::decay_t<decltype(t)>;
auto& cb = *blocks.emplace_back(std::make_unique<ControlBlock>());
cb.vector = new std::vector<T>();
cb.handler = [](void* p, size_t i) {
handler<T>(*reinterpret_cast<std::vector<T>*>(p), i);
};
cb.deleter = [](void* p) {
auto* c = reinterpret_cast<std::vector<T>*>(p);
delete c;
};
};
register_type(A{});
register_type(B{});
register_type(C{});
auto handle = [&](size_t tidx, size_t elem) {
auto& cb = *blocks.at(tidx);
cb.handler(&cb.vector, elem);
};
handle(0, 0);
handle(1, 0);
handle(2, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment