Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace detail {
- template<typename U>
- constexpr U FibOverflowIndicator = 4; //Not a Fibonacci number
- template<typename U, size_t N>
- struct Fib {
- public:
- static constexpr U val =
- (static_cast<U>(static_cast<unsigned long long>(Fib<U, N-1>::val) + Fib<U, N-2>::val) <= Fib<U, N-1>::val)
- ? FibOverflowIndicator<U>
- : Fib<U, N-1>::val + Fib<U, N-2>::val;
- };
- template<typename U>
- struct Fib<U, 0> {
- static constexpr U val = 1;
- };
- template<typename U>
- struct Fib<U, 1> {
- static constexpr U val = 1;
- };
- template<typename U, size_t N>
- constexpr bool isValidFibIndex() {
- return Fib<U, N>::val != FibOverflowIndicator<U>;
- }
- template<typename U, size_t N = 0>
- constexpr std::enable_if_t<!isValidFibIndex<U, N + 1>(), size_t>
- greatestStoreableFibIndex() {
- return N;
- }
- template<typename U, size_t N = 0>
- constexpr std::enable_if_t<isValidFibIndex<U, N + 1>(), size_t>
- greatestStoreableFibIndex() {
- return greatestStoreableFibIndex<U, N + 1>();
- }
- } // namespace detail
- template<typename U, size_t N>
- constexpr U Fib() {
- return detail::Fib<U, N>::val;
- }
- template<typename U>
- struct FibLimit {
- // The number of distinct Fibonacci numbers U can store.
- static constexpr size_t value = detail::greatestStoreableFibIndex<U>() + 1;
- };
- // Fibonacci number n is too large to fit in U, let's return the sequence.
- template<typename U, typename Container, size_t n, U... us>
- constexpr std::enable_if_t<Fib<U, n>() == detail::FibOverflowIndicator<U>, Container>
- make_fibonacci_seq() {
- return {{us...}};
- }
- // Fibonacci number n can fit inside a U, continue.
- template<typename U, typename Container, size_t n, U... us>
- constexpr std::enable_if_t<Fib<U, n>() != detail::FibOverflowIndicator<U>, Container>
- make_fibonacci_seq() {
- return make_fibonacci_seq<U, Container, n+1, us..., Fib<U, n>()>();
- }
- //In class A:
- const std::array<U, FibLimit<U>::value> fibonacci = make_fibonacci_seq<U, std::array<U, FibLimit<U>::value>, 0>();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement