#include <iostream>
#include <unordered_set>
#include <memory>
#include <vector>
#include <deque>
template < typename T, typename TAG = void > struct magic
{
// ...
/* 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 { /* ... */ };
template < int N > struct use_case {} ;
int main()
{
// the general solution is not imposed; nothing needs to be done to
// 'let the specific use-cases choose how to store the objects'
std::vector< std::shared_ptr<A> > seq1(5) ;
for( int i = 0 ; i < 5 ; ++i ) seq1.emplace_back( new A ) ;
// the general solution can be used in conjunction with aspecial case solution
// here, objects participate multiple use cases
// all objects participate in the this use case, half of them also participate
// in the first use case, and the other half also participates in
// a new use-case using the general solution.
std::deque< std::shared_ptr<A> > seq2 { seq1.begin(), seq1.end() } ;
for( int i = 0 ; i < 5 ; ++i ) seq2.emplace_front( new tracked< A, use_case<1> > ) ;
// here, the same set of objects participate in two different use cases
// with both use cases implemented using just the general solution
tracked< A, use_case<2> > three[5] ;
std::vector< std::reference_wrapper<A> > four ;
for( A a : three )
four.emplace_back( tracked< std::reference_wrapper<A>, use_case<3> >(a) ) ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dW5vcmRlcmVkX3NldD4KI2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGRlcXVlPgoKdGVtcGxhdGUgPCB0eXBlbmFtZSBULCB0eXBlbmFtZSBUQUcgPSB2b2lkICA+IHN0cnVjdCBtYWdpYwp7CiAgICAvLyAuLi4KICAgIC8qIHByaXZhdGU6ICovIHN0YXRpYyBzdGQ6OnVub3JkZXJlZF9zZXQ8VCo+IG9iamVjdHMgOwp9OwoKdGVtcGxhdGUgPCB0eXBlbmFtZSBULCB0eXBlbmFtZSBUQUcgPiBzdGQ6OnVub3JkZXJlZF9zZXQ8VCo+IG1hZ2ljPFQsVEFHPjo6b2JqZWN0cyA7Cgp0ZW1wbGF0ZSA8IHR5cGVuYW1lIFQsIHR5cGVuYW1lIFRBRyA9IHZvaWQgPiBzdHJ1Y3QgdHJhY2tlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBULCBtYWdpYzwgdHJhY2tlZDxULFRBRz4sIFRBRyA+CnsKICAgIHRlbXBsYXRlIDwgdHlwZW5hbWUgLi4uIEFSR1MgPiB0cmFja2VkKCBBUkdTLi4uIGFyZ3MgKSA6IFQoYXJncy4uLikge30KfTsKCnN0cnVjdCBBIHsgLyogLi4uICovIH07Cgp0ZW1wbGF0ZSA8IGludCBOID4gc3RydWN0IHVzZV9jYXNlIHt9IDsKCmludCBtYWluKCkKewogICAvLyB0aGUgZ2VuZXJhbCBzb2x1dGlvbiBpcyBub3QgaW1wb3NlZDsgbm90aGluZyBuZWVkcyB0byBiZSBkb25lIHRvCiAgIC8vICdsZXQgdGhlIHNwZWNpZmljIHVzZS1jYXNlcyBjaG9vc2UgaG93IHRvIHN0b3JlIHRoZSBvYmplY3RzJwogICBzdGQ6OnZlY3Rvcjwgc3RkOjpzaGFyZWRfcHRyPEE+ID4gc2VxMSg1KSA7CiAgIGZvciggaW50IGkgPSAwIDsgaSA8IDUgOyArK2kgKSBzZXExLmVtcGxhY2VfYmFjayggbmV3IEEgKSA7CgogICAvLyB0aGUgZ2VuZXJhbCBzb2x1dGlvbiBjYW4gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGFzcGVjaWFsIGNhc2Ugc29sdXRpb24KICAgLy8gaGVyZSwgb2JqZWN0cyBwYXJ0aWNpcGF0ZSBtdWx0aXBsZSB1c2UgY2FzZXMKICAgLy8gYWxsIG9iamVjdHMgcGFydGljaXBhdGUgaW4gdGhlIHRoaXMgdXNlIGNhc2UsIGhhbGYgb2YgdGhlbSBhbHNvIHBhcnRpY2lwYXRlCiAgIC8vIGluIHRoZSBmaXJzdCB1c2UgY2FzZSwgYW5kIHRoZSBvdGhlciBoYWxmIGFsc28gcGFydGljaXBhdGVzIGluCiAgIC8vIGEgbmV3IHVzZS1jYXNlIHVzaW5nIHRoZSBnZW5lcmFsIHNvbHV0aW9uLgogICBzdGQ6OmRlcXVlPCBzdGQ6OnNoYXJlZF9wdHI8QT4gPiBzZXEyIHsgc2VxMS5iZWdpbigpLCBzZXExLmVuZCgpIH0gOwogICBmb3IoIGludCBpID0gMCA7IGkgPCA1IDsgKytpICkgc2VxMi5lbXBsYWNlX2Zyb250KCBuZXcgdHJhY2tlZDwgQSwgdXNlX2Nhc2U8MT4gPiApIDsKCiAgIC8vIGhlcmUsIHRoZSBzYW1lIHNldCBvZiBvYmplY3RzIHBhcnRpY2lwYXRlIGluIHR3byBkaWZmZXJlbnQgdXNlIGNhc2VzCiAgIC8vIHdpdGggYm90aCB1c2UgY2FzZXMgaW1wbGVtZW50ZWQgdXNpbmcganVzdCB0aGUgZ2VuZXJhbCBzb2x1dGlvbgogICB0cmFja2VkPCBBLCB1c2VfY2FzZTwyPiA+IHRocmVlWzVdIDsKICAgc3RkOjp2ZWN0b3I8IHN0ZDo6cmVmZXJlbmNlX3dyYXBwZXI8QT4gPiBmb3VyIDsKICAgZm9yKCBBIGEgOiB0aHJlZSApCiAgICAgICBmb3VyLmVtcGxhY2VfYmFjayggdHJhY2tlZDwgc3RkOjpyZWZlcmVuY2Vfd3JhcHBlcjxBPiwgdXNlX2Nhc2U8Mz4gPihhKSApIDsKfQo=