162 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  *  Copyright 2019 The WebRTC Project Authors. All rights reserved.
 | |
|  *
 | |
|  *  Use of this source code is governed by a BSD-style license
 | |
|  *  that can be found in the LICENSE file in the root of the source
 | |
|  *  tree. An additional intellectual property rights grant can be found
 | |
|  *  in the file PATENTS.  All contributing project authors may
 | |
|  *  be found in the AUTHORS file in the root of the source tree.
 | |
|  */
 | |
| 
 | |
| #include "rtc_base/numerics/divide_round.h"
 | |
| 
 | |
| #include <limits>
 | |
| 
 | |
| #include "test/gtest.h"
 | |
| 
 | |
| namespace webrtc {
 | |
| namespace {
 | |
| 
 | |
| TEST(DivideRoundUpTest, CanBeUsedAsConstexpr) {
 | |
|   static_assert(DivideRoundUp(5, 1) == 5, "");
 | |
|   static_assert(DivideRoundUp(5, 2) == 3, "");
 | |
| }
 | |
| 
 | |
| TEST(DivideRoundUpTest, ReturnsZeroForZeroDividend) {
 | |
|   EXPECT_EQ(DivideRoundUp(uint8_t{0}, 1), 0);
 | |
|   EXPECT_EQ(DivideRoundUp(uint8_t{0}, 3), 0);
 | |
|   EXPECT_EQ(DivideRoundUp(int{0}, 1), 0);
 | |
|   EXPECT_EQ(DivideRoundUp(int{0}, 3), 0);
 | |
| }
 | |
| 
 | |
| TEST(DivideRoundUpTest, WorksForMaxDividend) {
 | |
|   EXPECT_EQ(DivideRoundUp(uint8_t{255}, 2), 128);
 | |
|   EXPECT_EQ(DivideRoundUp(std::numeric_limits<int>::max(), 2),
 | |
|             std::numeric_limits<int>::max() / 2 +
 | |
|                 (std::numeric_limits<int>::max() % 2));
 | |
| }
 | |
| 
 | |
| TEST(DivideRoundToNearestTest, CanBeUsedAsConstexpr) {
 | |
|   static constexpr int kOne = DivideRoundToNearest(5, 4);
 | |
|   static constexpr int kTwo = DivideRoundToNearest(7, 4);
 | |
|   static_assert(kOne == 1, "");
 | |
|   static_assert(kTwo == 2, "");
 | |
| }
 | |
| 
 | |
| TEST(DivideRoundToNearestTest, DivideByOddNumber) {
 | |
|   EXPECT_EQ(DivideRoundToNearest(0, 3), 0);
 | |
|   EXPECT_EQ(DivideRoundToNearest(1, 3), 0);
 | |
|   EXPECT_EQ(DivideRoundToNearest(2, 3), 1);
 | |
|   EXPECT_EQ(DivideRoundToNearest(3, 3), 1);
 | |
|   EXPECT_EQ(DivideRoundToNearest(4, 3), 1);
 | |
|   EXPECT_EQ(DivideRoundToNearest(5, 3), 2);
 | |
|   EXPECT_EQ(DivideRoundToNearest(6, 3), 2);
 | |
| }
 | |
| 
 | |
| TEST(DivideRoundToNearestTest, DivideByEvenNumberTieRoundsUp) {
 | |
|   EXPECT_EQ(DivideRoundToNearest(0, 4), 0);
 | |
|   EXPECT_EQ(DivideRoundToNearest(1, 4), 0);
 | |
|   EXPECT_EQ(DivideRoundToNearest(2, 4), 1);
 | |
|   EXPECT_EQ(DivideRoundToNearest(3, 4), 1);
 | |
|   EXPECT_EQ(DivideRoundToNearest(4, 4), 1);
 | |
|   EXPECT_EQ(DivideRoundToNearest(5, 4), 1);
 | |
|   EXPECT_EQ(DivideRoundToNearest(6, 4), 2);
 | |
|   EXPECT_EQ(DivideRoundToNearest(7, 4), 2);
 | |
| }
 | |
| 
 | |
| TEST(DivideRoundToNearestTest, LargeDivisor) {
 | |
|   EXPECT_EQ(DivideRoundToNearest(std::numeric_limits<int>::max() - 1,
 | |
|                                  std::numeric_limits<int>::max()),
 | |
|             1);
 | |
| }
 | |
| 
 | |
| TEST(DivideRoundToNearestTest, DivideSmallTypeByLargeType) {
 | |
|   uint8_t small = 0xff;
 | |
|   uint16_t large = 0xffff;
 | |
|   EXPECT_EQ(DivideRoundToNearest(small, large), 0);
 | |
| }
 | |
| 
 | |
| using IntegerTypes = ::testing::Types<int8_t,
 | |
|                                       int16_t,
 | |
|                                       int32_t,
 | |
|                                       int64_t,
 | |
|                                       uint8_t,
 | |
|                                       uint16_t,
 | |
|                                       uint32_t,
 | |
|                                       uint64_t>;
 | |
| template <typename T>
 | |
| class DivideRoundTypedTest : public ::testing::Test {};
 | |
| TYPED_TEST_SUITE(DivideRoundTypedTest, IntegerTypes);
 | |
| 
 | |
| TYPED_TEST(DivideRoundTypedTest, RoundToNearestPreservesType) {
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int8_t{3})),
 | |
|                    decltype(TypeParam{100} / int8_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int16_t{3})),
 | |
|                    decltype(TypeParam{100} / int16_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int32_t{3})),
 | |
|                    decltype(TypeParam{100} / int32_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, int64_t{3})),
 | |
|                    decltype(TypeParam{100} / int64_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint8_t{3})),
 | |
|                    decltype(TypeParam{100} / uint8_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint16_t{3})),
 | |
|                    decltype(TypeParam{100} / uint16_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint32_t{3})),
 | |
|                    decltype(TypeParam{100} / uint32_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundToNearest(TypeParam{100}, uint64_t{3})),
 | |
|                    decltype(TypeParam{100} / uint64_t{3})>::value,
 | |
|       "");
 | |
| }
 | |
| 
 | |
| TYPED_TEST(DivideRoundTypedTest, RoundUpPreservesType) {
 | |
|   static_assert(std::is_same<decltype(DivideRoundUp(TypeParam{100}, int8_t{3})),
 | |
|                              decltype(TypeParam{100} / int8_t{3})>::value,
 | |
|                 "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundUp(TypeParam{100}, int16_t{3})),
 | |
|                    decltype(TypeParam{100} / int16_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundUp(TypeParam{100}, int32_t{3})),
 | |
|                    decltype(TypeParam{100} / int32_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundUp(TypeParam{100}, int64_t{3})),
 | |
|                    decltype(TypeParam{100} / int64_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint8_t{3})),
 | |
|                    decltype(TypeParam{100} / uint8_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint16_t{3})),
 | |
|                    decltype(TypeParam{100} / uint16_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint32_t{3})),
 | |
|                    decltype(TypeParam{100} / uint32_t{3})>::value,
 | |
|       "");
 | |
|   static_assert(
 | |
|       std::is_same<decltype(DivideRoundUp(TypeParam{100}, uint64_t{3})),
 | |
|                    decltype(TypeParam{100} / uint64_t{3})>::value,
 | |
|       "");
 | |
| }
 | |
| 
 | |
| }  // namespace
 | |
| }  // namespace webrtc
 |