ranges: allow leaving a number empty, support swapping min/max