```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 would exceed 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, in which case we use cap
        # To avoid overflow, we can check if 2**i > cap / base
        # But cap / base might be problematic if base is very small.
        # Instead, we can compute step by step or use logarithms.
        # A safer approach: if 2**i * base > cap, use cap.
        # We can check if i is large enough that 2**i * base > cap.
        # Since base and cap are non-negative, and base > 0 here:
        # 2**i * base > cap  <=>  2**i > cap / base
        # We can compute cap / base as a float, but if base is very small, cap/base could be huge.
        # Alternatively, we can use logarithms: i * log(2) > log(cap / base)
        # But log(cap/base) might have issues if cap/base is very large or small.
        
        # Simpler approach: compute 2**i as an integer, but if it's too large, we know the result is cap.
        # We can check if 2**i * base > cap by comparing 2**i > cap / base.
        # To avoid overflow in 2**i, we can check if i is large enough.
        # The maximum i where 2**i * base <= cap is when 2**i <= cap / base.
        # If cap / base is very large, 2**i could overflow.
        
        # Let's use a different approach: compute the value iteratively to avoid huge powers.
        # Start with current = base, and for each step, multiply by 2, but cap at cap.
        # This avoids computing 2**i directly.
        
        # Actually, let's just compute iteratively:
        # For i=0: value = base
        # For i=1: value = base * 2
        # For i=2: value = base * 4
        # ...
        # But we need to cap at cap.
        
        # Let's restructure: compute iteratively
        current = base
        for i in range(attempts):
            val = min(cap, current)
            result.append(val)
            current *= 2
            # If current already exceeds cap, all subsequent values will be cap
            # But we still need to append cap for remaining iterations
            # Actually, once current > cap, min(cap, current) = cap for all future i
            # So we can break early and fill the rest with cap
            if current > cap:
                # Fill remaining with cap
                for j in range(i + 1, attempts):
                    result.append(cap)
                break
        else:
            # If we didn't break, all values were computed
            pass
    
    return result
```