Skip to content

Instantly share code, notes, and snippets.

@dmatveev
Last active December 20, 2015 21:49
Show Gist options
  • Save dmatveev/6200371 to your computer and use it in GitHub Desktop.
Save dmatveev/6200371 to your computer and use it in GitHub Desktop.
I really like the things I can do easily with C++11x. An example: some RAII madness. Just replace begin/end/unwinding with lock/unlock/etc operations else, and you will get an utility for transactional access to multiple objects.
/* g++ -std=c++11 wrap.cc */
#include <functional>
#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
typedef std::function<void ()> Action;
typedef std::function<void (Action)> Context;
class Foo {
const std::string _str;
void msg (const std::string &text) {
std::cout << "* " << _str << " " << text << std::endl;
}
public:
Foo (const std::string &str) : _str (str) {}
void ensure (const Action &act) {
msg ("begin");
try {
act();
} catch (...) {
msg ("unwinding");
throw;
}
msg ("end");
};
};
int main (int argc, char *argv[]) {
const std::vector<std::string> samples = {
"Foo", "Bar", "Baz"
};
std::vector<Foo *> foos;
std::transform (samples.begin(), samples.end(),
std::back_inserter (foos),
[](const std::string &s) { return new Foo (s); });
Context ctx = [&foos](const Action &act) {
foos.front()->ensure (act);
};
for (auto it = foos.begin() + 1; it != foos.end(); ++it) {
Foo *foo = *it;
ctx = [ctx, foo] (const Action &act) {
foo->ensure ([ctx, act]() { ctx (act); });
};
}
std::cout << "Successful case:" << std::endl;
ctx ([]() { std::cout << " - I am an action!" << std::endl; });
std::cout << "And unsuccessful one" << std::endl;
try {
ctx ([]() { throw "Oops!"; });
} catch (...) {
std::cout << "Got it? :)" << std::endl;
}
return 0;
}
// /tmp $ ./a.out
// Successful case:
// * Baz begin
// * Bar begin
// * Foo begin
// - I am an action!
// * Foo end
// * Bar end
// * Baz end
// And unsuccessful one
// * Baz begin
// * Bar begin
// * Foo begin
// * Foo unwinding
// * Bar unwinding
// * Baz unwinding
// Got it? :)
// /tmp $
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment