#include <functional>
#include <iterator>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <typeinfo>
#include <array>
std::vector<std::pair<std::function<void(int)>, void*>> callbacks;
class MyClass{
static unsigned const num_possible_callbacks = 2; // keep updated
std::array<std::type_info const*, num_possible_callbacks> _infos;
unsigned _next_info;
// adds type_info and passes through
template<class T>
T const& add_info(T const& bound){
if(_next_info == num_possible_callbacks)
throw "oh shi...!"; // something went out of sync
_infos[_next_info++] = &typeid(T);
return bound;
}
public:
MyClass() : _next_info(0){
using std::placeholders::_1;
callbacks.push_back(std::make_pair(
add_info(std::bind(&MyClass::myFunc, this, _1)),
(void*)this));
callbacks.push_back(std::make_pair(
add_info([this](int i){ return myOtherFunc(i, 0.5); }),
(void*)this));
}
~MyClass(){
using std::placeholders::_1;
callbacks.erase(std::remove_if(callbacks.begin(), callbacks.end(),
[&](std::pair<std::function<void(int)>, void*> const& p) -> bool{
if(p.second != (void*)this)
return false;
auto const& f = p.first;
for(unsigned i = 0; i < _infos.size(); ++i)
if(_infos[i] == &f.target_type())
return true;
return false;
}), callbacks.end());
}
void myFunc(int param){ /* ... */ }
void myOtherFunc(int param1, double param2){ /* ... */ }
};
int main(){
auto print = []{ std::cout << "Callbacks:" << callbacks.size() << "\n"; };
print();
{
MyClass c1;
print();
{
MyClass c2;
print();
}
print();
}
print();
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpdGVyYXRvcj4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8YXJyYXk+CgpzdGQ6OnZlY3RvcjxzdGQ6OnBhaXI8c3RkOjpmdW5jdGlvbjx2b2lkKGludCk+LCB2b2lkKj4+IGNhbGxiYWNrczsKCmNsYXNzIE15Q2xhc3N7CiAgc3RhdGljIHVuc2lnbmVkIGNvbnN0IG51bV9wb3NzaWJsZV9jYWxsYmFja3MgPSAyOyAvLyBrZWVwIHVwZGF0ZWQKICBzdGQ6OmFycmF5PHN0ZDo6dHlwZV9pbmZvIGNvbnN0KiwgbnVtX3Bvc3NpYmxlX2NhbGxiYWNrcz4gX2luZm9zOwogIHVuc2lnbmVkIF9uZXh0X2luZm87CgogIC8vIGFkZHMgdHlwZV9pbmZvIGFuZCBwYXNzZXMgdGhyb3VnaAogIHRlbXBsYXRlPGNsYXNzIFQ+CiAgVCBjb25zdCYgYWRkX2luZm8oVCBjb25zdCYgYm91bmQpewogICAgaWYoX25leHRfaW5mbyA9PSBudW1fcG9zc2libGVfY2FsbGJhY2tzKQogICAgICB0aHJvdyAib2ggc2hpLi4uISI7IC8vIHNvbWV0aGluZyB3ZW50IG91dCBvZiBzeW5jCiAgICBfaW5mb3NbX25leHRfaW5mbysrXSA9ICZ0eXBlaWQoVCk7CiAgICByZXR1cm4gYm91bmQ7CiAgfQpwdWJsaWM6CiAgTXlDbGFzcygpIDogX25leHRfaW5mbygwKXsKICAgIHVzaW5nIHN0ZDo6cGxhY2Vob2xkZXJzOjpfMTsKICAgIGNhbGxiYWNrcy5wdXNoX2JhY2soc3RkOjptYWtlX3BhaXIoCiAgICAgICAgYWRkX2luZm8oc3RkOjpiaW5kKCZNeUNsYXNzOjpteUZ1bmMsIHRoaXMsIF8xKSksCiAgICAgICAgKHZvaWQqKXRoaXMpKTsKICAgIGNhbGxiYWNrcy5wdXNoX2JhY2soc3RkOjptYWtlX3BhaXIoCiAgICAgICAgYWRkX2luZm8oW3RoaXNdKGludCBpKXsgcmV0dXJuIG15T3RoZXJGdW5jKGksIDAuNSk7IH0pLAogICAgICAgICh2b2lkKil0aGlzKSk7CiAgfQoKICB+TXlDbGFzcygpewogICAgdXNpbmcgc3RkOjpwbGFjZWhvbGRlcnM6Ol8xOwoKICAgIGNhbGxiYWNrcy5lcmFzZShzdGQ6OnJlbW92ZV9pZihjYWxsYmFja3MuYmVnaW4oKSwgY2FsbGJhY2tzLmVuZCgpLAogICAgICAgIFsmXShzdGQ6OnBhaXI8c3RkOjpmdW5jdGlvbjx2b2lkKGludCk+LCB2b2lkKj4gY29uc3QmIHApIC0+IGJvb2x7CiAgICAgICAgICBpZihwLnNlY29uZCAhPSAodm9pZCopdGhpcykKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYXV0byBjb25zdCYgZiA9IHAuZmlyc3Q7CiAgICAgICAgICBmb3IodW5zaWduZWQgaSA9IDA7IGkgPCBfaW5mb3Muc2l6ZSgpOyArK2kpCiAgICAgICAgICAgIGlmKF9pbmZvc1tpXSA9PSAmZi50YXJnZXRfdHlwZSgpKQogICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0pLCBjYWxsYmFja3MuZW5kKCkpOwogIH0KCiAgdm9pZCBteUZ1bmMoaW50IHBhcmFtKXsgLyogLi4uICovIH0KICB2b2lkIG15T3RoZXJGdW5jKGludCBwYXJhbTEsIGRvdWJsZSBwYXJhbTIpeyAvKiAuLi4gKi8gfQp9OwoKaW50IG1haW4oKXsKICBhdXRvIHByaW50ID0gW117IHN0ZDo6Y291dCA8PCAiQ2FsbGJhY2tzOiIgPDwgY2FsbGJhY2tzLnNpemUoKSA8PCAiXG4iOyB9OwogIHByaW50KCk7CiAgewogICAgTXlDbGFzcyBjMTsKICAgIHByaW50KCk7CiAgICB7CiAgICAgIE15Q2xhc3MgYzI7CiAgICAgIHByaW50KCk7CiAgICB9CiAgICBwcmludCgpOwogIH0KICBwcmludCgpOwp9