1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
12 
13 #include <cstdint>
14 #include <limits>
15 #include <type_traits>
16 #include <vector>
17 
18 #include "test/gtest.h"
19 
20 namespace webrtc_event_logging {
21 namespace {
22 
23 template <typename T>
24 class SignednessConversionTest : public ::testing::Test {
25  public:
26   static_assert(std::is_integral<T>::value, "");
27   static_assert(std::is_signed<T>::value, "");
28 };
29 
30 TYPED_TEST_SUITE_P(SignednessConversionTest);
31 
TYPED_TEST_P(SignednessConversionTest,CorrectlyConvertsLegalValues)32 TYPED_TEST_P(SignednessConversionTest, CorrectlyConvertsLegalValues) {
33   using T = TypeParam;
34   std::vector<T> legal_values = {std::numeric_limits<T>::min(),
35                                  std::numeric_limits<T>::min() + 1,
36                                  -1,
37                                  0,
38                                  1,
39                                  std::numeric_limits<T>::max() - 1,
40                                  std::numeric_limits<T>::max()};
41   for (T val : legal_values) {
42     const auto unsigned_val = ToUnsigned(val);
43     T signed_val;
44     ASSERT_TRUE(ToSigned<T>(unsigned_val, &signed_val))
45         << "Failed on " << static_cast<uint64_t>(unsigned_val) << ".";
46     EXPECT_EQ(val, signed_val)
47         << "Failed on " << static_cast<uint64_t>(unsigned_val) << ".";
48   }
49 }
50 
TYPED_TEST_P(SignednessConversionTest,FailsOnConvertingIllegalValues)51 TYPED_TEST_P(SignednessConversionTest, FailsOnConvertingIllegalValues) {
52   using T = TypeParam;
53 
54   // Note that a signed integer whose width is N bits, has N-1 digits.
55   constexpr bool width_is_64 = std::numeric_limits<T>::digits == 63;
56 
57   if (width_is_64) {
58     return;  // Test irrelevant; illegal values do not exist.
59   }
60 
61   const uint64_t max_legal_value = ToUnsigned(static_cast<T>(-1));
62 
63   const std::vector<uint64_t> illegal_values = {
64       max_legal_value + 1u, max_legal_value + 2u,
65       std::numeric_limits<uint64_t>::max() - 1u,
66       std::numeric_limits<uint64_t>::max()};
67 
68   for (uint64_t unsigned_val : illegal_values) {
69     T signed_val;
70     EXPECT_FALSE(ToSigned<T>(unsigned_val, &signed_val))
71         << "Failed on " << static_cast<uint64_t>(unsigned_val) << ".";
72   }
73 }
74 
75 REGISTER_TYPED_TEST_SUITE_P(SignednessConversionTest,
76                             CorrectlyConvertsLegalValues,
77                             FailsOnConvertingIllegalValues);
78 
79 using Types = ::testing::Types<int8_t, int16_t, int32_t, int64_t>;
80 
81 INSTANTIATE_TYPED_TEST_SUITE_P(_, SignednessConversionTest, Types);
82 
83 }  // namespace
84 }  // namespace webrtc_event_logging
85