1 /*
2 * Copyright 2019 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 "rtc_base/numerics/divide_round.h"
12
13 #include <limits>
14
15 #include "test/gtest.h"
16
17 namespace webrtc {
18 namespace {
19
TEST(DivideRoundUpTest,CanBeUsedAsConstexpr)20 TEST(DivideRoundUpTest, CanBeUsedAsConstexpr) {
21 static_assert(DivideRoundUp(5, 1) == 5, "");
22 static_assert(DivideRoundUp(5, 2) == 3, "");
23 }
24
TEST(DivideRoundUpTest,ReturnsZeroForZeroDividend)25 TEST(DivideRoundUpTest, ReturnsZeroForZeroDividend) {
26 EXPECT_EQ(DivideRoundUp(uint8_t{0}, 1), 0);
27 EXPECT_EQ(DivideRoundUp(uint8_t{0}, 3), 0);
28 EXPECT_EQ(DivideRoundUp(int{0}, 1), 0);
29 EXPECT_EQ(DivideRoundUp(int{0}, 3), 0);
30 }
31
TEST(DivideRoundUpTest,WorksForMaxDividend)32 TEST(DivideRoundUpTest, WorksForMaxDividend) {
33 EXPECT_EQ(DivideRoundUp(uint8_t{255}, 2), 128);
34 EXPECT_EQ(DivideRoundUp(std::numeric_limits<int>::max(), 2),
35 std::numeric_limits<int>::max() / 2 +
36 (std::numeric_limits<int>::max() % 2));
37 }
38
TEST(DivideRoundToNearestTest,CanBeUsedAsConstexpr)39 TEST(DivideRoundToNearestTest, CanBeUsedAsConstexpr) {
40 static constexpr int kOne = DivideRoundToNearest(5, 4);
41 static constexpr int kTwo = DivideRoundToNearest(7, 4);
42 static_assert(kOne == 1, "");
43 static_assert(kTwo == 2, "");
44 }
45
TEST(DivideRoundToNearestTest,DivideByOddNumber)46 TEST(DivideRoundToNearestTest, DivideByOddNumber) {
47 EXPECT_EQ(DivideRoundToNearest(0, 3), 0);
48 EXPECT_EQ(DivideRoundToNearest(1, 3), 0);
49 EXPECT_EQ(DivideRoundToNearest(2, 3), 1);
50 EXPECT_EQ(DivideRoundToNearest(3, 3), 1);
51 EXPECT_EQ(DivideRoundToNearest(4, 3), 1);
52 EXPECT_EQ(DivideRoundToNearest(5, 3), 2);
53 EXPECT_EQ(DivideRoundToNearest(6, 3), 2);
54 }
55
TEST(DivideRoundToNearestTest,DivideByEvenNumberTieRoundsUp)56 TEST(DivideRoundToNearestTest, DivideByEvenNumberTieRoundsUp) {
57 EXPECT_EQ(DivideRoundToNearest(0, 4), 0);
58 EXPECT_EQ(DivideRoundToNearest(1, 4), 0);
59 EXPECT_EQ(DivideRoundToNearest(2, 4), 1);
60 EXPECT_EQ(DivideRoundToNearest(3, 4), 1);
61 EXPECT_EQ(DivideRoundToNearest(4, 4), 1);
62 EXPECT_EQ(DivideRoundToNearest(5, 4), 1);
63 EXPECT_EQ(DivideRoundToNearest(6, 4), 2);
64 EXPECT_EQ(DivideRoundToNearest(7, 4), 2);
65 }
66
TEST(DivideRoundToNearestTest,LargeDivisor)67 TEST(DivideRoundToNearestTest, LargeDivisor) {
68 EXPECT_EQ(DivideRoundToNearest(std::numeric_limits<int>::max() - 1,
69 std::numeric_limits<int>::max()),
70 1);
71 }
72
TEST(DivideRoundToNearestTest,DivideSmallTypeByLargeType)73 TEST(DivideRoundToNearestTest, DivideSmallTypeByLargeType) {
74 uint8_t small = 0xff;
75 uint16_t large = 0xffff;
76 EXPECT_EQ(DivideRoundToNearest(small, large), 0);
77 }
78
79 using IntegerTypes = ::testing::Types<int8_t,
80 int16_t,
81 int32_t,
82 int64_t,
83 uint8_t,
84 uint16_t,
85 uint32_t,
86 uint64_t>;
87 template <typename T>
88 class DivideRoundTypedTest : public ::testing::Test {};
89 TYPED_TEST_SUITE(DivideRoundTypedTest, IntegerTypes);
90
TYPED_TEST(DivideRoundTypedTest,RoundToNearestPreservesType)91 TYPED_TEST(DivideRoundTypedTest, RoundToNearestPreservesType) {
92 static_assert(
93 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int8_t{3})),
94 decltype(TypeParam{100} / int8_t{3})>::value,
95 "");
96 static_assert(
97 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int16_t{3})),
98 decltype(TypeParam{100} / int16_t{3})>::value,
99 "");
100 static_assert(
101 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int32_t{3})),
102 decltype(TypeParam{100} / int32_t{3})>::value,
103 "");
104 static_assert(
105 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int64_t{3})),
106 decltype(TypeParam{100} / int64_t{3})>::value,
107 "");
108 static_assert(
109 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint8_t{3})),
110 decltype(TypeParam{100} / uint8_t{3})>::value,
111 "");
112 static_assert(
113 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint16_t{3})),
114 decltype(TypeParam{100} / uint16_t{3})>::value,
115 "");
116 static_assert(
117 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint32_t{3})),
118 decltype(TypeParam{100} / uint32_t{3})>::value,
119 "");
120 static_assert(
121 std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint64_t{3})),
122 decltype(TypeParam{100} / uint64_t{3})>::value,
123 "");
124 }
125
TYPED_TEST(DivideRoundTypedTest,RoundUpPreservesType)126 TYPED_TEST(DivideRoundTypedTest, RoundUpPreservesType) {
127 static_assert(std::is_same<decltype(DivideRoundUp(TypeParam{100}, int8_t{3})),
128 decltype(TypeParam{100} / int8_t{3})>::value,
129 "");
130 static_assert(
131 std::is_same<decltype(DivideRoundUp(TypeParam{100}, int16_t{3})),
132 decltype(TypeParam{100} / int16_t{3})>::value,
133 "");
134 static_assert(
135 std::is_same<decltype(DivideRoundUp(TypeParam{100}, int32_t{3})),
136 decltype(TypeParam{100} / int32_t{3})>::value,
137 "");
138 static_assert(
139 std::is_same<decltype(DivideRoundUp(TypeParam{100}, int64_t{3})),
140 decltype(TypeParam{100} / int64_t{3})>::value,
141 "");
142 static_assert(
143 std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint8_t{3})),
144 decltype(TypeParam{100} / uint8_t{3})>::value,
145 "");
146 static_assert(
147 std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint16_t{3})),
148 decltype(TypeParam{100} / uint16_t{3})>::value,
149 "");
150 static_assert(
151 std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint32_t{3})),
152 decltype(TypeParam{100} / uint32_t{3})>::value,
153 "");
154 static_assert(
155 std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint64_t{3})),
156 decltype(TypeParam{100} / uint64_t{3})>::value,
157 "");
158 }
159
160 } // namespace
161 } // namespace webrtc
162