```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 avoid overflow, check if 2**i * base > cap
            # If base is a float, we can compute step by step
            
            # Simple approach: if i is large enough that base * 2**i > cap, just use cap
            # We can check: if base * 2**i > cap, use cap
            # But computing 2**i as int then multiplying by float base could overflow
            
            # Better: compute iteratively or check bounds
            # 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 do this by checking if 2**i > cap / base
                # But cap / base could be problematic if base is very small
                # Alternative: compute value iteratively to avoid huge ints
                # Or: if i is large, 2**i is huge, so base * 2**i > cap (assuming base > 0 and cap is finite)
                
                # Let's compute base * 2**i safely
                # If base is an int, base * 2**i is an int, then min(cap, that_int)
                # If base is a float, base * 2**i could overflow when converting 2**i to float
                
                # Strategy: if base is int, compute as int, then compare with cap
                # If base is float, we need to be careful
                
                if isinstance(base, int):
                    val = base * (2 ** i)
                    delay = min(cap, val)
                else:
                    # base is float
                    # Check if 2**i * base > cap
                    # If i is large, 2**i is huge. If base > 0 and cap is finite, eventually exceeds cap
                    # We can check: if base * 2**i > cap
                    # To avoid overflow, check if 2**i > cap / base
                    # But cap / base might be inf or nan
                    # Simpler: compute iteratively
                    val = base
                    for _ in range(i):
                        val *= 2
                        if val > cap:
                            break
                    delay = min(cap, val)
        result.append(delay)
    return result
```