```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:
            value = 0.0
        else:
            # If 2**i * base > cap, then min(cap, base*2**i) = cap
            # We can check: if 2**i > cap / base, then value = cap
            # But cap/base might be float; handle carefully
            # Alternative: compute iteratively to avoid huge ints
            # Use iterative doubling to avoid huge integer exponentiation
            pass
        
        # Better approach: iterative computation to avoid huge ints
        # Start with current = base, then double each step, but cap at cap
        # This avoids computing 2**i as a huge int
        
    # Redo with iterative approach
    result = []
    current = base
    for i in range(attempts):
        value = min(cap, current)
        result.append(value)
        current *= 2
        # If current already exceeds cap, it will stay capped, but we still need to append cap for remaining
        # Actually, once current >= cap, all subsequent values are cap
        # But we must still append cap for each remaining iteration
        # However, current *= 2 could overflow if current is huge... but if current >= cap, we can just append cap
        # Let's handle: if current >= cap, then for all remaining i, value = cap
        # But we need to be careful: current might be float, and multiplying by 2 repeatedly is fine for floats
        # However, if base is 0, current stays 0
        # If base > 0, current doubles each time. Once current >= cap, all future values are cap.
        # But we must not let current grow unbounded as a float (it won't overflow for reasonable caps)
        # Actually, if cap is very large, current could overflow as float. But the problem says cap is non-negative.
        # To be safe, once current >= cap, we can just append cap for all remaining iterations.
    
    # Let me rewrite cleanly:
    result = []
    current = base
    for i in range(attempts):
        if current >= cap:
            # All remaining values are cap
            result.extend([cap] * (attempts - i))
            break
        value = min(cap, current)
        result.append(value)
        current *= 2
    
    return result
```