```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 without causing overflow by checking if 2**i exceeds cap/base
        # If base == 0, then base * 2**i == 0, so min(cap, 0) = 0
        if base == 0:
            result.append(0.0)
            continue
        # Check if 2**i * base > cap, i.e., 2**i > cap / base
        # To avoid overflow, we can check if i is large enough that 2**i * base > cap
        # Since cap and base are non-negative, if cap == 0, then min(cap, ...) = 0
        if cap == 0:
            result.append(0.0)
            continue
        # We need to compute min(cap, base * 2**i)
        # If base * 2**i > cap, then result is cap
        # Otherwise, result is base * 2**i
        # To avoid overflow, check if 2**i > cap / base
        # cap / base is a float, but 2**i can be huge. We can check if i is large enough.
        # If i >= some threshold, 2**i * base > cap.
        # Let's compute: if base * 2**i > cap, then 2**i > cap / base
        # We can check if i > log2(cap / base), but that involves math.log2 which may not be imported.
        # Instead, we can iteratively check or use a safe comparison.
        # Since we cannot import math, we can do:
        # If i is large, 2**i will be huge. We can check if 2**i * base > cap by comparing step by step.
        # But a simpler approach: if i is large enough that 2**i > cap / base, then result is cap.
        # We can compute cap / base as a float, but if base is very small, cap/base could be huge.
        # Alternative: use integer arithmetic. If base is an integer, we can do integer comparison.
        # But base could be a float.
        # Let's handle it by checking if i is large enough that 2**i * base > cap.
        # We can do: if i >= 1024, then 2**i is astronomically large, so base * 2**i > cap for any reasonable cap.
        # But this is not robust.
        # Better approach: compute 2**i as an integer, then multiply by base. If base is a float, multiplying a huge int by a float causes overflow.
        # So we need to avoid converting huge int to float.
        # We can check if 2**i > cap / base. If cap / base is finite, and 2**i > cap / base, then result is cap.
        # But cap / base could be inf if base is very small.
        # Let's use a different approach:
        # If base == 0, result is 0.
        # If cap == 0, result is 0.
        # Otherwise, we want min(cap, base * 2**i).
        # If base * 2**i > cap, result is cap.
        # To check if base * 2**i > cap without overflow:
        # If i is large, 2**i is huge. We can check if i > log2(cap / base).
        # Since we can't import math, we can approximate or use a loop.
        # Alternatively, we can compute 2**i as an integer, and if it's too large, we know the result is cap.
        # How large is too large? If 2**i * base > cap, then 2**i > cap / base.
        # If cap / base is finite, we can check if 2**i > cap / base.
        # But 2**i as an int can be huge, and cap / base as a float can be huge.
        # Let's try: if i >= 1024, then 2**i is at least 2**1024, which is about 1.8e308, close to float max.
        # If base is small, base * 2**i could overflow.
        # So for i >= 1024, we can assume base * 2**i > cap (unless cap is also huge, but cap is a float, so it can't be larger than float max).
        # Actually, if cap is a float, it can be at most ~1.8e308. If base is positive, and i >= 1024, then 2**i >= 2**1024 ~ 1.8e308, so base * 2**i >= base * 1.8e308. If base >= 1, this is >= 1.8e308, which is >= cap (since cap <= float max). If base < 1, base * 2**i could be less than cap.
        # So we need a more careful check.
        # Let's compute cap / base as a float. If cap / base is inf, then base * 2**i > cap for all i (since base > 0).
        # If cap / base is finite, we can check if 2**i > cap / base.
        # But 2**i as an int can be huge. We can check if i > log2(cap / base).
        # Since we can't import math, we can use a loop to find the smallest i such that 2**i > cap / base.
        # But this is complex.
        # Simpler: for each i, compute 2**i as an int. If 2**i * base > cap, result is cap. Otherwise, result is base * 2**i.
        # To avoid overflow when multiplying int by float, we can check if 2**i > cap / base.
        # cap / base is a float. If cap / base is inf, then for any i, 2**i > cap / base is false (inf > inf is false), but actually if cap / base is inf, then base * 2**i > cap for all i (since base > 0 and cap is finite).
        # Wait, if cap / base is inf, that means base is very small or cap is very large. If base > 0 and cap is finite, cap / base can be inf if base is extremely small.
        # In that case, base * 2**i > cap for all i >= 1 (since base * 2**i grows).
        # So if cap / base is inf, result is cap for all i >= 1, and for i=0, result is min(cap, base) = base (since base < cap if cap / base is inf).
        # This is getting complicated.
        # Let's use a different approach: compute the value as a float, but catch the overflow.
        # We can try to compute base * 2**i, and if it overflows, use cap.
        # But we can't catch OverflowError easily in a loop without try/except.
        # Let's use try/except.
        try:
            val = base * (2 ** i)
            result.append(min(cap, val))
        except OverflowError:
            result.append(cap)
    return result
```