Branch data Line data Source code
1 : : #include <concepts> 2 : : #include <cstdint> 3 : : 4 : : namespace Math 5 : : { 6 : : 7 : : /// @concept Multipliable 8 : : /// @brief A concept to check if a type supports multiplication operations. 9 : : /// @tparam T The type to check against the `Multipliable` requirements. 10 : : template <typename T> 11 : : concept Multipliable = requires(T lhs, T rhs) { 12 : : // clang-format off 13 : : {lhs * rhs} -> std::convertible_to<T>; 14 : : // clang-format on 15 : : }; 16 : : 17 : : /// @brief Calculates the power of a base raised to an exponent 18 : : /// 19 : : /// @tparam Base The base. Must support multiplication (*) 20 : : /// @param base The base of type Base 21 : : /// @param exponent A non-negative integer representing the exponent. 22 : : /// 23 : : /// @return The result of raising base to the power of exponent. 24 : : template <Multipliable Base, std::unsigned_integral Exponent> 25 : 2 : constexpr auto Power(Base base, Exponent exponent) -> Base 26 : : { 27 : 2 : auto power = Base{1}; 28 : 6 : while (exponent > Exponent{0U}) { 29 : 4 : if (exponent & Exponent{1U}) { 30 : 2 : power *= base; 31 : : } 32 : 4 : base *= base; 33 : 4 : exponent >>= Exponent{1U}; 34 : : } 35 : 2 : return power; 36 : : } 37 : : 38 : : } // namespace Math