Hmm, good thoughts.
The whole point of the macro and the comment is to explain what is happening, and leave the high-level abstraction alone.
8 9 10 11 12 13
|
// At this point, we know that the signs are the same.
// Since 7 < 12 is TRUE
// and -7 < -12 is FALSE
// we'll use the sign of the numbers as a proxy for FALSE or TRUE
// when we return to the caller.
#define F( x ) (x) ? !sign : sign
|
It is all explained nicely. Thereafter, the reader only need concern himself with the given function of the operator: is this < that?
20 21
|
if (this->length() != that.length())
return F( this->length() < that.length() );
|
35 36
|
// Finally
return F( *(iters.first) < *(iters.second) );
|
This reads and does exactly like you would expect. Is this < that? (Plus the known caveat that the sign counts.) The whole thing fits on the screen at once, including commentary.
I am still not convinced that using a function (albeit in the form of a macro) undermines the readability of the code, as much as would looking at all the extra stuff on the line to play with the sign bit (wait, why am I twiddling with the sign again?) Define once and reuse. I have learned the hard way to keep weird stuff in
one spot and to simply reference it -- even if the function is a write-once kind of thing.
It is true that this may force a lookup, but in this case all the reader has to do is look up to the top of his text display where the macro is defined (and which, presuming he processes language from top to bottom like all other extant humans, he has already read).
As you may surmise, I don't like to break abstraction unless explicitly. (Especially since it overloads
my brain when too many things are happening in one reading.)
But, do you think
#define F
...
#undef F
would likely clash with anything? Is this a reasonable conclusion or is professional code too unreliable to trust that some moron hasn't got an 'F' defined across files somewhere?
Thank you for the commentary and interest. :-)