Files
filament/libs/utils/test/test_algorithm.cpp
Mathias Agopian 718e7ab064 remove a bunch of <functional> includes
This forces us to use an explicit hash class in a few place, but it
is cleaner.

remove utils::lower_bound and utils::upper_bound, which were not used.
2022-06-03 08:35:57 -07:00

161 lines
5.0 KiB
C++

/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <utils/algorithm.h>
#include <array>
using namespace utils;
template <typename T>
static inline T count_leading_zeros(T v) noexcept {
return utils::clz(v);
}
template <typename T>
static inline T count_trailing_zeros(T v) noexcept {
return utils::ctz(v);
}
TEST(AlgorithmTest, details_clz) {
for (uint64_t i = 1, j = 63; j < 64; i *= 2, j--) {
EXPECT_EQ(j, details::clz(i));
EXPECT_EQ(j, details::clz(i|1));
}
for (uint32_t i = 1, j = 31; j < 32; i *= 2, j--) {
EXPECT_EQ(j, details::clz(i));
EXPECT_EQ(j, details::clz(i|1));
}
}
TEST(AlgorithmTest, clz) {
for (uint64_t i = 1, j = 63; j < 64; i *= 2, j--) {
EXPECT_EQ(j, clz(i));
EXPECT_EQ(j, clz(i|1));
EXPECT_EQ(j, details::clz(i));
EXPECT_EQ(j, details::clz(i|1));
EXPECT_EQ(j, count_leading_zeros(i));
}
for (uint32_t i = 1, j = 31; j < 32; i *= 2, j--) {
EXPECT_EQ(j, clz(i));
EXPECT_EQ(j, clz(i|1));
EXPECT_EQ(j, details::clz(i));
EXPECT_EQ(j, details::clz(i|1));
EXPECT_EQ(j, count_leading_zeros(i));
}
}
TEST(AlgorithmTest, details_ctz) {
for (uint64_t i = 1, j = 0; j < 64; i *= 2, j++) {
EXPECT_EQ(j, details::ctz(i));
}
for (uint32_t i = 1, j = 0; j < 32; i *= 2, j++) {
EXPECT_EQ(j, details::ctz(i));
}
}
TEST(AlgorithmTest, ctz) {
for (uint64_t i = 1, j = 0; j < 64; i *= 2, j++) {
EXPECT_EQ(j, ctz(i));
EXPECT_EQ(j, details::ctz(i));
EXPECT_EQ(j, count_trailing_zeros(i));
}
for (uint32_t i = 1, j = 0; j < 32; i *= 2, j++) {
EXPECT_EQ(j, ctz(i));
EXPECT_EQ(j, details::ctz(i));
EXPECT_EQ(j, count_trailing_zeros(i));
}
}
TEST(AlgorithmTest, details_popcount) {
EXPECT_EQ(0, details::popcount(0u));
EXPECT_EQ(0, details::popcount(0lu));
EXPECT_EQ(0, details::popcount(0llu));
EXPECT_EQ(sizeof(int)*8, details::popcount(-1u));
EXPECT_EQ(sizeof(long)*8, details::popcount(-1lu));
EXPECT_EQ(sizeof(long long)*8, details::popcount(-1llu));
EXPECT_EQ(8, details::popcount(uint8_t(-1)));
EXPECT_EQ(32, details::popcount(uint32_t(-1)));
EXPECT_EQ(64, details::popcount(uint64_t(-1)));
EXPECT_EQ(4, details::popcount(uint8_t(0x55)));
EXPECT_EQ(16, details::popcount(uint32_t(0x55555555)));
EXPECT_EQ(32, details::popcount(uint64_t(0x5555555555555555)));
for (uint64_t i = 1, j = 63; j < 64; i *= 2, j--) {
EXPECT_EQ(1, details::popcount(i));
}
for (uint32_t i = 1, j = 31; j < 32; i *= 2, j--) {
EXPECT_EQ(1, details::popcount(i));
}
for (uint8_t i = 1, j = 7; j < 8; i *= 2, j--) {
EXPECT_EQ(1, details::popcount(i));
}
}
TEST(AlgorithmTest, popcount) {
EXPECT_EQ(0, popcount(0u));
EXPECT_EQ(0, popcount(0lu));
EXPECT_EQ(0, popcount(0llu));
EXPECT_EQ(sizeof(int)*8, popcount(-1u));
EXPECT_EQ(sizeof(long)*8, popcount(-1lu));
EXPECT_EQ(sizeof(long long)*8, popcount(-1llu));
EXPECT_EQ(8, popcount(uint8_t(-1)));
EXPECT_EQ(32, popcount(uint32_t(-1)));
EXPECT_EQ(64, popcount(uint64_t(-1)));
EXPECT_EQ(4, popcount(uint8_t(0x55)));
EXPECT_EQ(16, popcount(uint32_t(0x55555555)));
EXPECT_EQ(32, popcount(uint64_t(0x5555555555555555)));
for (uint64_t i = 1, j = 63; i < 64; i *= 2, j--) {
EXPECT_EQ(1, popcount(i));
}
for (uint32_t i = 1, j = 31; j < 32; i *= 2, j--) {
EXPECT_EQ(1, popcount(i));
}
for (uint8_t i = 1, j = 7; j < 8; i *= 2, j--) {
EXPECT_EQ(1, popcount(i));
}
}
TEST(AlgorithmTest, Partition) {
int* r;
int array[8] = { 2, 5, 4, 8, 9, 9, 9, 9 };
r = utils::partition_point(std::begin(array), std::end(array), [](int i) { return i < 9; });
EXPECT_EQ(4, r - std::begin(array));
r = utils::partition_point(std::begin(array), std::end(array), [](int i) { return i < 10; });
EXPECT_EQ(std::end(array), r);
r = utils::partition_point(std::begin(array), std::end(array), [](int i) { return i < 2; });
EXPECT_EQ(std::begin(array), r);
int array7[7] = { 2, 5, 4, 8, 9, 9, 9 };
r = utils::partition_point(std::begin(array7), std::end(array7), [](int i) { return i < 9; });
EXPECT_EQ(4, r - std::begin(array7));
int array9[9] = { 2, 5, 4, 8, 9, 9, 9, 9, 9 };
r = utils::partition_point(std::begin(array9), std::end(array9), [](int i) { return i < 9; });
EXPECT_EQ(4, r - std::begin(array9));
}