code: def wrap_ufunc_base(name, n_in, n_out, doc):
      
      ufunc = getattr(np, name)
      if n_in == 1:
          if n_out == 1:
              def wrapper(self, out=None, **kwargs):
                  if out is None or isinstance(out, (type(self.elem),
                                                     type(self.elem.data))):
                      out = (out,)
  
                  return self.elem.__array_ufunc__(
                      ufunc, '__call__', self.elem, out=out, **kwargs)
  
          elif n_out == 2:
              def wrapper(self, out=None, **kwargs):
                  if out is None:
                      out = (None, None)
  
                  return self.elem.__array_ufunc__(
                      ufunc, '__call__', self.elem, out=out, **kwargs)
  
          else:
              raise NotImplementedError
  
      elif n_in == 2:
          if n_out == 1:
              def wrapper(self, x2, out=None, **kwargs):
                  return self.elem.__array_ufunc__(
                      ufunc, '__call__', self.elem, x2, out=(out,), **kwargs)
  
          else:
              raise NotImplementedError
      else:
          raise NotImplementedError
  
      wrapper.__name__ = wrapper.__qualname__ = name
      wrapper.__doc__ = doc
      return wrapper
docs: Return ufunc wrapper for implementation-agnostic ufunc classes.