
OK I'll have to rethink, and make sure everything other than arithmetic is supported for moved-from types.
Actually, in principle, a moved-from object should be a valid object, which just has an unspecified value. But computing x-x should be legal, unless it is documented that the type has a valid singular state (accessible by being moved from or swapped (=move-assigned)) and that all operations other than assignment have a precondition that the arguments are not singular. And then it is strange not to have a way to test if a value is singular.
Most uses of a moved-from object I can think of other than destruction and assignment are rather contrived. For a container, it can make sense to look at its size and assign to the elements. For a bignum, maybe if you are interested in an arbitrary number < y (to pass it to a nextafter-like function), before setting x to y-1, you could check if x<y and not want that to crash the program. If you are going to use a bignum as a bitfield, the same argument as for the container could be made.
The problem with your comparison example, is it's not clear whether the singular state is less than a non-singular value or not. Basically all operations are undefined. I think unless there are strong objections, I'll only support destruct-or-assign-to moved-from objects, and document that as a limitation. I can add asserts for the other operations, but basically I think that should be enough for the types to interoperate with the std lib.
Your remark about this making rvalue references useless is one that has been made a number of times and usually leads to the destructive move semantics proposal.
In this case, ideally gmp should have an empty state ("lazy allocation" in the projects page). In general, what to do with types that do not have an empty state is still a bit unclear. There is a proposal to add an overloadable library function that does a destructive move, but it wouldn't help here.
Understood, John.