#include <iostream>
#include <memory>
#include <vector>

class Node {
public:
   using NodePtr = std::unique_ptr<Node>;
   Node( char lc, NodePtr l, NodePtr r ) :
	c( lc ), left( std::move(l) ), right( std::move(r) )
   {
   }
   ~Node();

private:
   NodePtr left;
   NodePtr right;
   char    c;
};


Node::~Node()
{
	std::cout << "destroying " << c << std::endl;
	
     if( ! (left || right) ) // optimization
         return;
     std::vector<NodePtr> nodes;
     auto populate = [&nodes] ( Node *n ) {
         if( n->left ) nodes.push_back( std::move( n->left ) );
         if( n->right ) nodes.push_back( std::move( n->right ) );
     };
     populate( this );
     while( !nodes.empty() ) {
         auto n = std::move( nodes.back() );
         nodes.pop_back();
         populate( n.get() );
     }
}


int main() {
	Node root( 'A', 
	    std::make_unique<Node>( 'l', std::make_unique<Node>( 'L', nullptr, nullptr ), nullptr ),
	    std::make_unique<Node>( 'r', std::make_unique<Node>( 'R', nullptr, nullptr ), nullptr ) );
	return 0;
}