def _get_split_idx(N, blocksize, pad=0):
    """
    Returns a list of indexes dividing an array into blocks of size blocksize
    with optional padding.  Padding takes into account that the resultant block
    must fit within the original array.

    Parameters
    ----------
    N : Nonnegative integer
        Total array length
    blocksize : Nonnegative integer
        Size of each block
    pad : Nonnegative integer
        Pad to add on either side of each index

    Returns
    -------
    split_idx : List of 2-tuples
        Indices to create splits
    pads_used : List of 2-tuples
        Pads that were actually used on either side

    Examples
    --------
    >>> split_idx, pads_used = _get_split_idx(5, 2)
    >>> print split_idx
    [(0, 2), (2, 4), (4, 5)]
    >>> print pads_used
    [(0, 0), (0, 0), (0, 0)]

    >>> _get_split_idx(5, 2, pad=1)
    >>> print split_idx
    [(0, 3), (1, 5), (3, 5)]
    >>> print pads_used
    [(0, 1), (1, 1), (1, 0)]
    """
    num_fullsplits = N // blocksize
    remainder = N % blocksize

    split_idx = []
    pads_used = []
    for i in range(num_fullsplits):
        start = max(0, i * blocksize - pad)
        end = min(N, (i + 1) * blocksize + pad)
        split_idx.append((start, end))

        leftpad = i * blocksize - start
        rightpad = end - (i + 1) * blocksize
        pads_used.append((leftpad, rightpad))

    # Append the last split if there is a remainder
    if remainder:
        start = max(0, num_fullsplits * blocksize - pad)
        split_idx.append((start, N))

        leftpad = num_fullsplits * blocksize - start
        pads_used.append((leftpad, 0))

    return split_idx, pads_used