// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkObject.h" #include "vtkVariant.h" #include #include #include int TestVariantComparison(int, char*[]) { signed char positiveChar = 100; signed char negativeChar = -100; short positiveShort = 10000; short negativeShort = -10000; int positiveInt = 100000; int negativeInt = -100000; long positiveLong = 1000000; long negativeLong = -1000000; int shiftAmount64 = 8 * sizeof(vtkTypeInt64) - 2; int shiftAmountInt = 8 * sizeof(int) - 2; int shiftAmountLong = 8 * sizeof(long) - 2; vtkTypeInt64 positive64 = static_cast(1) << shiftAmount64; vtkTypeInt64 negative64 = -positive64; // There is nothing inherently magical about these values. I just // happen to like them and they're outside the range of signed // integers. unsigned char unsignedChar = 192; unsigned short unsignedShort = 49152; unsigned int unsignedInt = (static_cast(1) << shiftAmountInt) * 3; unsigned long unsignedLong = (static_cast(1) << shiftAmountLong) * 3; vtkTypeUInt64 unsigned64 = 3 * (static_cast(1) << shiftAmount64); std::string numberString("100000"); std::string alphaString("ABCDEFG"); float positiveFloat = 12345.678; float negativeFloat = -12345.678; double positiveDouble = 123456789.012345; double negativeDouble = -123456789.012345; vtkObject* fooObject = vtkObject::New(); vtkVariant invalidVariant; // Now we need variants for all of those vtkVariant positiveCharVariant(positiveChar); vtkVariant unsignedCharVariant(unsignedChar); vtkVariant negativeCharVariant(negativeChar); vtkVariant positiveShortVariant(positiveShort); vtkVariant unsignedShortVariant(unsignedShort); vtkVariant negativeShortVariant(negativeShort); vtkVariant positiveIntVariant(positiveInt); vtkVariant unsignedIntVariant(unsignedInt); vtkVariant negativeIntVariant(negativeInt); vtkVariant positiveLongVariant(positiveLong); vtkVariant unsignedLongVariant(unsignedLong); vtkVariant negativeLongVariant(negativeLong); vtkVariant positive64Variant(positive64); vtkVariant unsigned64Variant(unsigned64); vtkVariant negative64Variant(negative64); vtkVariant positiveFloatVariant(positiveFloat); vtkVariant negativeFloatVariant(negativeFloat); vtkVariant positiveDoubleVariant(positiveDouble); vtkVariant negativeDoubleVariant(negativeDouble); vtkVariant numberStringVariant(numberString); vtkVariant alphaStringVariant(alphaString); vtkVariant fooObjectVariant(fooObject); int errorCount = 0; int overallErrorCount = 0; #define CHECK_EXPRESSION_FALSE(expr) \ do \ { \ if ((expr)) \ { \ ++errorCount; \ std::cerr << "TEST FAILED: " << #expr << " should have been false\n\n"; \ } \ } while (false) #define CHECK_EXPRESSION_TRUE(expr) \ do \ { \ if (!(expr)) \ { \ ++errorCount; \ std::cerr << "TEST FAILED: " << #expr << " should have been true\n\n"; \ } \ } while (false) std::cerr << "Testing same-type comparisons... "; CHECK_EXPRESSION_FALSE(positiveCharVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(unsignedCharVariant < positiveCharVariant); CHECK_EXPRESSION_FALSE(unsignedCharVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positiveShortVariant < negativeShortVariant); CHECK_EXPRESSION_FALSE(unsignedShortVariant < positiveShortVariant); CHECK_EXPRESSION_FALSE(unsignedShortVariant < negativeShortVariant); CHECK_EXPRESSION_FALSE(positiveIntVariant < negativeIntVariant); CHECK_EXPRESSION_FALSE(unsignedIntVariant < positiveIntVariant); CHECK_EXPRESSION_FALSE(unsignedIntVariant < negativeIntVariant); CHECK_EXPRESSION_FALSE(positiveLongVariant < negativeLongVariant); CHECK_EXPRESSION_FALSE(unsignedLongVariant < positiveLongVariant); CHECK_EXPRESSION_FALSE(unsignedLongVariant < negativeLongVariant); CHECK_EXPRESSION_FALSE(positive64Variant < negative64Variant); CHECK_EXPRESSION_FALSE(unsigned64Variant < positive64Variant); CHECK_EXPRESSION_FALSE(unsigned64Variant < negative64Variant); CHECK_EXPRESSION_FALSE(positiveFloatVariant < negativeFloatVariant); CHECK_EXPRESSION_FALSE(positiveDoubleVariant < negativeDoubleVariant); CHECK_EXPRESSION_FALSE(alphaString < numberString); if (errorCount == 0) { std::cerr << "Test succeeded.\n"; } else { std::cerr << errorCount << " error(s) found!\n"; } overallErrorCount += errorCount; errorCount = 0; std::cerr << "Testing cross-type comparisons... "; CHECK_EXPRESSION_FALSE(positiveShortVariant < positiveCharVariant); CHECK_EXPRESSION_FALSE(positiveIntVariant < positiveCharVariant); CHECK_EXPRESSION_FALSE(positiveLongVariant < positiveCharVariant); CHECK_EXPRESSION_FALSE(positive64Variant < positiveCharVariant); CHECK_EXPRESSION_FALSE(positiveShortVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positiveIntVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positiveLongVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positive64Variant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positiveShortVariant < unsignedCharVariant); CHECK_EXPRESSION_FALSE(positiveIntVariant < unsignedCharVariant); CHECK_EXPRESSION_FALSE(positiveLongVariant < unsignedCharVariant); CHECK_EXPRESSION_FALSE(positive64Variant < unsignedCharVariant); CHECK_EXPRESSION_FALSE(negativeCharVariant < negativeShortVariant); CHECK_EXPRESSION_FALSE(negativeCharVariant < negativeIntVariant); CHECK_EXPRESSION_FALSE(negativeCharVariant < negativeLongVariant); CHECK_EXPRESSION_FALSE(negativeCharVariant < negative64Variant); CHECK_EXPRESSION_FALSE(unsignedShortVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(unsignedIntVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(unsignedLongVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(unsigned64Variant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positiveFloatVariant < positiveCharVariant); CHECK_EXPRESSION_FALSE(positiveFloatVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positiveFloatVariant < unsignedCharVariant); CHECK_EXPRESSION_FALSE(positiveDoubleVariant < positiveCharVariant); CHECK_EXPRESSION_FALSE(positiveDoubleVariant < negativeCharVariant); CHECK_EXPRESSION_FALSE(positiveDoubleVariant < unsignedCharVariant); CHECK_EXPRESSION_FALSE(alphaStringVariant < positiveIntVariant); CHECK_EXPRESSION_FALSE(numberStringVariant != positiveIntVariant); CHECK_EXPRESSION_FALSE(positiveDoubleVariant < fooObjectVariant); CHECK_EXPRESSION_FALSE(positiveFloatVariant < invalidVariant); if (errorCount == 0) { std::cerr << "Test succeeded.\n"; } else { std::cerr << errorCount << " error(s) found!\n"; } overallErrorCount += errorCount; errorCount = 0; std::cerr << "Testing cross-type equality..."; char c = 100; short s = 100; int i = 100; long l = 100; vtkTypeInt64 i64 = 100; float f = 100; double d = 100; std::string str("100"); CHECK_EXPRESSION_TRUE(vtkVariant(c) == vtkVariant(s)); CHECK_EXPRESSION_TRUE(vtkVariant(c) == vtkVariant(i)); CHECK_EXPRESSION_TRUE(vtkVariant(c) == vtkVariant(l)); CHECK_EXPRESSION_TRUE(vtkVariant(c) == vtkVariant(i64)); CHECK_EXPRESSION_TRUE(vtkVariant(c) == vtkVariant(f)); CHECK_EXPRESSION_TRUE(vtkVariant(c) == vtkVariant(d)); CHECK_EXPRESSION_TRUE(vtkVariant(s) == vtkVariant(i)); CHECK_EXPRESSION_TRUE(vtkVariant(s) == vtkVariant(l)); CHECK_EXPRESSION_TRUE(vtkVariant(s) == vtkVariant(i64)); CHECK_EXPRESSION_TRUE(vtkVariant(s) == vtkVariant(f)); CHECK_EXPRESSION_TRUE(vtkVariant(s) == vtkVariant(d)); CHECK_EXPRESSION_TRUE(vtkVariant(s) == vtkVariant(str)); CHECK_EXPRESSION_TRUE(vtkVariant(i) == vtkVariant(l)); CHECK_EXPRESSION_TRUE(vtkVariant(i) == vtkVariant(i64)); CHECK_EXPRESSION_TRUE(vtkVariant(i) == vtkVariant(f)); CHECK_EXPRESSION_TRUE(vtkVariant(i) == vtkVariant(d)); CHECK_EXPRESSION_TRUE(vtkVariant(i) == vtkVariant(str)); CHECK_EXPRESSION_TRUE(vtkVariant(l) == vtkVariant(i64)); CHECK_EXPRESSION_TRUE(vtkVariant(l) == vtkVariant(f)); CHECK_EXPRESSION_TRUE(vtkVariant(l) == vtkVariant(d)); CHECK_EXPRESSION_TRUE(vtkVariant(l) == vtkVariant(str)); CHECK_EXPRESSION_TRUE(vtkVariant(i64) == vtkVariant(f)); CHECK_EXPRESSION_TRUE(vtkVariant(i64) == vtkVariant(d)); CHECK_EXPRESSION_TRUE(vtkVariant(i64) == vtkVariant(str)); CHECK_EXPRESSION_TRUE(vtkVariant(f) == vtkVariant(d)); CHECK_EXPRESSION_TRUE(vtkVariant(f) == vtkVariant(str)); CHECK_EXPRESSION_TRUE(vtkVariant(d) == vtkVariant(str)); if (errorCount == 0) { std::cerr << " Test succeeded.\n"; } else { std::cerr << errorCount << " error(s) found!\n"; } overallErrorCount += errorCount; errorCount = 0; std::cerr << "Testing vtkVariant as STL map key... "; std::map TestMap; TestMap[vtkVariant(s)] = "short"; TestMap[vtkVariant(i)] = "int"; TestMap[vtkVariant(l)] = "long"; TestMap[vtkVariant(i64)] = "int64"; TestMap[vtkVariant(f)] = "float"; TestMap[vtkVariant(d)] = "double"; TestMap[vtkVariant(str)] = "string"; CHECK_EXPRESSION_TRUE(TestMap.find(vtkVariant(100)) != TestMap.end()); CHECK_EXPRESSION_TRUE(TestMap[vtkVariant(100)] == "string"); CHECK_EXPRESSION_TRUE(TestMap.size() == 1); if (errorCount == 0) { std::cerr << " Test succeeded.\n"; } else { std::cerr << errorCount << " error(s) found!\n"; } overallErrorCount += errorCount; errorCount = 0; std::cerr << "Testing vtkVariant as STL map key with strict weak ordering (fast comparator)..."; // This one should treat variants containing different types as // unequal. std::map TestMap2; TestMap2[vtkVariant()] = "invalid"; TestMap2[vtkVariant(s)] = "short"; TestMap2[vtkVariant(i)] = "int"; TestMap2[vtkVariant(l)] = "long"; TestMap2[vtkVariant(i64)] = "int64"; TestMap2[vtkVariant(f)] = "float"; TestMap2[vtkVariant(d)] = "double"; TestMap2[vtkVariant(str)] = "string"; CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant()) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant()] == "invalid"); CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant(s)) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant(s)] == "short"); CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant(i)) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant(i)] == "int"); CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant(l)) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant(l)] == "long"); CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant(i64)) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant(i64)] == "int64"); CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant(f)) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant(f)] == "float"); CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant(d)) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant(d)] == "double"); CHECK_EXPRESSION_TRUE(TestMap2.find(vtkVariant(str)) != TestMap2.end()); CHECK_EXPRESSION_TRUE(TestMap2[vtkVariant("100")] == "string"); CHECK_EXPRESSION_TRUE(TestMap2.size() == 8); if (errorCount == 0) { std::cerr << " Test succeeded.\n"; } else { std::cerr << errorCount << " error(s) found!\n"; } overallErrorCount += errorCount; if (overallErrorCount == 0) { std::cerr << "All tests succeeded.\n"; } else { std::cerr << "Some tests failed! Overall error count: " << overallErrorCount << "\n"; std::cerr << "Debug information:\n"; std::cerr << "CHAR(" << sizeof(char) << "): " << "positive " << positiveChar << ", " << "negative " << negativeChar << ", " << "unsigned " << unsignedChar << "\n"; std::cerr << "SHORT(" << sizeof(short) << "): " << "positive " << positiveShort << ", " << "negative " << negativeShort << ", " << "unsigned " << unsignedShort << "\n"; std::cerr << "INT(" << sizeof(int) << "): " << "positive " << positiveInt << ", " << "negative " << negativeInt << ", " << "unsigned " << unsignedInt << "\n"; std::cerr << "LONG(" << sizeof(long) << "): " << "positive " << positiveLong << ", " << "negative " << negativeLong << ", " << "unsigned " << unsignedLong << "\n"; std::cerr << "INT64(" << sizeof(vtkTypeInt64) << "): " << "positive " << positive64 << ", " << "negative " << negative64 << ", " << "unsigned " << unsigned64 << "\n"; } fooObject->Delete(); return (overallErrorCount > 0); }