```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 use an iterative approach:
        # current = base
        # for i in range(attempts):
        #     value = min(cap, current)
        #     result.append(value)
        #     current *= 2
        #     if current > cap:
        #         # Once current exceeds cap, all subsequent values will be cap
        #         # But we need to be careful: if base is 0, current stays 0.
        #         # If base > 0, current grows.
        
        # This approach avoids computing 2**i directly and avoids overflow.
        
        # Let's implement this iterative approach.
        pass
    
    # Let me rewrite the function properly with the iterative approach.
    result = []
    current = base
    for i in range(attempts):
        value = min(cap, current)
        result.append(value)
        current *= 2
        # If current already exceeds cap, all future values will be cap
        # But we still need to append cap for remaining iterations
        # Actually, 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
    
    return result
```