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

tracked A (my_objects)
---------------------
A::foo( 0x9b82230, 2, y )
A::foo( 0x9b8222c, 2, y )

tracked A (their_objects)
--------------
A::foo( 0xbfc3a9b4, 3, z )
A::foo( 0xbfc3a9b0, 3, z )
A::foo( 0xbfc3a9ac, 3, z )
A::foo( 0xbfc3a9a8, 3, z )

tracked B (my_objects)
--------------
B::bar( 0xbfc3a9a4, hello )
B::bar( 0xbfc3a9a0, hello )
B::bar( 0xbfc3a99c, hello )