def fftshift(x: ndarray, axes: int | tuple[int, ...] | None = None) -> ndarray:
    """
    Shift the zero-frequency component to the center of the spectrum.

    This function swaps half-spaces for all axes listed (defaults to all).
    Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.

    Parameters
    ----------
    x : array_like
        Input array.

    axes : int or shape tuple, optional
        Axes over which to shift.  Default is None, which shifts all axes.

    Returns
    -------
    y : ndarray
        The shifted array.

    Availability
    --------
    Multiple GPUs, Multiple CPUs
    """
    shift: int | tuple[int, ...]
    if axes is None:
        axes = tuple(range(x.ndim))
        shift = tuple(dim // 2 for dim in x.shape)
    elif isinstance(axes, integer_types):
        shift = x.shape[axes] // 2
    else:
        shift = tuple(x.shape[ax] // 2 for ax in axes)

    return roll(x, shift, axes)

    Shift the zero-frequency component to the center of the spectrum.

    This function swaps half-spaces for all axes listed (defaults to all).
    Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.

    Parameters
    ----------
    x : array_like
        Input array.

    axes : int or shape tuple, optional
        Axes over which to shift.  Default is None, which shifts all axes.

    Returns
    -------
    y : ndarray
        The shifted array.

    Availability
    --------
    Multiple GPUs, Multiple CPUs
    
cupynumeric/fft/fft.py