```python
def retry_delays(attempts, base, cap):
    if isinstance(attempts, bool) or not isinstance(attempts, int):
        raise TypeError("attempts must be a non-negative integer")
    if attempts < 0:
        raise ValueError("attempts must be non-negative")
    if base < 0:
        raise ValueError("base must be non-negative")
    if cap < 0:
        raise ValueError("cap must be non-negative")
    
    result = []
    for i in range(attempts):
        # Compute base * 2**i carefully to avoid overflow
        # If base is 0, delay is 0
        if base == 0:
            delay = 0
        else:
            # Check if base * 2**i would exceed cap
            # We can compare without computing the full power if it's too large
            # Since cap is non-negative, if base * 2**i >= cap, we use cap
            # To avoid overflow, we can check if 2**i is so large that base * 2**i > cap
            # But we need to handle float base and int cap or vice versa
            
            # Let's handle the case where base * 2**i might overflow
            # If base is a float, 2**i can be huge. We need to avoid converting huge int to float.
            
            # Strategy: if base == 0, delay = 0
            # Otherwise, we want min(cap, base * 2**i)
            # If base * 2**i >= cap, result is cap
            # We can check if 2**i >= cap / base (if base > 0)
            # But cap / base might be problematic if base is very small.
            
            # Alternative: compute step by step or use logarithms? No, simpler:
            # If base is 0, delay = 0.
            # If base > 0, we can check if 2**i is large enough that base * 2**i >= cap.
            # Since cap is non-negative, if cap == 0, delay = 0.
            # If cap > 0 and base > 0:
            #   We want min(cap, base * 2**i)
            #   If base * 2**i >= cap, use cap.
            #   To avoid overflow, we can check if 2**i >= cap / base.
            #   But cap / base could be a float. If base is very small, cap/base is huge.
            #   However, 2**i grows exponentially. For large i, 2**i will be huge.
            #   We can check if i is large enough that 2**i > cap / base.
            #   But cap / base might not be an integer.
            
            # Simpler approach: if base * 2**i would overflow, it means base * 2**i is very large,
            # so it's definitely >= cap (since cap is finite). So we can just use cap.
            # How to detect overflow? We can try to compute and catch, but that's not ideal.
            # Instead, we can check if 2**i is so large that base * 2**i > cap.
            # Since base >= 0 and cap >= 0, if base == 0, delay = 0.
            # If base > 0, we can compute threshold = cap / base.
            # If 2**i >= threshold, then base * 2**i >= cap, so delay = cap.
            # But threshold might be a float. We can compare 2**i with threshold.
            # However, 2**i is an int, threshold is a float. Comparing int and float is fine.
            # But if threshold is very large, 2**i might overflow when converted to float?
            # Actually, we don't need to convert 2**i to float. We can compare int 2**i with float threshold.
            # Python can compare int and float. If 2**i is huge, it can still be compared with a float.
            # But if threshold is inf, then any 2**i < inf, so we compute base * 2**i.
            # If base * 2**i overflows, we catch it.
            
            # Let's try a different approach:
            # If base == 0: delay = 0
            # Else if cap == 0: delay = 0
            # Else:
            #   We want min(cap, base * 2**i)
            #   If base * 2**i >= cap, use cap.
            #   To avoid overflow, we can check if 2**i >= cap / base.
            #   But cap / base might be a float. If base is very small, cap/base is huge.
            #   We can check if i is large enough that 2**i >= cap / base.
            #   Since 2**i grows exponentially, for large i, 2**i will be huge.
            #   We can compute threshold = cap / base.
            #   If 2**i >= threshold, delay = cap.
            #   Else, delay = base * 2**i.
            #   But if base * 2**i overflows, we need to handle it.
            #   Actually, if 2**i >= threshold, we use cap, so we don't compute base * 2**i.
            #   If 2**i < threshold, then base * 2**i < cap, so it won't overflow (since cap is finite).
            #   Wait, base * 2**i < cap, so it's bounded by cap, which is finite. So no overflow.
            #   So the only issue is when base * 2**i >= cap, in which case we use cap.
            #   So we can check if 2**i >= cap / base.
            #   But cap / base might be a float. If base is very small, cap/base is huge.
            #   We can compare 2**i (int) with cap / base (float).
            #   If 2**i >= cap / base, delay = cap.
            #   Else, delay = base * 2**i.
            #   But if base * 2**i overflows, it means base * 2**i is huge, so it's >= cap, so we should use cap.
            #   So we can check if 2**i >= cap / base.
            #   But cap / base might be inf if base is very small. If cap / base is inf, then 2**i < inf, so we compute base * 2**i.
            #   But if base * 2**i overflows, we catch it.
            
            # Let's implement:
            if base == 0:
                delay = 0
            elif cap == 0:
                delay = 0
            else:
                # Check if base * 2**i >= cap
                # We can check if 2**i >= cap / base
                # But cap / base might be a float. If base is very small, cap/base is huge.
                # We can compare 2**i with cap / base.
                # If 2**i >= cap / base, delay = cap.
                # Else, delay = base * 2**i.
                # But if base * 2**i overflows, we need to handle it.
                # Actually, if 2**i >= cap / base, we use cap, so we don't compute base * 2**i.
                # If 2**i < cap / base, then base * 2**i < cap, so it won't overflow.
                # So we can safely compute base * 2**i when 2**i < cap / base.
                # But how to check 2**i >= cap / base without computing 2**i as float?
                # We can compute 2**i as int, and compare with cap / base as float.
                # Python can compare int and float. If 2**i is huge, it can still be compared with a float.
                # But if cap / base is inf, then 2**i < inf, so we compute base * 2**i.
                # If base * 2**i overflows, we catch it.
                
                # Let's try:
                try:
                    threshold = cap / base
                    if 2 ** i >= threshold:
                        delay = cap
                    else:
                        delay = base * (2 ** i)
                except OverflowError:
                    delay = cap
            result.append(delay)
    return result
```