```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):
        # Avoid computing 2**i as a huge int that can't convert to float
        # Instead, compute base * 2**i carefully
        # If base == 0, then base * 2**i == 0 for all i
        if base == 0:
            value = 0.0
        else:
            # Compute base * 2**i without creating huge ints
            # We can use logarithms or iterative multiplication
            # But simpler: if 2**i is too large, the result will exceed cap
            # So we can check if base * 2**i > cap without computing the full value
            # Use: if i is large enough that base * 2**i > cap, then value = cap
            # We need to determine when base * 2**i > cap
            
            # If base > 0 and cap > 0, find the smallest i where base * 2**i > cap
            # base * 2**i > cap => 2**i > cap / base => i > log2(cap / base)
            # But we need to handle edge cases
            
            # Simpler approach: iteratively compute, but stop early if value >= cap
            # Actually, let's just compute step by step to avoid huge ints
            
            # Start with current = base
            # For each i, current = base * 2**i
            # We can track current iteratively
            
            # Let's use an iterative approach
            pass
        
        # Let me redo this properly
        # Use iterative computation to avoid huge integers
        # current = base * 2**i, but compute incrementally
        
        # Actually, let's just use a different approach:
        # For each i, compute base * 2**i but check if it exceeds cap first
        # If base == 0, value = 0
        # If base > 0, we can compute 2**i as float if i is small, or check bounds
        
        # Better: use math.log2 to determine if base * 2**i > cap
        # But we can't import math... wait, math is standard library, not third-party
        
        # Let me use a simple iterative approach without huge ints
        # current_value = base
        # For i=0: value = min(cap, base)
        # For i=1: value = min(cap, base * 2)
        # For i=2: value = min(cap, base * 4)
        # etc.
        
        # We can compute iteratively:
        # current = base
        # for i in range(attempts):
        #   value = min(cap, current)
        #   result.append(value)
        #   current *= 2
        #   if current > cap and base > 0:
        #     # all subsequent values will be cap
        #     for j in range(i+1, attempts):
        #       result.append(cap)
        #     break
        
        # But we need to handle base == 0 separately
        
        # Let me restructure the whole function
        pass
    
    # Redo properly
    result = []
    if base == 0:
        for i in range(attempts):
            result.append(0.0)
        return result
    
    current = base
    for i in range(attempts):
        value = min(cap, current)
        result.append(value)
        if current >= cap:
            # All remaining values are cap
            for j in range(i + 1, attempts):
                result.append(cap)
            break
        current *= 2
    
    return result
```