#include <cassert>
#include <string>
#include <vector>
#include <iostream>
int sign(int i)
{
return i < 0 ? -1 : i > 0 ? +1 : 0;
}
template<typename T>
int spaceship(T a, T b)
{
return a < b ? -123 : a > b ? +123 : 0;
}
std::string op(int cmp)
{
return cmp < 0 ? "<" : cmp > 0 ? ">" : "==";
}
template<typename T>
void test_spaceship(const std::vector<T> &elements)
{
bool error = false;
for (std::size_t i = 0; i < elements.size(); ++i) {
for (std::size_t j = 0; j < elements.size(); ++j) {
int expected = spaceship(i, j);
int actual = spaceship(elements[i], elements[j]);
if (sign(expected) != sign(actual)) {
std::cerr << __func__ << ":\n";
std::cerr << " expected " << elements[i] << " "
<< op(expected) << " " << elements[j] << "\n";
std::cerr << " but got " << elements[i] << " "
<< op(actual) << " " << elements[j] << "\n";
error = true;
}
}
}
std::flush(std::cerr);
assert(!error);
}
int main()
{
std::vector<std::string> elements{
"",
"first",
"second",
"zfourth", // intentionally in the wrong order
"third",
"zzfifth"
};
test_spaceship(elements);
std::cout << "ok\n";
std::string s;
std::getline(std::cin, s);
}
My other favorite topic is the cctype header since you must never feed a plain character to functions like isalnum
or toupper
. Furthermore by doing this, you limit your program to 8-bit character sets, unless CHAR_MAXCHAR_BIT
is greater than 8 on your machine, and chances are small for that.