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