Created
October 2, 2011 06:34
-
-
Save bullno1/1257145 to your computer and use it in GitHub Desktop.
Tail recursion in C++11
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> | |
#include <functional> | |
template<typename ReturnType, typename Arg1> | |
struct tail_call_result | |
{ | |
template<typename FuncType> | |
inline tail_call_result(FuncType func, Arg1 arg) | |
:func(func) | |
,argument(arg) | |
,isFinal(false) | |
{ | |
} | |
inline tail_call_result(ReturnType result) | |
:result(result) | |
,isFinal(true) | |
{ | |
} | |
inline tail_call_result(const tail_call_result& other) | |
:isFinal(other.isFinal) | |
,result(other.result) | |
,argument(other.argument) | |
,func(other.func) | |
{ | |
} | |
inline tail_call_result() | |
:isFinal(false) | |
,func() | |
{ | |
} | |
operator ReturnType() const | |
{ | |
tail_call_result<ReturnType, Arg1> res(*this); | |
while(true) | |
{ | |
res = func(res.argument); | |
if(res.isFinal) | |
return res.result; | |
} | |
} | |
bool isFinal; | |
ReturnType result; | |
Arg1 argument; | |
std::function<tail_call_result<ReturnType, Arg1>(Arg1)> func; | |
}; | |
template<typename ReturnType, typename FuncType> | |
struct tail_call_enabled_function | |
{ | |
inline tail_call_enabled_function(FuncType func) | |
:func(func) | |
{ | |
} | |
template<typename Arg1> | |
tail_call_result<ReturnType, Arg1> operator()(Arg1 arg) | |
{ | |
return tail_call_result<ReturnType, Arg1>(func, arg); | |
} | |
FuncType func; | |
}; | |
tail_call_result<int, int> _loop(int n); | |
tail_call_enabled_function<int, tail_call_result<int, int>(*)(int n)> loop(_loop); | |
tail_call_result<int, int> _loop(int n) | |
{ | |
if(n == 0) | |
return 123; | |
else | |
{ | |
std::cout << n << std::endl; | |
return loop(n - 1); | |
} | |
} | |
int main(int argc, char* argv[]) | |
{ | |
int result = loop(1000); | |
std::cout << result << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment