Mjolnir Core
Core functionality of the Mjolnir API
math.h
Go to the documentation of this file.
1 
7 
8 #pragma once
9 
13 
14 #include <concepts>
15 
16 
17 // === DECLARATIONS ===================================================================================================
18 
19 namespace mjolnir
20 {
23 
24 
36 template <std::integral T_Type>
37 [[nodiscard]] constexpr auto is_power_of_2(T_Type value) noexcept -> bool;
38 
39 
51 template <std::integral T_Type>
52 [[nodiscard]] constexpr auto gauss_summation(T_Type n) -> T_Type;
53 
54 
68 template <Number T_Type>
69 [[nodiscard]] constexpr auto power(T_Type base, std::integral auto exponent) noexcept -> T_Type;
70 
71 
86 template <Number T_Type = UST>
87 [[nodiscard]] constexpr auto power_of_2(std::integral auto exponent) noexcept -> T_Type;
88 
89 
91 } // namespace mjolnir
92 
93 
94 // === DEFINITIONS ====================================================================================================
95 
96 
97 #include <cassert>
98 
99 
100 namespace mjolnir
101 {
102 template <std::integral T_Type>
103 [[nodiscard]] constexpr auto is_power_of_2(T_Type value) noexcept -> bool
104 {
105  auto u_value = signed_to_unsigned(value);
106  return (value > 0) && ! (u_value & (u_value - 1));
107 }
108 
109 
110 // --------------------------------------------------------------------------------------------------------------------
111 
112 template <std::integral T_Type>
113 [[nodiscard]] constexpr auto gauss_summation(T_Type n) -> T_Type
114 {
115  assert(n >= 0 && "n must be a positive number"); // NOLINT
116 
117  return (n * n + n) / 2;
118 }
119 
120 
121 // --------------------------------------------------------------------------------------------------------------------
122 
123 template <Number T_Type>
124 // NOLINTNEXTLINE(misc-no-recursion)
125 [[nodiscard]] constexpr auto power(T_Type base, std::integral auto exponent) noexcept -> T_Type
126 {
127  assert(exponent >= 0 && "exponent must be a positive number"); // NOLINT
128 
129  if (exponent == 0)
130  return 1;
131  if (exponent % 2 == 0)
132  return power(base, exponent / 2) * power(base, exponent / 2);
133  return base * power(base, (exponent - 1) / 2) * power(base, (exponent - 1) / 2);
134 }
135 
136 
137 // --------------------------------------------------------------------------------------------------------------------
138 
139 template <Number T_Type>
140 [[nodiscard]] constexpr auto power_of_2(std::integral auto exponent) noexcept -> T_Type
141 {
142  assert(exponent >= 0 && "exponent must be a positive number"); // NOLINT
143 
144  return static_cast<T_Type>(UST(1) << static_cast<UST>(exponent));
145 }
146 
147 
148 } // namespace mjolnir
Contains some basic definitions and concepts that are frequently needed.
Defines the fundamental data types.
std::size_t UST
Unsigned integer type that is returned by sizeof operations.
Definition: fundamental_types.h:29
constexpr auto is_power_of_2(T_Type value) noexcept -> bool
Return true if the passed value is a power of 2.
Definition: math.h:103
constexpr auto power(T_Type base, std::integral auto exponent) noexcept -> T_Type
Calculate the power of a number using an integer based exponent.
Definition: math.h:125
constexpr auto gauss_summation(T_Type n) -> T_Type
Calculate the sum of the first n positive numbers.
Definition: math.h:113
constexpr auto power_of_2(std::integral auto exponent) noexcept -> T_Type
Calculate the power of 2 using an integer based exponent.
Definition: math.h:140
constexpr auto signed_to_unsigned(T_Type value) -> EquallySizedUnsignedType< T_Type >
Cast an integer to an equally sized unsigned type.
Definition: type.h:94
Contains multiple utility functions for type related operations.