Add numeric library

This commit is contained in:
2025-04-03 23:18:51 +02:00
parent 0776012d09
commit afbfd0e781
9 changed files with 66 additions and 29 deletions

View File

@ -18,6 +18,7 @@ cc_library(
"functional.hpp",
"integers.hpp",
"meta.hpp",
"numeric.hpp",
"utility.hpp",
],
srcs = [
@ -44,5 +45,6 @@ cc_library(
"functional",
"integers",
"meta",
"numeric",
"utility",
]]

View File

@ -15,14 +15,6 @@ constexpr bool has_single_bit(is_unsigned_integer auto x)
return x != 0 && ((x - 1) & x) == 0;
}
// @Todo Move this to numeric library
template<is_integer T>
constexpr bool is_pow2(T x)
{
using unsigned_type = select_t<is_unsigned_integer<T>, T, as_unsigned_integer<T>>;
return x > 0 && has_single_bit(static_cast<unsigned_type>(x));
}
constexpr int popcount(uint8_t v)
{
v = v - ((v >> 1) & 0x55);

View File

@ -17,15 +17,6 @@ ASL_TEST(has_single_bit)
ASL_TEST_EXPECT(!asl::has_single_bit(341U));
}
ASL_TEST(is_pow2)
{
ASL_TEST_EXPECT(asl::is_pow2(4));
ASL_TEST_EXPECT(asl::is_pow2(65536));
ASL_TEST_EXPECT(!asl::is_pow2(6));
ASL_TEST_EXPECT(!asl::is_pow2(1978));
ASL_TEST_EXPECT(!asl::is_pow2(0));
}
ASL_TEST(popcount) // NOLINT(*-cognitive-complexity)
{
ASL_TEST_EXPECT(asl::popcount(uint8_t{0}) == 0);

View File

@ -6,6 +6,9 @@
#include "asl/base/meta.hpp"
using float32_t = float;
using float64_t = double;
namespace asl
{

43
asl/base/numeric.hpp Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2025 Steven Le Rouzic
//
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include "asl/base/integers.hpp"
#include "asl/base/bit.hpp"
#include "asl/base/meta.hpp"
namespace asl
{
template<is_integer T>
constexpr bool is_pow2(T x)
{
using unsigned_type = select_t<is_unsigned_integer<T>, T, as_unsigned_integer<T>>;
return x > 0 && has_single_bit(static_cast<unsigned_type>(x));
}
template<typename T>
concept is_numeric = is_integer<T> || is_floating_point<T>;
template<is_numeric T>
constexpr T min(T a, T b)
{
return (a <= b) ? a : b;
}
template<is_numeric T>
constexpr T max(T a, T b)
{
return (a >= b) ? a : b;
}
template<is_numeric T>
constexpr T clamp(T x, T a, T b)
{
return min(max(x, a), b);
}
} // namespace asl

View File

@ -0,0 +1,16 @@
// Copyright 2025 Steven Le Rouzic
//
// SPDX-License-Identifier: BSD-3-Clause
#include "asl/base/numeric.hpp"
#include "asl/testing/testing.hpp"
ASL_TEST(is_pow2)
{
ASL_TEST_EXPECT(asl::is_pow2(4));
ASL_TEST_EXPECT(asl::is_pow2(65536));
ASL_TEST_EXPECT(!asl::is_pow2(6));
ASL_TEST_EXPECT(!asl::is_pow2(1978));
ASL_TEST_EXPECT(!asl::is_pow2(0));
}

View File

@ -69,18 +69,6 @@ constexpr U bit_cast(T value) requires (sizeof(T) == sizeof(U))
return __builtin_bit_cast(U, value);
}
template<typename T>
constexpr T min(T a, T b)
{
return (a <= b) ? a : b;
}
template<typename T>
constexpr T max(T a, T b)
{
return (a >= b) ? a : b;
}
// NOLINTBEGIN(*-macro-parentheses)
#define ASL_DELETE_COPY(T) \
T(const T&) = delete; \

View File

@ -8,6 +8,7 @@
#include "asl/base/utility.hpp"
#include "asl/base/meta.hpp"
#include "asl/base/bit.hpp"
#include "asl/base/numeric.hpp"
#include "asl/memory/allocator.hpp"
#include "asl/memory/memory.hpp"
#include "asl/types/maybe_uninit.hpp"

View File

@ -4,6 +4,7 @@
#include "asl/formatting/format.hpp"
#include "asl/base/float.hpp"
#include "asl/base/numeric.hpp"
#define JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED 0
#define JKJ_STATIC_DATA_SECTION_DEFINED 0