Ignoring the tags (which not everything uses) it's possible to express all of those as a single increasing number by simply putting enough zeros in, which does make them representable as simple numbers, so I think you're kinda splitting hairs. Most version number representations/libraries will likely do something similar to read it anyway even if you keep it a string - split it into separate individual numbers and compare major/minor/patch/etc separately, and by virtue of fitting the individual parts into separate integers you're giving them all a maximum value, which is what the zeros would do.
The problem is they shoved the individual parts into a single 32-bit integer, which just isn't enough space so they had to compromise and make some of the numbers have extremely small ranges.
There are exceptions to that rule, however - Maintenance releases. Node, Typescript, Java, .NET, and I'm sure many more obvious instances I need not list.
If you "just" increment you leave no room for showing patching in your versioning strategy.
I'm not entirely sure what you're getting at? That's the point of the `feature` and `patch` version numbers. If you want you can put a 4th or 5th number in there as well to fit whatever uses you have.
Perhaps you're missing what I meant by 'increasing' - it's just a 1:1 conversion of the version number to a single integer, it's not like you're assigning every version a new number. 3.9.3 would become something like 3009003, and 3.10.1 would become 3010001. If you compare those representations then 3010001 always compares higher, and there's also nothing preventing you from releasing 3.9.3 after 3.10.1.
My point was that doing a format like the above (major, 3 digit minor, 3 digit patch) is not fundamentally different from storing each individual number as it's own integer, which most version libraries I've seen do at some point. The problem is just that the range of each number is restricted significantly by requiring 3 digits rather than if you used individual 32-bit or 16-bit integers for each one.
The problem is they shoved the individual parts into a single 32-bit integer, which just isn't enough space so they had to compromise and make some of the numbers have extremely small ranges.