```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 would cause base * 2**i > cap
        # We can avoid computing huge 2**i by comparing incrementally
        # If base * 2**i >= cap, then min(cap, base * 2**i) = cap
        # We need to check if 2**i >= cap / base
        # But cap/base might not be an integer. Use float comparison carefully.
        # Alternative: compute value step by step, but cap the multiplication.
        # Since we need min(cap, base * 2**i), we can compute iteratively:
        # Start with current = base, and for each i, current *= 2, but cap at cap.
        # This avoids huge numbers.
        pass
    
    # Better approach: iterative computation with capping
    result = []
    current = base
    for i in range(attempts):
        val = min(cap, current)
        result.append(val)
        current *= 2
        if current > cap:
            # Once current exceeds cap, all subsequent values will be cap
            # But we still need to append cap for remaining iterations
            # Actually, we can just fill the rest with cap
            for _ in range(i + 1, attempts):
                result.append(cap)
            break
    return result
```