#include <iostream>
#include <unordered_set>
template < typename T > struct magic
{
magic() : enable_for_each_instance(false) {}
magic( bool b) : enable_for_each_instance(b)
{ if(b) objects.insert( static_cast<T*>(this) ) ; }
magic( const magic& that ) : magic(that.enable_for_each_instance) {}
magic( magic&& that ) : magic(that.enable_for_each_instance) {}
~magic() { if(enable_for_each_instance) objects.erase( static_cast<T*>(this) ) ; }
template< typename FN > static void for_each_instance( FN fn )
{ for( T* p : objects ) fn(p) ; }
const bool enable_for_each_instance ;
private: static std::unordered_set<T*> objects ;
};
template < typename T > std::unordered_set<T*> magic<T>::objects ;
struct A : magic<A>
{
explicit A( bool enable_magic = false ) : magic<A>(enable_magic) {}
void foo( int i, char c )
{ std::cout << "A::foo( " << this << ", " << i << ", " << c << " )\n" ; }
};
struct B : magic<B>
{
explicit B( bool enable_magic = false ) : magic<B>(enable_magic) {}
void bar( double d ) const
{ std::cout << "B::bar( " << this << ", " << d << " )\n" ; }
};
int main()
{
A one(true), x ;
B two(true), y ;
{
A three = one ;
B four, five = two ;
A a[1000] ;
B b[25] ;
A::for_each_instance( []( A* p ) { p->foo( 99, 'X' ) ; } ) ;
B::for_each_instance( []( B* p ) { p->bar( 12.8 ) ; } ) ;
}
std::cout << "------------------------\n" ;
A::for_each_instance( []( A* p ) { p->foo( -7, 'Y' ) ; } ) ;
B::for_each_instance( []( B* p ) { p->bar( 123.45 ) ; } ) ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dW5vcmRlcmVkX3NldD4KCnRlbXBsYXRlIDwgdHlwZW5hbWUgVCA+IHN0cnVjdCBtYWdpYwp7CiAgICBtYWdpYygpIDogZW5hYmxlX2Zvcl9lYWNoX2luc3RhbmNlKGZhbHNlKSB7fQoKICAgIG1hZ2ljKCBib29sIGIpIDogZW5hYmxlX2Zvcl9lYWNoX2luc3RhbmNlKGIpCiAgICB7IGlmKGIpIG9iamVjdHMuaW5zZXJ0KCBzdGF0aWNfY2FzdDxUKj4odGhpcykgKSA7IH0KCiAgICBtYWdpYyggY29uc3QgbWFnaWMmIHRoYXQgKSA6IG1hZ2ljKHRoYXQuZW5hYmxlX2Zvcl9lYWNoX2luc3RhbmNlKSB7fQoKICAgIG1hZ2ljKCBtYWdpYyYmIHRoYXQgKSA6IG1hZ2ljKHRoYXQuZW5hYmxlX2Zvcl9lYWNoX2luc3RhbmNlKSB7fQoKICAgIH5tYWdpYygpIHsgaWYoZW5hYmxlX2Zvcl9lYWNoX2luc3RhbmNlKSBvYmplY3RzLmVyYXNlKCBzdGF0aWNfY2FzdDxUKj4odGhpcykgKSA7IH0KCiAgICB0ZW1wbGF0ZTwgdHlwZW5hbWUgRk4gPiBzdGF0aWMgdm9pZCBmb3JfZWFjaF9pbnN0YW5jZSggRk4gZm4gKQogICAgeyBmb3IoIFQqIHAgOiBvYmplY3RzICkgZm4ocCkgOyB9CgogICAgY29uc3QgYm9vbCBlbmFibGVfZm9yX2VhY2hfaW5zdGFuY2UgOwogICAgcHJpdmF0ZTogc3RhdGljIHN0ZDo6dW5vcmRlcmVkX3NldDxUKj4gb2JqZWN0cyA7Cn07Cgp0ZW1wbGF0ZSA8IHR5cGVuYW1lIFQgPiBzdGQ6OnVub3JkZXJlZF9zZXQ8VCo+IG1hZ2ljPFQ+OjpvYmplY3RzIDsKCnN0cnVjdCBBIDogbWFnaWM8QT4KewogICAgZXhwbGljaXQgQSggYm9vbCBlbmFibGVfbWFnaWMgPSBmYWxzZSApIDogbWFnaWM8QT4oZW5hYmxlX21hZ2ljKSB7fQogICAgdm9pZCBmb28oIGludCBpLCBjaGFyIGMgKQogICAgeyBzdGQ6OmNvdXQgPDwgIkE6OmZvbyggIiA8PCB0aGlzIDw8ICIsICIgPDwgaSA8PCAiLCAiIDw8IGMgPDwgIiApXG4iIDsgfQp9OwoKc3RydWN0IEIgOiBtYWdpYzxCPgp7CiAgICBleHBsaWNpdCBCKCBib29sIGVuYWJsZV9tYWdpYyA9IGZhbHNlICkgOiBtYWdpYzxCPihlbmFibGVfbWFnaWMpIHt9CiAgICB2b2lkIGJhciggZG91YmxlIGQgKSBjb25zdAogICAgeyBzdGQ6OmNvdXQgPDwgIkI6OmJhciggIiA8PCB0aGlzIDw8ICIsICIgPDwgZCA8PCAiIClcbiIgOyB9Cn07CgppbnQgbWFpbigpCnsKICAgIEEgb25lKHRydWUpLCB4IDsKICAgIEIgdHdvKHRydWUpLCB5IDsKICAgIHsKICAgICAgICBBIHRocmVlID0gb25lIDsKICAgICAgICBCIGZvdXIsIGZpdmUgPSB0d28gOwogICAgICAgIEEgYVsxMDAwXSA7CiAgICAgICAgQiBiWzI1XSA7CiAgICAgICAgQTo6Zm9yX2VhY2hfaW5zdGFuY2UoIFtdKCBBKiBwICkgeyBwLT5mb28oIDk5LCAnWCcgKSA7IH0gKSA7CiAgICAgICAgQjo6Zm9yX2VhY2hfaW5zdGFuY2UoIFtdKCBCKiBwICkgeyBwLT5iYXIoIDEyLjggKSA7IH0gKSA7CiAgICB9CiAgICBzdGQ6OmNvdXQgPDwgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIiA7CiAgICBBOjpmb3JfZWFjaF9pbnN0YW5jZSggW10oIEEqIHAgKSB7IHAtPmZvbyggLTcsICdZJyApIDsgfSApIDsKICAgIEI6OmZvcl9lYWNoX2luc3RhbmNlKCBbXSggQiogcCApIHsgcC0+YmFyKCAxMjMuNDUgKSA7IH0gKSA7Cn0K
A::foo( 0xbfbc3944, 99, X )
A::foo( 0xbfbc3940, 99, X )
B::bar( 0xbfbc3946, 12.8 )
B::bar( 0xbfbc3942, 12.8 )
------------------------
A::foo( 0xbfbc3940, -7, Y )
B::bar( 0xbfbc3942, 123.45 )