Created
November 29, 2013 01:13
-
-
Save kinchungwong/7700253 to your computer and use it in GitHub Desktop.
The second step of implementing Fibonacci with C++ Metaprogramming, involving lazy-evaluation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
template <class First, class Second> struct Add; | |
template <int First, int Second> | |
struct Add< | |
std::integral_constant<int, First>, | |
std::integral_constant<int, Second>> | |
{ | |
typedef int value_type; | |
typedef std::integral_constant<value_type, (First + Second)> type; | |
static const value_type value = type::value; | |
value_type operator() () const { return value; } | |
}; | |
template <class First, class Second> struct Subtract; | |
template <int First, int Second> | |
struct Subtract< | |
std::integral_constant<int, First>, | |
std::integral_constant<int, Second>> | |
{ | |
typedef int value_type; | |
typedef std::integral_constant<value_type, (First - Second)> type; | |
static const value_type value = type::value; | |
value_type operator() () const { return value; } | |
}; | |
template <class CValueOne, class CValueTwo> struct Equals; // Prototype | |
template <int First, int Second> | |
struct Equals< | |
std::integral_constant<int, First>, | |
std::integral_constant<int, Second>> | |
: std::false_type | |
{ | |
// Inherited from std::false_type | |
}; | |
template <int First> | |
struct Equals< | |
std::integral_constant<int, First>, | |
std::integral_constant<int, First>> | |
: std::true_type | |
{ | |
// Inherited from std::true_type | |
}; | |
template <class First, class Second> struct Less; // Prototype | |
template <int First, int Second> | |
struct Less< | |
std::integral_constant<int, First>, | |
std::integral_constant<int, Second>> | |
: std::integral_constant<bool, (First < Second)> | |
{ | |
// Inherited from std::integral_constant<bool, constexpr> | |
}; | |
template <bool Cond, class EvalIfTrue, class EvalIfFalse> | |
struct ConditionalEval; | |
template <class EvalIfTrue, class EvalIfFalse> | |
struct ConditionalEval<false, EvalIfTrue, EvalIfFalse> | |
{ | |
typedef typename EvalIfFalse::type type; | |
}; | |
template <class EvalIfTrue, class EvalIfFalse> | |
struct ConditionalEval<true, EvalIfTrue, EvalIfFalse> | |
{ | |
typedef typename EvalIfTrue::type type; | |
}; | |
template <class CIndex> | |
struct Fibonacci | |
{ | |
struct details | |
{ | |
typedef std::integral_constant<int, 0> N0; | |
typedef std::integral_constant<int, 1> N1; | |
typedef std::integral_constant<int, 2> N2; | |
typedef std::integral_constant<int, 42> Nuniverse; | |
}; | |
typedef typename ConditionalEval< | |
Less<typename CIndex::type, typename details::N2>::value, | |
typename details::N1, | |
/* typename details::Nuniverse */ | |
Fibonacci<Subtract<typename CIndex::type, typename details::N2>> | |
>::type type; | |
}; | |
int main() | |
{ | |
typedef std::integral_constant<int, 0> N0; | |
typedef std::integral_constant<int, 1> N1; | |
typedef std::integral_constant<int, 2> N2; | |
typedef std::integral_constant<int, 3> N3; | |
typedef std::integral_constant<int, 4> N4; | |
typedef std::integral_constant<int, 5> N5; | |
std::cout << "N0 gives: " << Fibonacci<N0>::type::value << std::endl; | |
std::cout << "N1 gives: " << Fibonacci<N1>::type::value << std::endl; | |
std::cout << "N2 gives: " << Fibonacci<N2>::type::value << std::endl; | |
std::cout << "N3 gives: " << Fibonacci<N3>::type::value << std::endl; | |
std::cout << "N4 gives: " << Fibonacci<N4>::type::value << std::endl; | |
std::cout << "N5 gives: " << Fibonacci<N4>::type::value << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment