```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
        else:
            # Check if base * 2**i exceeds cap
            # We need to compare base * 2**i with cap
            # Since cap is a float, we need to handle carefully
            # If 2**i is too large, base * 2**i will definitely exceed cap (if cap is finite)
            # But we need to avoid OverflowError when converting int to float
            
            # Approach: if base * 2**i > cap, use cap
            # To check this without overflow:
            # If base == 0, handled above
            # If cap == 0, delay is 0
            if cap == 0:
                delay = 0
            else:
                # Check if base * 2**i > cap
                # We can compute 2**i as int, then multiply by base
                # But base might be float, so base * 2**i could overflow when converting 2**i to float
                
                # Alternative: check if 2**i > cap / base (if base > 0)
                # But cap / base might be problematic if base is very small
                
                # Better approach: if base * 2**i would overflow, it's definitely > cap (assuming cap is finite)
                # So we can check: if 2**i is too large to convert to float, then base * 2**i > cap (since base > 0 and cap is finite)
                
                # Let's try to compute base * 2**i safely
                # If base is an int, base * 2**i is an int, and min(cap, ...) works if cap is float
                # But if base is float, base * 2**i requires converting 2**i to float, which can overflow
                
                # Strategy: 
                # - If base is int: base * 2**i is int, compare with cap (float). Python handles int vs float comparison fine.
                # - If base is float: we need to avoid overflow. Check if 2**i > cap / base.
                
                if isinstance(base, int):
                    val = base * (2 ** i)
                    delay = min(cap, val)
                else:
                    # base is float
                    # Check if 2**i > cap / base
                    # If base == 0, handled above
                    # cap / base could be inf if base is very small, but that's fine
                    # If 2**i > cap / base, then base * 2**i > cap, so delay = cap
                    # Otherwise, base * 2**i <= cap, so delay = base * 2**i
                    
                    # To check 2**i > cap / base without overflow:
                    # If cap / base is inf, then 2**i > inf is false, so we compute base * 2**i
                    # But base * 2**i might overflow...
                    
                    # Let's think differently:
                    # If base * 2**i > cap, delay = cap
                    # If base * 2**i <= cap, delay = base * 2**i
                    
                    # For float base, base * 2**i can overflow if 2**i is too large
                    # But if 2**i is too large, base * 2**i > cap (since cap is finite), so delay = cap
                    
                    # So: if 2**i is too large to convert to float, delay = cap
                    # Otherwise, compute base * 2**i and compare with cap
                    
                    try:
                        val = base * (2 ** i)
                        delay = min(cap, val)
                    except OverflowError:
                        delay = cap
        result.append(delay)
    return result
```