reimplement guarded_ptr from scratch