```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 converting huge int to float
        # If base is 0, delay is 0
        if base == 0:
            delay = 0.0
        else:
            # Check if base * 2**i exceeds cap
            # We need to compare base * 2**i with cap without overflow
            # Since cap is a float, we can compute 2**i as int, then multiply by base
            # But base * 2**i could be huge. Instead, check if 2**i > cap / base
            # to avoid computing huge int * float
            
            # Handle base == 0 separately (already done above)
            # For base > 0:
            # delay = min(cap, base * 2**i)
            # If base * 2**i >= cap, delay = cap
            # Otherwise delay = base * 2**i
            
            # To avoid overflow, check if 2**i > cap / base
            # cap / base is a float. If base is very small, cap/base could be huge.
            # But 2**i as int can be huge. We need to compare int 2**i with float cap/base.
            # Python can compare int and float, but converting huge int to float may overflow.
            
            # Alternative: compute delay step by step, capping early.
            # Start with delay = base, multiply by 2 each step, cap at cap.
            # This avoids huge intermediate values.
            pass
        
        # Better approach: iterative computation with early cap
        # Start from i=0, delay = base
        # For each i, delay = min(cap, delay * 2)
        # This avoids computing 2**i directly as huge int
        
        # Let's restructure:
        delay = base
        for i in range(attempts):
            if delay >= cap:
                result.append(cap)
            else:
                result.append(delay)
                delay = delay * 2
                if delay > cap:
                    delay = cap
        return result
```