#include <iostream>
#include <memory>
template < typename T>
struct Node {
T m_info;
std:: shared_ptr < Node< T>> m_next;
std:: shared_ptr < Node< T>> m_prev;
} ;
template < typename T>
struct List {
void print( ) {
auto n = m_head.get ( ) ;
while ( n) {
std:: cout << n- > m_info << '\n ' ;
n = n- > m_next.get ( ) ;
}
}
void add( T value) {
auto node = std:: make_shared < Node< T>> ( Node< T> { value, m_head, nullptr} ) ;
if ( m_head) m_head.get ( ) - > m_prev = m_head;
m_head = node;
}
private :
std:: shared_ptr < Node< T>> m_head;
} ;
struct noisy_at_dying {
int id;
~noisy_at_dying( ) { std:: cout << id << " is dying\n " ; }
} ;
// for print
std:: ostream & operator<< ( std:: ostream & os, const noisy_at_dying& nad) { return os << nad.id ; }
int main( ) {
{
List< noisy_at_dying> l;
for ( auto i = int { 0 } ; i < 3 ; ++ i)
l.add ( { i } ) ;
std:: cout << "\n The list is populated. Printing...\n \n " ;
l.print ( ) ;
std:: cout << "\n The list is about to be destroyed...\n \n " ;
}
std:: cout << "\n The list has been destroyed.\n " ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBOb2RlIHsKICAgIFQgbV9pbmZvOwoKICAgIHN0ZDo6c2hhcmVkX3B0cjxOb2RlPFQ+PiBtX25leHQ7CiAgICBzdGQ6OnNoYXJlZF9wdHI8Tm9kZTxUPj4gbV9wcmV2Owp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBMaXN0IHsKCiAgICB2b2lkIHByaW50KCkgewogICAgICAgIGF1dG8gbiA9IG1faGVhZC5nZXQoKTsKCiAgICAgICAgd2hpbGUgKG4pIHsKICAgICAgICAgICAgc3RkOjpjb3V0IDw8IG4tPm1faW5mbyA8PCAnXG4nOwoKICAgICAgICAgICAgbiA9IG4tPm1fbmV4dC5nZXQoKTsKICAgICAgICB9CiAgICB9CgogICAgdm9pZCBhZGQoVCB2YWx1ZSkgewogICAgICAgIGF1dG8gbm9kZSA9IHN0ZDo6bWFrZV9zaGFyZWQ8Tm9kZTxUPj4oTm9kZTxUPnsgdmFsdWUsIG1faGVhZCwgbnVsbHB0cn0pOwogICAgICAgIGlmIChtX2hlYWQpIG1faGVhZC5nZXQoKS0+bV9wcmV2ID0gbV9oZWFkOwogICAgICAgIG1faGVhZCA9IG5vZGU7CiAgICB9Cgpwcml2YXRlOgogICAgc3RkOjpzaGFyZWRfcHRyPE5vZGU8VD4+IG1faGVhZDsKfTsKCnN0cnVjdCBub2lzeV9hdF9keWluZyB7CiAgICBpbnQgaWQ7CgogICAgfm5vaXN5X2F0X2R5aW5nKCkgeyBzdGQ6OmNvdXQgPDwgaWQgPDwgIiBpcyBkeWluZ1xuIjsgfQp9OwoKLy8gZm9yIHByaW50CnN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG9zLCBjb25zdCBub2lzeV9hdF9keWluZyYgbmFkKSB7cmV0dXJuIG9zIDw8IG5hZC5pZDt9CgppbnQgbWFpbigpIHsKCiAgICB7CiAgICAgICAgTGlzdDxub2lzeV9hdF9keWluZz4gbDsKCiAgICAgICAgZm9yIChhdXRvIGkgPSBpbnR7IDAgfTsgaSA8IDM7ICsraSkKICAgICAgICAgICAgbC5hZGQoeyBpIH0pOwoKICAgICAgICBzdGQ6OmNvdXQgPDwgIlxuVGhlIGxpc3QgaXMgcG9wdWxhdGVkLiBQcmludGluZy4uLlxuXG4iOwoKICAgICAgICBsLnByaW50KCk7CgogICAgICAgIHN0ZDo6Y291dCA8PCAiXG5UaGUgbGlzdCBpcyBhYm91dCB0byBiZSBkZXN0cm95ZWQuLi5cblxuIjsKICAgIH0KCiAgICBzdGQ6OmNvdXQgPDwgIlxuVGhlIGxpc3QgaGFzIGJlZW4gZGVzdHJveWVkLlxuIjsKfQ==