diff --git a/ml_dtypes/include/intn.h b/ml_dtypes/include/intn.h index 5d0311f1..e201fd97 100644 --- a/ml_dtypes/include/intn.h +++ b/ml_dtypes/include/intn.h @@ -241,7 +241,9 @@ struct intN { } }; +using int1 = intN<1, int8_t>; using int2 = intN<2, int8_t>; +using uint1 = intN<1, uint8_t>; using uint2 = intN<2, uint8_t>; using int4 = intN<4, int8_t>; using uint4 = intN<4, uint8_t>; @@ -295,6 +297,12 @@ struct intN_numeric_limits_base { namespace std { +template <> +struct numeric_limits + : public ml_dtypes::internal::intN_numeric_limits_base {}; +template <> +struct numeric_limits + : public ml_dtypes::internal::intN_numeric_limits_base {}; template <> struct numeric_limits : public ml_dtypes::internal::intN_numeric_limits_base {}; diff --git a/ml_dtypes/tests/intn_test.cc b/ml_dtypes/tests/intn_test.cc index 14694f8a..55866306 100644 --- a/ml_dtypes/tests/intn_test.cc +++ b/ml_dtypes/tests/intn_test.cc @@ -58,7 +58,7 @@ struct IntNTestParamNames { } }; -using IntNTypes = ::testing::Types; +using IntNTypes = ::testing::Types; TYPED_TEST_SUITE(IntNTest, IntNTypes, IntNTestParamNames); TEST(IntNTest, NumericLimits) { @@ -69,6 +69,13 @@ TEST(IntNTest, NumericLimits) { EXPECT_EQ(static_cast(std::numeric_limits::lowest()), -8); EXPECT_EQ(std::numeric_limits::digits, 3); EXPECT_EQ(std::numeric_limits::digits10, 0); + EXPECT_EQ(std::numeric_limits::is_signed, true); + EXPECT_EQ(std::numeric_limits::is_modulo, false); + EXPECT_EQ(static_cast(std::numeric_limits::min()), -1); + EXPECT_EQ(static_cast(std::numeric_limits::max()), 0); + EXPECT_EQ(static_cast(std::numeric_limits::lowest()), -1); + EXPECT_EQ(std::numeric_limits::digits, 0); + EXPECT_EQ(std::numeric_limits::digits10, 0); } TEST(UIntNTest, NumericLimits) { @@ -79,6 +86,13 @@ TEST(UIntNTest, NumericLimits) { EXPECT_EQ(static_cast(std::numeric_limits::lowest()), 0); EXPECT_EQ(std::numeric_limits::digits, 4); EXPECT_EQ(std::numeric_limits::digits10, 1); + EXPECT_EQ(std::numeric_limits::is_signed, false); + EXPECT_EQ(std::numeric_limits::is_modulo, true); + EXPECT_EQ(static_cast(std::numeric_limits::min()), 0); + EXPECT_EQ(static_cast(std::numeric_limits::max()), 1); + EXPECT_EQ(static_cast(std::numeric_limits::lowest()), 0); + EXPECT_EQ(std::numeric_limits::digits, 1); + EXPECT_EQ(std::numeric_limits::digits10, 0); } TYPED_TEST(IntNTest, NumericLimitsBase) { @@ -141,7 +155,7 @@ struct ConstexprEvaluator { }; // To avoid warnings about unused left-side of comma expressions, -// we additionally pass the expression through a contexpr function. +// we additionally pass the expression through a constexpr function. template constexpr void ConstexprEvaluatorFunc(T&&) {} @@ -211,8 +225,8 @@ TYPED_TEST(IntNTest, Casts) { } // Implicit conversion to optional. - std::optional c = IntN(1); - EXPECT_EQ(c, 1); + std::optional c = IntN(0); + EXPECT_EQ(c, 0); // Loop through all valid values. for (int i = static_cast(std::numeric_limits::min()); @@ -329,17 +343,18 @@ struct CustomInt { int x; }; -#define GEN_DEST_TYPES(Type) \ - std::pair, std::pair, std::pair, \ - std::pair, std::pair, \ - std::pair, std::pair, \ - std::pair, std::pair, std::pair, \ - std::pair, std::pair, \ +#define GEN_DEST_TYPES(Type) \ + std::pair, std::pair, std::pair, \ + std::pair, std::pair, \ + std::pair, std::pair, \ + std::pair, std::pair, std::pair, \ + std::pair, std::pair, \ + std::pair, std::pair, \ std::pair, std::pair #define GEN_TYPE_PAIRS() \ - GEN_DEST_TYPES(int2), GEN_DEST_TYPES(uint2), GEN_DEST_TYPES(int4), \ - GEN_DEST_TYPES(uint4) + GEN_DEST_TYPES(int1), GEN_DEST_TYPES(uint1), GEN_DEST_TYPES(int2), \ + GEN_DEST_TYPES(uint2), GEN_DEST_TYPES(int4), GEN_DEST_TYPES(uint4) using IntNCastTypePairs = ::testing::Types; template