Skip to content

Instantly share code, notes, and snippets.

@kinchungwong
Created November 29, 2013 01:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kinchungwong/7700253 to your computer and use it in GitHub Desktop.
Save kinchungwong/7700253 to your computer and use it in GitHub Desktop.
The second step of implementing Fibonacci with C++ Metaprogramming, involving lazy-evaluation.
#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