1*39034388SChristopher Di Bella //===----------------------------------------------------------------------===// 2*39034388SChristopher Di Bella // 3*39034388SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*39034388SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 5*39034388SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*39034388SChristopher Di Bella // 7*39034388SChristopher Di Bella //===----------------------------------------------------------------------===// 8*39034388SChristopher Di Bella 9*39034388SChristopher Di Bella // Implementations of well-known functions in mathematics that are useful for 10*39034388SChristopher Di Bella // testing algorithms. 11*39034388SChristopher Di Bella 12*39034388SChristopher Di Bella #ifndef LIBCXX_TEST_MATHS_H 13*39034388SChristopher Di Bella #define LIBCXX_TEST_MATHS_H 14*39034388SChristopher Di Bella 15*39034388SChristopher Di Bella #include <algorithm> 16*39034388SChristopher Di Bella #include <cassert> 17*39034388SChristopher Di Bella #include <concepts> 18*39034388SChristopher Di Bella #include <ranges> 19*39034388SChristopher Di Bella #include <vector> 20*39034388SChristopher Di Bella 21*39034388SChristopher Di Bella template <std::ranges::forward_range R> triangular_sum(R & input)22*39034388SChristopher Di Bellaconstexpr std::ranges::range_value_t<R> triangular_sum(R& input) { 23*39034388SChristopher Di Bella assert(not std::ranges::empty(input)); 24*39034388SChristopher Di Bella auto [min, max] = std::ranges::minmax_element(input); 25*39034388SChristopher Di Bella return static_cast<std::ranges::range_value_t<R>>( 26*39034388SChristopher Di Bella (static_cast<double>(std::ranges::distance(input)) / 2) * (*min + *max)); 27*39034388SChristopher Di Bella } 28*39034388SChristopher Di Bella 29*39034388SChristopher Di Bella template <std::integral I> factorial(I const n)30*39034388SChristopher Di Bellaconstexpr I factorial(I const n) { 31*39034388SChristopher Di Bella assert(n >= 0); 32*39034388SChristopher Di Bella auto result = I(1); 33*39034388SChristopher Di Bella for (auto i = I(1); i <= n; ++i) { 34*39034388SChristopher Di Bella result *= i; 35*39034388SChristopher Di Bella } 36*39034388SChristopher Di Bella 37*39034388SChristopher Di Bella return result; 38*39034388SChristopher Di Bella } 39*39034388SChristopher Di Bella static_assert(factorial(0) == 1); 40*39034388SChristopher Di Bella static_assert(factorial(1) == 1); 41*39034388SChristopher Di Bella static_assert(factorial(2) == 2); 42*39034388SChristopher Di Bella static_assert(factorial(3) == 6); 43*39034388SChristopher Di Bella static_assert(factorial(4) == 24); 44*39034388SChristopher Di Bella static_assert(factorial(5) == 120); 45*39034388SChristopher Di Bella 46*39034388SChristopher Di Bella template <std::integral I> fibonacci(I const n)47*39034388SChristopher Di Bellaconstexpr I fibonacci(I const n) { 48*39034388SChristopher Di Bella assert(n >= 0); 49*39034388SChristopher Di Bella 50*39034388SChristopher Di Bella auto result = I(0); 51*39034388SChristopher Di Bella auto prev = I(1); 52*39034388SChristopher Di Bella for (auto i = I(0); i < n; ++i) { 53*39034388SChristopher Di Bella result += std::exchange(prev, result); 54*39034388SChristopher Di Bella } 55*39034388SChristopher Di Bella return result; 56*39034388SChristopher Di Bella } 57*39034388SChristopher Di Bella static_assert(fibonacci(0) == 0); 58*39034388SChristopher Di Bella static_assert(fibonacci(1) == 1); 59*39034388SChristopher Di Bella static_assert(fibonacci(2) == 1); 60*39034388SChristopher Di Bella static_assert(fibonacci(3) == 2); 61*39034388SChristopher Di Bella static_assert(fibonacci(4) == 3); 62*39034388SChristopher Di Bella static_assert(fibonacci(5) == 5); 63*39034388SChristopher Di Bella static_assert(fibonacci(6) == 8); 64*39034388SChristopher Di Bella static_assert(fibonacci(7) == 13); 65*39034388SChristopher Di Bella static_assert(fibonacci(8) == 21); 66*39034388SChristopher Di Bella static_assert(fibonacci(9) == 34); 67*39034388SChristopher Di Bella 68*39034388SChristopher Di Bella #endif // LIBCXX_TEST_MATHS_H 69