xref: /llvm-project/libcxx/test/support/maths.h (revision 3903438860b6eebf53a912c672560e1e55311220)
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 Bella constexpr 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 Bella constexpr 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 Bella constexpr 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