bit_cast_test.cc (3492B)
1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Unit test for bit_cast template. 16 17 #include <cstdint> 18 #include <cstring> 19 20 #include "gtest/gtest.h" 21 #include "absl/base/casts.h" 22 #include "absl/base/macros.h" 23 24 namespace absl { 25 ABSL_NAMESPACE_BEGIN 26 namespace { 27 28 template <int N> 29 struct marshall { char buf[N]; }; 30 31 template <typename T> 32 void TestMarshall(const T values[], int num_values) { 33 for (int i = 0; i < num_values; ++i) { 34 T t0 = values[i]; 35 marshall<sizeof(T)> m0 = absl::bit_cast<marshall<sizeof(T)> >(t0); 36 T t1 = absl::bit_cast<T>(m0); 37 marshall<sizeof(T)> m1 = absl::bit_cast<marshall<sizeof(T)> >(t1); 38 ASSERT_EQ(0, memcmp(&t0, &t1, sizeof(T))); 39 ASSERT_EQ(0, memcmp(&m0, &m1, sizeof(T))); 40 } 41 } 42 43 // Convert back and forth to an integral type. The C++ standard does 44 // not guarantee this will work, but we test that this works on all the 45 // platforms we support. 46 // 47 // Likewise, we below make assumptions about sizeof(float) and 48 // sizeof(double) which the standard does not guarantee, but which hold on the 49 // platforms we support. 50 51 template <typename T, typename I> 52 void TestIntegral(const T values[], int num_values) { 53 for (int i = 0; i < num_values; ++i) { 54 T t0 = values[i]; 55 I i0 = absl::bit_cast<I>(t0); 56 T t1 = absl::bit_cast<T>(i0); 57 I i1 = absl::bit_cast<I>(t1); 58 ASSERT_EQ(0, memcmp(&t0, &t1, sizeof(T))); 59 ASSERT_EQ(i0, i1); 60 } 61 } 62 63 TEST(BitCast, Bool) { 64 static const bool bool_list[] = { false, true }; 65 TestMarshall<bool>(bool_list, ABSL_ARRAYSIZE(bool_list)); 66 } 67 68 TEST(BitCast, Int32) { 69 static const int32_t int_list[] = 70 { 0, 1, 100, 2147483647, -1, -100, -2147483647, -2147483647-1 }; 71 TestMarshall<int32_t>(int_list, ABSL_ARRAYSIZE(int_list)); 72 } 73 74 TEST(BitCast, Int64) { 75 static const int64_t int64_list[] = 76 { 0, 1, 1LL << 40, -1, -(1LL<<40) }; 77 TestMarshall<int64_t>(int64_list, ABSL_ARRAYSIZE(int64_list)); 78 } 79 80 TEST(BitCast, Uint64) { 81 static const uint64_t uint64_list[] = 82 { 0, 1, 1LLU << 40, 1LLU << 63 }; 83 TestMarshall<uint64_t>(uint64_list, ABSL_ARRAYSIZE(uint64_list)); 84 } 85 86 TEST(BitCast, Float) { 87 static const float float_list[] = 88 { 0.0f, 1.0f, -1.0f, 10.0f, -10.0f, 89 1e10f, 1e20f, 1e-10f, 1e-20f, 90 2.71828f, 3.14159f }; 91 TestMarshall<float>(float_list, ABSL_ARRAYSIZE(float_list)); 92 TestIntegral<float, int>(float_list, ABSL_ARRAYSIZE(float_list)); 93 TestIntegral<float, unsigned>(float_list, ABSL_ARRAYSIZE(float_list)); 94 } 95 96 TEST(BitCast, Double) { 97 static const double double_list[] = 98 { 0.0, 1.0, -1.0, 10.0, -10.0, 99 1e10, 1e100, 1e-10, 1e-100, 100 2.718281828459045, 101 3.141592653589793238462643383279502884197169399375105820974944 }; 102 TestMarshall<double>(double_list, ABSL_ARRAYSIZE(double_list)); 103 TestIntegral<double, int64_t>(double_list, ABSL_ARRAYSIZE(double_list)); 104 TestIntegral<double, uint64_t>(double_list, ABSL_ARRAYSIZE(double_list)); 105 } 106 107 } // namespace 108 ABSL_NAMESPACE_END 109 } // namespace absl