-
-
Save TylerGlaiel/7b6fa06628883148e4403b3cc616fdec to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <vector> | |
#include <string> | |
#include <iostream> | |
enum class _tree_return { | |
Continue = 0, | |
Prune, | |
Break | |
}; | |
template<typename T, typename F1, typename F2, typename F3> | |
_tree_return _for_tree(T initial, F1 condition, F2 branch, F3 visit) { | |
_tree_return result = visit(initial); | |
if(result == _tree_return::Break) return _tree_return::Break; | |
if(result != _tree_return::Prune) { | |
for(T subnode : branch(initial)) { | |
if(condition(subnode)) { | |
_tree_return result = _for_tree(subnode, condition, branch, visit); | |
if(result == _tree_return::Break) return _tree_return::Break; | |
} | |
} | |
} | |
return _tree_return::Continue; | |
} | |
#define tree_break return _tree_return::Break | |
#define tree_prune return _tree_return::Prune | |
#define tree_continue return _tree_return::Continue | |
//v-- semicolon to not allow you to get the return value here | |
#define for_tree(XName, Xinitial, Condition, Branch, Visit) ;_for_tree(Xinitial, \ | |
[&](decltype(Xinitial) XName){ return Condition; }, \ | |
[&](decltype(Xinitial) XName){ return std::vector<decltype(Xinitial)>Branch; }, \ | |
[&](decltype(Xinitial) XName){ Visit; return _tree_return::Continue; }) | |
//excuse the use of a std::vector in there, I guess you cant return an initialize_list from a lambda | |
//that wouldn't really be an issue if this was implemented at the language level instead of hacked together from lambdas and macros | |
struct Node { | |
Node* left = NULL; | |
Node* right = NULL; | |
std::string value; | |
Node(std::string value):value(value){} | |
}; | |
int main() { | |
//syntax is a little uglier than it could be if it was native | |
//imperative tree sample | |
for_tree(x, std::string(""), x.size()<=8, ({x+"a", x+"b", x+"c"}), { | |
std::cout << x << std::endl; | |
}); | |
//tree structure sample | |
Node mytree("root"); | |
mytree.left = new Node("left"); | |
mytree.right = new Node("right"); | |
mytree.left->left = new Node("leftleft"); | |
for_tree(x, &mytree, x != NULL, ({x->left, x->right}), { | |
std::cout << x->value << std::endl; | |
}); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment