Add numeric library
This commit is contained in:
@ -18,6 +18,7 @@ cc_library(
|
|||||||
"functional.hpp",
|
"functional.hpp",
|
||||||
"integers.hpp",
|
"integers.hpp",
|
||||||
"meta.hpp",
|
"meta.hpp",
|
||||||
|
"numeric.hpp",
|
||||||
"utility.hpp",
|
"utility.hpp",
|
||||||
],
|
],
|
||||||
srcs = [
|
srcs = [
|
||||||
@ -44,5 +45,6 @@ cc_library(
|
|||||||
"functional",
|
"functional",
|
||||||
"integers",
|
"integers",
|
||||||
"meta",
|
"meta",
|
||||||
|
"numeric",
|
||||||
"utility",
|
"utility",
|
||||||
]]
|
]]
|
||||||
|
@ -15,14 +15,6 @@ constexpr bool has_single_bit(is_unsigned_integer auto x)
|
|||||||
return x != 0 && ((x - 1) & x) == 0;
|
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)
|
constexpr int popcount(uint8_t v)
|
||||||
{
|
{
|
||||||
v = v - ((v >> 1) & 0x55);
|
v = v - ((v >> 1) & 0x55);
|
||||||
|
@ -17,15 +17,6 @@ ASL_TEST(has_single_bit)
|
|||||||
ASL_TEST_EXPECT(!asl::has_single_bit(341U));
|
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(popcount) // NOLINT(*-cognitive-complexity)
|
||||||
{
|
{
|
||||||
ASL_TEST_EXPECT(asl::popcount(uint8_t{0}) == 0);
|
ASL_TEST_EXPECT(asl::popcount(uint8_t{0}) == 0);
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include "asl/base/meta.hpp"
|
#include "asl/base/meta.hpp"
|
||||||
|
|
||||||
|
using float32_t = float;
|
||||||
|
using float64_t = double;
|
||||||
|
|
||||||
namespace asl
|
namespace asl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
43
asl/base/numeric.hpp
Normal file
43
asl/base/numeric.hpp
Normal 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
|
||||||
|
|
16
asl/base/numeric_tests.cpp
Normal file
16
asl/base/numeric_tests.cpp
Normal 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));
|
||||||
|
}
|
@ -69,18 +69,6 @@ constexpr U bit_cast(T value) requires (sizeof(T) == sizeof(U))
|
|||||||
return __builtin_bit_cast(U, value);
|
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)
|
// NOLINTBEGIN(*-macro-parentheses)
|
||||||
#define ASL_DELETE_COPY(T) \
|
#define ASL_DELETE_COPY(T) \
|
||||||
T(const T&) = delete; \
|
T(const T&) = delete; \
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "asl/base/utility.hpp"
|
#include "asl/base/utility.hpp"
|
||||||
#include "asl/base/meta.hpp"
|
#include "asl/base/meta.hpp"
|
||||||
#include "asl/base/bit.hpp"
|
#include "asl/base/bit.hpp"
|
||||||
|
#include "asl/base/numeric.hpp"
|
||||||
#include "asl/memory/allocator.hpp"
|
#include "asl/memory/allocator.hpp"
|
||||||
#include "asl/memory/memory.hpp"
|
#include "asl/memory/memory.hpp"
|
||||||
#include "asl/types/maybe_uninit.hpp"
|
#include "asl/types/maybe_uninit.hpp"
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "asl/formatting/format.hpp"
|
#include "asl/formatting/format.hpp"
|
||||||
#include "asl/base/float.hpp"
|
#include "asl/base/float.hpp"
|
||||||
|
#include "asl/base/numeric.hpp"
|
||||||
|
|
||||||
#define JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED 0
|
#define JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED 0
|
||||||
#define JKJ_STATIC_DATA_SECTION_DEFINED 0
|
#define JKJ_STATIC_DATA_SECTION_DEFINED 0
|
||||||
|
Reference in New Issue
Block a user