#include <iostream>
struct shared_buffer {};
shared_buffer do_pack(int arg);
shared_buffer do_pack(double arg);
struct foo {
friend shared_buffer do_pack(foo const& arg);
};
struct somestruct {
template<typename... Args>
shared_buffer pack(const Args&... args) {
// convert arg pack to array of pack functions and arguments
arg_pack_fn fns[] = { &wrap_do_pack<Args>... };
void const* data[] = { std::addressof(args)... };
return pack2(fns, data, sizeof...(Args));
}
private:
using arg_pack_fn = shared_buffer (*)(void const* arg);
// actual do_pack for each arg type
template<typename T>
static shared_buffer wrap_do_pack(void const* arg) {
return do_pack(*static_cast<T const*>(arg));
}
shared_buffer pack2(arg_pack_fn pack_fns[], void const* args[], size_t count);
};
// implementation in .cpp
shared_buffer do_pack(int arg) {
std::cout << arg << ' ';
}
shared_buffer do_pack(double arg) {
std::cout << arg << ' ';
}
shared_buffer do_pack(foo const& arg) {
std::cout << "foo ";
}
shared_buffer somestruct::pack2(arg_pack_fn pack_fns[], void const* args[], size_t count) {
for (size_t i = 0; i != count; ++i)
{
pack_fns[i](args[i]);
}
}
int main() {
somestruct ss;
ss.pack(foo{}, 1, 3.14);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IHNoYXJlZF9idWZmZXIge307CgpzaGFyZWRfYnVmZmVyIGRvX3BhY2soaW50IGFyZyk7CnNoYXJlZF9idWZmZXIgZG9fcGFjayhkb3VibGUgYXJnKTsKCnN0cnVjdCBmb28gewoJZnJpZW5kIHNoYXJlZF9idWZmZXIgZG9fcGFjayhmb28gY29uc3QmIGFyZyk7Cn07CgoKc3RydWN0IHNvbWVzdHJ1Y3QgewogICAgdGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJncz4KICAgIHNoYXJlZF9idWZmZXIgcGFjayhjb25zdCBBcmdzJi4uLiBhcmdzKSB7CiAgICAJLy8gY29udmVydCBhcmcgcGFjayB0byBhcnJheSBvZiBwYWNrIGZ1bmN0aW9ucyBhbmQgYXJndW1lbnRzCiAgICAJYXJnX3BhY2tfZm4gZm5zW10gPSB7ICZ3cmFwX2RvX3BhY2s8QXJncz4uLi4gfTsKICAgIAl2b2lkIGNvbnN0KiBkYXRhW10gPSB7IHN0ZDo6YWRkcmVzc29mKGFyZ3MpLi4uIH07CiAgICAJCiAgICAgICAgcmV0dXJuIHBhY2syKGZucywgZGF0YSwgc2l6ZW9mLi4uKEFyZ3MpKTsKICAgIH0KCnByaXZhdGU6CiAgICB1c2luZyBhcmdfcGFja19mbiA9IHNoYXJlZF9idWZmZXIgKCopKHZvaWQgY29uc3QqIGFyZyk7CgoJLy8gYWN0dWFsIGRvX3BhY2sgZm9yIGVhY2ggYXJnIHR5cGUKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICBzdGF0aWMgc2hhcmVkX2J1ZmZlciB3cmFwX2RvX3BhY2sodm9pZCBjb25zdCogYXJnKSB7CiAgICAgICAgcmV0dXJuIGRvX3BhY2soKnN0YXRpY19jYXN0PFQgY29uc3QqPihhcmcpKTsKICAgIH0KCiAgICBzaGFyZWRfYnVmZmVyIHBhY2syKGFyZ19wYWNrX2ZuIHBhY2tfZm5zW10sIHZvaWQgY29uc3QqIGFyZ3NbXSwgc2l6ZV90IGNvdW50KTsKfTsKCi8vIGltcGxlbWVudGF0aW9uIGluIC5jcHAKCnNoYXJlZF9idWZmZXIgZG9fcGFjayhpbnQgYXJnKSB7CglzdGQ6OmNvdXQgPDwgYXJnIDw8ICcgJzsKfQoKc2hhcmVkX2J1ZmZlciBkb19wYWNrKGRvdWJsZSBhcmcpIHsKCXN0ZDo6Y291dCA8PCBhcmcgPDwgJyAnOwp9CgpzaGFyZWRfYnVmZmVyIGRvX3BhY2soZm9vIGNvbnN0JiBhcmcpIHsKCXN0ZDo6Y291dCA8PCAiZm9vICI7Cn0KCnNoYXJlZF9idWZmZXIgc29tZXN0cnVjdDo6cGFjazIoYXJnX3BhY2tfZm4gcGFja19mbnNbXSwgdm9pZCBjb25zdCogYXJnc1tdLCBzaXplX3QgY291bnQpIHsKCWZvciAoc2l6ZV90IGkgPSAwOyBpICE9IGNvdW50OyArK2kpCgl7CgkJcGFja19mbnNbaV0oYXJnc1tpXSk7Cgl9Cn0KCmludCBtYWluKCkgewoJc29tZXN0cnVjdAlzczsKCXNzLnBhY2soZm9ve30sIDEsIDMuMTQpOwp9