cast_ut.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "cast.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. class TGenericCastsTest: public TTestBase {
  4. UNIT_TEST_SUITE(TGenericCastsTest);
  5. UNIT_TEST(TestVerifyDynamicCast)
  6. UNIT_TEST(TestIntegralCast)
  7. UNIT_TEST(TestEnumCast)
  8. UNIT_TEST(TestToUnderlying)
  9. UNIT_TEST(TestBitCast)
  10. UNIT_TEST_SUITE_END();
  11. private:
  12. struct TAaa {
  13. virtual ~TAaa() = default;
  14. };
  15. struct TBbb: public TAaa {};
  16. inline void TestVerifyDynamicCast() {
  17. TBbb bbb;
  18. TAaa* aaa = &bbb;
  19. TAaa* aaa2 = VerifyDynamicCast<TBbb*>(aaa);
  20. UNIT_ASSERT(aaa == aaa2);
  21. }
  22. void TestIntegralCast() {
  23. UNIT_ASSERT_EXCEPTION(SafeIntegerCast<ui32>(-5), TBadCastException);
  24. UNIT_ASSERT_EXCEPTION(SafeIntegerCast<ui16>(static_cast<i32>(Max<ui16>() + 10)), TBadCastException);
  25. UNIT_ASSERT_EXCEPTION(SafeIntegerCast<ui16>(static_cast<ui32>(Max<ui16>() + 10)), TBadCastException);
  26. }
  27. inline void TestEnumCast() {
  28. enum A {
  29. AM1 = -1
  30. };
  31. enum B: int {
  32. BM1 = -1
  33. };
  34. enum class C: unsigned short {
  35. CM1 = 1
  36. };
  37. UNIT_ASSERT_EXCEPTION(SafeIntegerCast<unsigned int>(AM1), TBadCastException);
  38. UNIT_ASSERT_EXCEPTION(SafeIntegerCast<unsigned int>(BM1), TBadCastException);
  39. UNIT_ASSERT_EXCEPTION(SafeIntegerCast<C>(AM1), TBadCastException);
  40. UNIT_ASSERT_EXCEPTION(static_cast<int>(SafeIntegerCast<C>(BM1)), TBadCastException);
  41. UNIT_ASSERT(SafeIntegerCast<A>(BM1) == AM1);
  42. UNIT_ASSERT(SafeIntegerCast<B>(AM1) == BM1);
  43. UNIT_ASSERT(SafeIntegerCast<A>(C::CM1) == 1);
  44. UNIT_ASSERT(SafeIntegerCast<B>(C::CM1) == 1);
  45. UNIT_ASSERT(SafeIntegerCast<A>(-1) == AM1);
  46. UNIT_ASSERT(SafeIntegerCast<B>(-1) == BM1);
  47. UNIT_ASSERT(SafeIntegerCast<C>(1) == C::CM1);
  48. }
  49. void TestToUnderlying() {
  50. enum A {
  51. AM1 = -1
  52. };
  53. enum B: int {
  54. BM1 = -1
  55. };
  56. enum class C: unsigned short {
  57. CM1 = 1
  58. };
  59. static_assert(static_cast<std::underlying_type_t<A>>(AM1) == ToUnderlying(AM1), "");
  60. static_assert(static_cast<std::underlying_type_t<B>>(BM1) == ToUnderlying(BM1), "");
  61. static_assert(static_cast<std::underlying_type_t<C>>(C::CM1) == ToUnderlying(C::CM1), "");
  62. static_assert(std::is_same<std::underlying_type_t<A>, decltype(ToUnderlying(AM1))>::value, "");
  63. static_assert(std::is_same<std::underlying_type_t<B>, decltype(ToUnderlying(BM1))>::value, "");
  64. static_assert(std::is_same<std::underlying_type_t<C>, decltype(ToUnderlying(C::CM1))>::value, "");
  65. UNIT_ASSERT_VALUES_EQUAL(static_cast<std::underlying_type_t<A>>(AM1), ToUnderlying(AM1));
  66. UNIT_ASSERT_VALUES_EQUAL(static_cast<std::underlying_type_t<B>>(BM1), ToUnderlying(BM1));
  67. UNIT_ASSERT_VALUES_EQUAL(static_cast<std::underlying_type_t<C>>(C::CM1), ToUnderlying(C::CM1));
  68. }
  69. void TestBitCast() {
  70. // Change sign of float
  71. {
  72. const float floatValue = 17.33f;
  73. ui32 ui32Value = BitCast<ui32>(floatValue);
  74. ui32Value ^= (ui32)1 << 31;
  75. UNIT_ASSERT_VALUES_EQUAL(-floatValue, BitCast<float>(ui32Value));
  76. }
  77. // Unpack ui64 into a struct
  78. {
  79. const ui64 value = 0x1122334455667788;
  80. struct TStruct {
  81. ui32 a;
  82. ui16 b;
  83. ui8 c;
  84. ui8 d;
  85. };
  86. auto structValue = BitCast<TStruct>(value);
  87. UNIT_ASSERT_VALUES_EQUAL(structValue.a, 0x55667788);
  88. UNIT_ASSERT_VALUES_EQUAL(structValue.b, 0x3344);
  89. UNIT_ASSERT_VALUES_EQUAL(structValue.c, 0x22);
  90. UNIT_ASSERT_VALUES_EQUAL(structValue.d, 0x11);
  91. }
  92. }
  93. };
  94. UNIT_TEST_SUITE_REGISTRATION(TGenericCastsTest);