Skip to content

Instantly share code, notes, and snippets.

@srz-zumix
Last active August 29, 2015 14:27
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 srz-zumix/94e3f8b801bd769466e5 to your computer and use it in GitHub Desktop.
Save srz-zumix/94e3f8b801bd769466e5 to your computer and use it in GitHub Desktop.
VC++ 2015 TMP benchmark
// http://qnighy.hatenablog.com/entry/20090204/1233733232
#include <iostream>
using namespace std;
namespace TMP
{
template<bool expr, typename IfTrue, typename IfFalse>
struct select
{
typedef int type;
};
template<typename IfTrue, typename IfFalse>
struct select<true, IfTrue, IfFalse>
{
typedef IfTrue type;
};
template<typename IfTrue, typename IfFalse>
struct select<false, IfTrue, IfFalse>
{
typedef IfFalse type;
};
template<typename t, t expr0, t expr1>
struct lt
{
static const bool value = expr0 < expr1;
};
template<int rest,unsigned long long int n>
struct sectionspacer
{
static void print(ostream &target) {sectionspacer<rest-1, n/10>::print(target);}
};
template<int rest>
struct sectionspacer<rest,0>
{
static void print(ostream &target) {target << "0";sectionspacer<rest-1, 0>::print(target);}
};
template<>
struct sectionspacer<0,0>
{
static void print(ostream &target) {}
};
//template<>
struct biguzero
{
static const unsigned long long int curr = 0;
typedef biguzero next;
static void print(ostream &target) {target<<"0";}
static bool _print(ostream &target) {return false;}
};
template<unsigned long long int acurr, typename anext=biguzero>
struct biguint
{
static const unsigned long long int curr = acurr;
typedef anext next;
static void print(ostream &target) {_print(target);}
static bool _print(ostream &target) {if(anext::_print(target)){sectionspacer<8,acurr>::print(target);}cout<<acurr;return true;}
};
//template<typename a, typename b,int cl=0>
//struct bigplus;
template<typename a, typename b,unsigned long long int cl=0>
struct biguplus
{
typedef
typename select<
lt<unsigned long long int, a::curr+b::curr+cl, 100000000>::value,
biguint<a::curr+b::curr+cl, typename biguplus<typename a::next, typename b::next, 0>::value>,
biguint<(a::curr+b::curr+cl)%100000000, typename biguplus<typename a::next, typename b::next, (a::curr+b::curr+cl)/100000000>::value>
>::type
value;
};
template<>
struct biguplus<biguzero, biguzero, 0>
{
typedef biguzero value;
};
template<typename a, unsigned long long int b>
struct bigudecr
{
typedef
typename select<
lt<unsigned long long int, a::curr, b>::value,
biguint<100000000+a::curr-b, typename bigudecr<typename a::next, 1>::value >,
biguint<a::curr-b, typename a::next>
>::type
value;
};
template<unsigned long long int b>
struct bigudecr<biguint<b>, b>
{
typedef biguzero value;
};
template<unsigned long long int a, unsigned long long int b>
struct bigudecr<biguint<a>, b>
{
typedef biguint<a-b> value;
};
template<unsigned long long int n>
struct bigfib_linear
{
typedef typename biguplus<typename bigfib_linear<n-1>::value, typename bigfib_linear<n-2>::value >::value value;
};
template<>
struct bigfib_linear<1>
{
typedef biguint<1> value;
};
template<>
struct bigfib_linear<0>
{
typedef biguzero value;
};
};
int main()
{
cout << "fib(700) = ";
TMP::bigfib_linear<240>::value::print(cout);
cout << endl;
return 0;
}
@echo off
call :build "%VS120COMNTOOLS%"
call :build "%VS140COMNTOOLS%"
call :clean
pause
goto :EOF
:build
call "%~1\vsvars32.bat"
cl >NUL
call :clean
bash -c "time -p cl.exe /c /EHsc /nologo /Febenchmark benchmark.cpp"
goto :EOF
:clean
del /F *.exe *.obj *.dump 2>NUL
goto :EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment