| /* |
| * 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 <cstdint> |
| #include <limits> |
| #include <type_traits> |
| |
| #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); |
| static_assert(DivideRoundToNearest(-5, 4) == -1); |
| static_assert(DivideRoundToNearest(-7, 4) == -2); |
| } |
| |
| TEST(DivideRoundToNearestTest, DivideByOddNumber) { |
| EXPECT_EQ(DivideRoundToNearest(-5, 3), -2); |
| EXPECT_EQ(DivideRoundToNearest(-4, 3), -1); |
| EXPECT_EQ(DivideRoundToNearest(-3, 3), -1); |
| EXPECT_EQ(DivideRoundToNearest(-2, 3), -1); |
| EXPECT_EQ(DivideRoundToNearest(-1, 3), 0); |
| 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(-7, 4), -2); |
| EXPECT_EQ(DivideRoundToNearest(-6, 4), -1); |
| EXPECT_EQ(DivideRoundToNearest(-5, 4), -1); |
| EXPECT_EQ(DivideRoundToNearest(-4, 4), -1); |
| EXPECT_EQ(DivideRoundToNearest(-3, 4), -1); |
| EXPECT_EQ(DivideRoundToNearest(-2, 4), 0); |
| EXPECT_EQ(DivideRoundToNearest(-1, 4), 0); |
| 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); |
| EXPECT_EQ(DivideRoundToNearest(std::numeric_limits<int>::min(), |
| 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 |