blob: 1f812e9f8a311c002565c9d67ed05548a0d2e963 [file] [edit]
/*
* Copyright 2026 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdint>
#include <limits>
#include <sstream>
#include <vector>
#include "support/iu64.h"
#include "gtest/gtest.h"
using namespace wasm;
TEST(IU64Test, DefaultConstruct) {
IU64 x;
EXPECT_EQ(x.value, 0u);
EXPECT_FALSE(x.negative);
EXPECT_EQ(x, IU64(0));
}
TEST(IU64Test, ConstructFromUnsigned32) {
uint32_t zero = 0;
uint32_t one = 1;
uint32_t mid = 12345678;
uint32_t maxU32 = std::numeric_limits<uint32_t>::max();
IU64 iZero(zero);
EXPECT_EQ(iZero.value, 0u);
EXPECT_FALSE(iZero.negative);
IU64 iOne(one);
EXPECT_EQ(iOne.value, 1u);
EXPECT_FALSE(iOne.negative);
IU64 iMid(mid);
EXPECT_EQ(iMid.value, mid);
EXPECT_FALSE(iMid.negative);
IU64 iMax(maxU32);
EXPECT_EQ(iMax.value, uint64_t(maxU32));
EXPECT_FALSE(iMax.negative);
}
TEST(IU64Test, ConstructFromSigned32) {
int32_t zero = 0;
int32_t one = 1;
int32_t maxI32 = std::numeric_limits<int32_t>::max();
int32_t negOne = -1;
int32_t negMid = -12345678;
int32_t minI32 = std::numeric_limits<int32_t>::min();
IU64 iZero(zero);
EXPECT_EQ(iZero.value, 0u);
EXPECT_FALSE(iZero.negative);
IU64 iOne(one);
EXPECT_EQ(iOne.value, 1u);
EXPECT_FALSE(iOne.negative);
IU64 iMax(maxI32);
EXPECT_EQ(iMax.value, uint64_t(maxI32));
EXPECT_FALSE(iMax.negative);
IU64 iNegOne(negOne);
EXPECT_EQ(iNegOne.value, 1u);
EXPECT_TRUE(iNegOne.negative);
IU64 iNegMid(negMid);
EXPECT_EQ(iNegMid.value, 12345678u);
EXPECT_TRUE(iNegMid.negative);
IU64 iMin(minI32);
EXPECT_EQ(iMin.value, 2147483648ULL);
EXPECT_TRUE(iMin.negative);
}
TEST(IU64Test, ConstructFromUnsigned64) {
uint64_t zero = 0;
uint64_t one = 1;
uint64_t maxU32 = std::numeric_limits<uint32_t>::max();
uint64_t maxI64 = std::numeric_limits<int64_t>::max();
uint64_t highBitOnly = uint64_t(1) << 63;
uint64_t maxU64 = std::numeric_limits<uint64_t>::max();
IU64 iZero(zero);
EXPECT_EQ(iZero.value, 0u);
EXPECT_FALSE(iZero.negative);
IU64 iOne(one);
EXPECT_EQ(iOne.value, 1u);
EXPECT_FALSE(iOne.negative);
IU64 iMaxU32(maxU32);
EXPECT_EQ(iMaxU32.value, maxU32);
EXPECT_FALSE(iMaxU32.negative);
IU64 iMaxI64(maxI64);
EXPECT_EQ(iMaxI64.value, maxI64);
EXPECT_FALSE(iMaxI64.negative);
IU64 iHighBit(highBitOnly);
EXPECT_EQ(iHighBit.value, highBitOnly);
EXPECT_FALSE(iHighBit.negative);
IU64 iMaxU64(maxU64);
EXPECT_EQ(iMaxU64.value, maxU64);
EXPECT_FALSE(iMaxU64.negative);
}
TEST(IU64Test, ConstructFromSigned64) {
int64_t zero = 0;
int64_t one = 1;
int64_t maxI64 = std::numeric_limits<int64_t>::max();
int64_t negOne = -1;
int64_t minI64 = std::numeric_limits<int64_t>::min();
int64_t minI64PlusOne = std::numeric_limits<int64_t>::min() + 1;
IU64 iZero(zero);
EXPECT_EQ(iZero.value, 0u);
EXPECT_FALSE(iZero.negative);
IU64 iOne(one);
EXPECT_EQ(iOne.value, 1u);
EXPECT_FALSE(iOne.negative);
IU64 iMax(maxI64);
EXPECT_EQ(iMax.value, uint64_t(maxI64));
EXPECT_FALSE(iMax.negative);
IU64 iNegOne(negOne);
EXPECT_EQ(iNegOne.value, 1u);
EXPECT_TRUE(iNegOne.negative);
IU64 iMin(minI64);
EXPECT_EQ(iMin.value, uint64_t(1) << 63);
EXPECT_TRUE(iMin.negative);
IU64 iMinPlusOne(minI64PlusOne);
EXPECT_EQ(iMinPlusOne.value, uint64_t(std::numeric_limits<int64_t>::max()));
EXPECT_TRUE(iMinPlusOne.negative);
}
TEST(IU64Test, EqualityAndInequality) {
EXPECT_EQ(IU64(int32_t(0)), IU64(uint32_t(0)));
EXPECT_EQ(IU64(int32_t(0)), IU64(int64_t(0)));
EXPECT_EQ(IU64(int32_t(0)), IU64(uint64_t(0)));
EXPECT_EQ(IU64(int32_t(42)), IU64(uint32_t(42)));
EXPECT_EQ(IU64(int32_t(42)), IU64(int64_t(42)));
EXPECT_EQ(IU64(int32_t(42)), IU64(uint64_t(42)));
EXPECT_EQ(IU64(int32_t(-42)), IU64(int64_t(-42)));
EXPECT_EQ(IU64(std::numeric_limits<int32_t>::min()),
IU64(int64_t(std::numeric_limits<int32_t>::min())));
EXPECT_NE(IU64(int32_t(1)), IU64(int32_t(-1)));
EXPECT_NE(IU64(uint64_t(0xffffffffffffffffULL)), IU64(int64_t(-1)));
EXPECT_NE(IU64(std::numeric_limits<int64_t>::min()), IU64(uint64_t(1) << 63));
}
TEST(IU64Test, TotalOrdering) {
std::vector<IU64> sortedValues = {
IU64(std::numeric_limits<int64_t>::min()),
IU64(std::numeric_limits<int64_t>::min() + 1),
IU64(int64_t(-0x100000000LL)),
IU64(std::numeric_limits<int32_t>::min()),
IU64(int32_t(-12345)),
IU64(int64_t(-2)),
IU64(int64_t(-1)),
IU64(0),
IU64(1),
IU64(2),
IU64(int32_t(12345)),
IU64(std::numeric_limits<int32_t>::max()),
IU64(uint64_t(std::numeric_limits<int32_t>::max()) + 1),
IU64(std::numeric_limits<uint32_t>::max()),
IU64(uint64_t(std::numeric_limits<uint32_t>::max()) + 1),
IU64(std::numeric_limits<int64_t>::max() - 1),
IU64(std::numeric_limits<int64_t>::max()),
IU64(uint64_t(std::numeric_limits<int64_t>::max()) + 1),
IU64(std::numeric_limits<uint64_t>::max() - 1),
IU64(std::numeric_limits<uint64_t>::max()),
};
for (size_t i = 0; i < sortedValues.size(); ++i) {
for (size_t j = 0; j < sortedValues.size(); ++j) {
const auto& a = sortedValues[i];
const auto& b = sortedValues[j];
if (i < j) {
EXPECT_LT(a, b);
EXPECT_LE(a, b);
EXPECT_GT(b, a);
EXPECT_GE(b, a);
EXPECT_NE(a, b);
EXPECT_FALSE(a == b);
EXPECT_FALSE(b < a);
} else if (i == j) {
EXPECT_EQ(a, b);
EXPECT_LE(a, b);
EXPECT_GE(a, b);
EXPECT_FALSE(a < b);
EXPECT_FALSE(a > b);
EXPECT_FALSE(a != b);
} else {
EXPECT_GT(a, b);
EXPECT_GE(a, b);
EXPECT_LT(b, a);
EXPECT_LE(b, a);
EXPECT_NE(a, b);
EXPECT_FALSE(a == b);
EXPECT_FALSE(a < b);
}
}
}
}
TEST(IU64Test, NumericLimits) {
EXPECT_TRUE(std::numeric_limits<IU64>::is_specialized);
EXPECT_TRUE(std::numeric_limits<IU64>::is_signed);
EXPECT_TRUE(std::numeric_limits<IU64>::is_integer);
EXPECT_EQ(std::numeric_limits<IU64>::min(),
IU64(std::numeric_limits<int64_t>::min()));
EXPECT_EQ(std::numeric_limits<IU64>::lowest(),
IU64(std::numeric_limits<int64_t>::min()));
EXPECT_EQ(std::numeric_limits<IU64>::max(),
IU64(std::numeric_limits<uint64_t>::max()));
}
TEST(IU64Test, StreamOutput) {
auto toString = [](const IU64& x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
EXPECT_EQ(toString(IU64(0)), "0");
EXPECT_EQ(toString(IU64(42)), "42");
EXPECT_EQ(toString(IU64(-42)), "-42");
EXPECT_EQ(toString(IU64(std::numeric_limits<int64_t>::min())),
"-9223372036854775808");
EXPECT_EQ(toString(IU64(std::numeric_limits<uint64_t>::max())),
"18446744073709551615");
}