123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #include "cast.h"
- #include "ylimits.h"
- #include <library/cpp/testing/unittest/registar.h>
- #include <util/system/valgrind.h>
- class TLimitTest: public TTestBase {
- UNIT_TEST_SUITE(TLimitTest);
- UNIT_TEST(TestLimits);
- UNIT_TEST(TestNan);
- UNIT_TEST(TestMaxDouble);
- UNIT_TEST_SUITE_END();
- protected:
- void TestLimits();
- void TestNan();
- void TestMaxDouble();
- };
- UNIT_TEST_SUITE_REGISTRATION(TLimitTest);
- #define CHECK_COND(X) UNIT_ASSERT(X)
- static inline bool ValidSignInfo(bool, bool) {
- return true;
- }
- template <class T>
- static inline bool ValidSignInfo(bool limitIsSigned, const T&) {
- return limitIsSigned && IsNegative(T(-1)) || !limitIsSigned && !IsNegative(T(-1));
- }
- template <class T>
- static inline bool TestIntegralLimits(const T&, bool unknownSign = true, bool isSigned = true) {
- using lim = std::numeric_limits<T>;
- CHECK_COND(lim::is_specialized);
- CHECK_COND(lim::is_integer);
- CHECK_COND(lim::min() < lim::max());
- CHECK_COND((unknownSign && ((lim::is_signed && (lim::min() != 0)) || (!lim::is_signed && (lim::min() == 0)))) ||
- (!unknownSign && ((lim::is_signed && isSigned) || (!lim::is_signed && !isSigned))));
- T min = Min();
- UNIT_ASSERT_EQUAL(lim::min(), min);
- T max = Max();
- UNIT_ASSERT_EQUAL(lim::max(), max);
- if (unknownSign) {
- CHECK_COND(ValidSignInfo(lim::is_signed, T()));
- }
- return true;
- }
- template <class T>
- static inline bool TestSignedIntegralLimits(const T& val) {
- return TestIntegralLimits(val, false, true);
- }
- template <class T>
- static inline bool TestUnsignedIntegralLimits(const T& val) {
- return TestIntegralLimits(val, false, false);
- }
- template <class T>
- static inline bool TestFloatLimits(const T&) {
- using lim = std::numeric_limits<T>;
- CHECK_COND(lim::is_specialized);
- CHECK_COND(!lim::is_modulo);
- CHECK_COND(!lim::is_integer);
- CHECK_COND(lim::is_signed);
- CHECK_COND(lim::max() > 1000);
- CHECK_COND(lim::min() > 0);
- CHECK_COND(lim::min() < 0.001);
- CHECK_COND(lim::epsilon() > 0);
- if (lim::is_iec559) {
- CHECK_COND(lim::has_infinity);
- CHECK_COND(lim::has_quiet_NaN);
- CHECK_COND(lim::has_signaling_NaN);
- }
- if (lim::has_infinity) {
- const T infinity = lim::infinity();
- CHECK_COND(infinity > lim::max());
- CHECK_COND(-infinity < -lim::max());
- }
- return true;
- }
- template <class T>
- static inline bool TestNan(const T&) {
- using lim = std::numeric_limits<T>;
- if (lim::has_quiet_NaN) {
- const T qnan = lim::quiet_NaN();
- CHECK_COND(!(qnan == 42));
- CHECK_COND(!(qnan == qnan));
- CHECK_COND(qnan != 42);
- CHECK_COND(qnan != qnan);
- }
- return true;
- }
- void TLimitTest::TestLimits() {
- UNIT_ASSERT(TestIntegralLimits(bool()));
- UNIT_ASSERT(TestIntegralLimits(char()));
- using signed_char = signed char;
- UNIT_ASSERT(TestSignedIntegralLimits(signed_char()));
- using unsigned_char = unsigned char;
- UNIT_ASSERT(TestUnsignedIntegralLimits(unsigned_char()));
- UNIT_ASSERT(TestSignedIntegralLimits(short()));
- using unsigned_short = unsigned short;
- UNIT_ASSERT(TestUnsignedIntegralLimits(unsigned_short()));
- UNIT_ASSERT(TestSignedIntegralLimits(int()));
- using unsigned_int = unsigned int;
- UNIT_ASSERT(TestUnsignedIntegralLimits(unsigned_int()));
- UNIT_ASSERT(TestSignedIntegralLimits(long()));
- using unsigned_long = unsigned long;
- UNIT_ASSERT(TestUnsignedIntegralLimits(unsigned_long()));
- using long_long = long long;
- UNIT_ASSERT(TestSignedIntegralLimits(long_long()));
- using unsigned_long_long = unsigned long long;
- UNIT_ASSERT(TestUnsignedIntegralLimits(unsigned_long_long()));
- UNIT_ASSERT(TestFloatLimits(float()));
- UNIT_ASSERT(TestFloatLimits(double()));
- using long_double = long double;
- UNIT_ASSERT(RUNNING_ON_VALGRIND || TestFloatLimits(long_double()));
- }
- void TLimitTest::TestNan() {
- UNIT_ASSERT(::TestNan(float()));
- UNIT_ASSERT(::TestNan(double()));
- using long_double = long double;
- UNIT_ASSERT(::TestNan(long_double()));
- }
- void TLimitTest::TestMaxDouble() {
- UNIT_ASSERT_VALUES_EQUAL(MaxCeil<i8>(), 127.0);
- UNIT_ASSERT_VALUES_EQUAL(MaxFloor<i8>(), 127.0);
- UNIT_ASSERT_VALUES_EQUAL(MaxCeil<ui8>(), 255.0);
- UNIT_ASSERT_VALUES_EQUAL(MaxFloor<ui8>(), 255.0);
- double d = 1ull << 63;
- UNIT_ASSERT_VALUES_EQUAL(MaxCeil<i64>(), d);
- UNIT_ASSERT_VALUES_EQUAL(MaxFloor<i64>(), nextafter(d, 0));
- d *= 2;
- UNIT_ASSERT_VALUES_EQUAL(MaxCeil<ui64>(), d);
- UNIT_ASSERT_VALUES_EQUAL(MaxFloor<ui64>(), nextafter(d, 0));
- }
|