def _generate_range(start, end, periods, offset):
    """Generate a regular range of cftime.datetime objects with a
    given time offset.

    Adapted from pandas.tseries.offsets.generate_range.

    Parameters
    ----------
    start : cftime.datetime, or None
        Start of range
    end : cftime.datetime, or None
        End of range
    periods : int, or None
        Number of elements in the sequence
    offset : BaseCFTimeOffset
        An offset class designed for working with cftime.datetime objects

    Returns
    -------
    A generator object
    """
    if start:
        start = offset.rollforward(start)
    if end:
        end = offset.rollback(end)
    if periods is None and end < start:
        end = None
        periods = 0
    if end is None:
        end = start + (periods - 1) * offset
    if start is None:
        start = end - (periods - 1) * offset
    current = start
    if offset.n >= 0:
        while current <= end:
            yield current
            next_date = current + offset
            if next_date <= current:
                raise ValueError(f'Offset {offset} did not increment date')
            current = next_date
    else:
        while current >= end:
            yield current
            next_date = current + offset
            if next_date >= current:
                raise ValueError(f'Offset {offset} did not decrement date')
            current = next_date
