Advertisement
Guest User

Untitled

a guest
Nov 30th, 2016
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.16 KB | None | 0 0
  1. namespace detail {
  2.    
  3.     template<typename U>
  4.     constexpr U FibOverflowIndicator = 4; //Not a Fibonacci number
  5.  
  6.     template<typename U, size_t N>
  7.     struct Fib {
  8.         public:
  9.             static constexpr U val =
  10.                 (static_cast<U>(static_cast<unsigned long long>(Fib<U, N-1>::val) + Fib<U, N-2>::val) <= Fib<U, N-1>::val)
  11.                 ? FibOverflowIndicator<U>
  12.                 : Fib<U, N-1>::val + Fib<U, N-2>::val;          
  13.     };
  14.  
  15.     template<typename U>
  16.     struct Fib<U, 0> {
  17.         static constexpr U val = 1;
  18.     };
  19.  
  20.     template<typename U>
  21.     struct Fib<U, 1> {
  22.         static constexpr U val = 1;
  23.     };
  24.  
  25.     template<typename U, size_t N>
  26.     constexpr bool isValidFibIndex() {
  27.         return Fib<U, N>::val != FibOverflowIndicator<U>;
  28.     }
  29.  
  30.     template<typename U, size_t N = 0>
  31.     constexpr std::enable_if_t<!isValidFibIndex<U, N + 1>(), size_t>
  32.     greatestStoreableFibIndex() {
  33.         return N;
  34.     }
  35.  
  36.     template<typename U, size_t N = 0>
  37.     constexpr std::enable_if_t<isValidFibIndex<U, N + 1>(), size_t>
  38.     greatestStoreableFibIndex() {
  39.         return greatestStoreableFibIndex<U, N + 1>();
  40.     }
  41. } // namespace detail
  42.  
  43. template<typename U, size_t N>
  44. constexpr U Fib() {
  45.     return detail::Fib<U, N>::val;
  46. }
  47.  
  48. template<typename U>
  49. struct FibLimit {
  50.     // The number of distinct Fibonacci numbers U can store.
  51.     static constexpr size_t value = detail::greatestStoreableFibIndex<U>() + 1;
  52. };
  53.  
  54. // Fibonacci number n is too large to fit in U, let's return the sequence.
  55. template<typename U, typename Container, size_t n, U... us>
  56. constexpr std::enable_if_t<Fib<U, n>() == detail::FibOverflowIndicator<U>, Container>
  57. make_fibonacci_seq() {
  58.     return {{us...}};
  59. }
  60.  
  61. // Fibonacci number n can fit inside a U, continue.
  62. template<typename U, typename Container, size_t n, U... us>
  63. constexpr std::enable_if_t<Fib<U, n>() != detail::FibOverflowIndicator<U>, Container>
  64. make_fibonacci_seq() {
  65.     return make_fibonacci_seq<U, Container, n+1, us..., Fib<U, n>()>();
  66. }
  67.  
  68.  
  69.  
  70. //In class A:
  71.  
  72. 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