Wayverb
stable.h
1 #pragma once
2 
3 #include "utilities/tuple_like.h"
4 
5 #include <cmath>
6 
7 namespace wayverb {
8 namespace waveguide {
9 namespace detail {
10 
11 template <typename T, size_t... Ix>
12 constexpr auto make_next_array(T&& a, double rci, std::index_sequence<Ix...>) {
13  constexpr auto size = sizeof...(Ix);
14  return std::array<double, size>{
15  {(util::tuple_like_getter<Ix>(a) -
16  util::tuple_like_getter<size - Ix>(a) * rci) /
17  (1 - rci * rci)...}};
18 }
19 
20 template <typename T>
21 constexpr auto make_next_array(T&& a, double rci) {
22  constexpr auto size = util::tuple_like_size_v<util::decay_const_ref_t<T>>;
23  return make_next_array(
24  std::forward<T>(a), rci, std::make_index_sequence<size - 1>{});
25 }
26 
27 } // namespace detail
28 
29 template <typename T,
30  std::enable_if_t<
31  util::tuple_like_size_v<util::decay_const_ref_t<T>> == 1,
32  int> = 0>
33 constexpr auto is_stable(T&&) {
34  return true;
35 }
36 
39 template <typename T,
40  std::enable_if_t<
41  util::tuple_like_size_v<util::decay_const_ref_t<T>> != 1,
42  int> = 0>
43 constexpr auto is_stable(T&& a) {
44  constexpr auto size = util::tuple_like_size_v<util::decay_const_ref_t<T>>;
45  const auto rci = util::tuple_like_getter<size - 1>(a);
46  if (1 <= std::abs(rci)) {
47  return false;
48  }
49  return is_stable(detail::make_next_array(std::forward<T>(a), rci));
50 }
51 
52 } // namespace waveguide
53 } // namespace wayverb
Definition: traits.h:46
Definition: capsule_base.h:9