1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
#include <iostream>
#include <unordered_set>
#include <memory>
template < typename T, typename TAG = void > struct magic
{
magic() { objects.insert( static_cast<T*>(this) ) ; }
magic( const magic& that ) : magic() {}
magic( magic&& that ) : magic() {}
~magic() { objects.erase( static_cast<T*>(this) ) ; }
template< typename FN > static void for_each_instance( FN fn )
{ for( T* p : objects ) fn(p) ; }
private: static std::unordered_set<T*> objects ;
};
template < typename T, typename TAG > std::unordered_set<T*> magic<T,TAG>::objects ;
template < typename T, typename TAG = void > struct tracked
: T, magic< tracked<T,TAG>, TAG >
{
template < typename ... ARGS > tracked( ARGS... args ) : T(args...) {}
};
struct A
{
virtual ~A() {}
void foo( int i, char c )
{ std::cout << "A::foo( " << this << ", " << i << ", " << c << " )\n" ; }
};
struct B
{
B( int a = 0, double b = 0 ) {}
virtual ~B() {}
void bar( const char* cstr )
{ std::cout << "B::bar( " << this << ", " << cstr << " )\n" ; }
};
int main()
{
A not_tracked[10] ;
B also_not_tracked[20] ;
std::unique_ptr<A> default_tracked( new tracked<A> ) ;
std::unique_ptr<B> also_default_tracked( new tracked<B> ) ;
struct my_objects {};
A* my_tracked_A_objects = new tracked< A, my_objects >[2] ;
tracked< B, my_objects > my_tracked_B_objects[3] { {1,2.3}, {4,5.6}, {7,8.9} } ;
struct their_objects {};
tracked< A, their_objects > their_tracked_A_objects[4] ;
std::cout << "tracked A (default)\n-----------------------\n" ;
tracked<A>::for_each_instance( []( A* pa ) { pa->foo( 1, 'x' ) ; } ) ;
std::cout << "\ntracked A (my_objects)\n---------------------\n" ;
tracked<A,my_objects>::for_each_instance( []( A* pa ) { pa->foo( 2, 'y' ) ; } ) ;
std::cout << "\ntracked A (their_objects)\n--------------\n" ;
tracked<A,their_objects>::for_each_instance( []( A* pa ) { pa->foo( 3, 'z' ) ; } ) ;
std::cout << "\ntracked B (my_objects)\n--------------\n" ;
tracked<B,my_objects>::for_each_instance( []( B* pb ) { pb->bar( "hello" ) ; } ) ;
}
|