Skip to content

Instantly share code, notes, and snippets.

@stormbrew
Created March 21, 2014 12:05
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 stormbrew/9684750 to your computer and use it in GitHub Desktop.
Save stormbrew/9684750 to your computer and use it in GitHub Desktop.
So recent versions of C++ kind of let you do something obscene that's very reminiscent of ruby blocks...
template <type tNodeType, typename tLambda>
void when(tLambda func)
{
if (tNodeType == node_type) {
func(*reinterpret_cast<node<tNodeType>*>(&data));
}
}
// this is an obscene hack to let you do something like
// the lambda-using when above, but a bit cleaner if more
// abusive:
//
// n.when<compiler::script_file>([](compiler::node<compiler::script_file> &script) {
// // do stuff
// }
//
// vs.
//
// for (auto script : n.where<compiler::script_file>) {
// // do stuff
// }
//
// the former will look nicer again, probably, when lambdas
// can have auto args, which should be in C++14.
template <type tNodeType>
class when_
{
node<tNodeType> *begin_;
node<tNodeType> *end_;
public:
when_(node<tNodeType> *item)
: begin_(item), end_(nullptr)
{
if (item) { end_ = item+1; }
}
node<tNodeType> *begin() { return begin_; }
node<tNodeType> *end() { return end_; }
};
template <type tNodeType>
when_<tNodeType> when()
{
if (tNodeType == node_type) {
return when_<tNodeType>(reinterpret_cast<node<tNodeType>*>(&data));
} else {
return when_<tNodeType>(nullptr);
}
}
// later
for (auto script : into->when<type::script_file>()) {
script.statements.push_back(expr);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment