use intrusive_ptr instead of shared_ptr