Skip to content

Instantly share code, notes, and snippets.

@Fiona-J-W
Created June 21, 2014 21:10
Show Gist options
  • Save Fiona-J-W/e6f34a8e9f812c5d7890 to your computer and use it in GitHub Desktop.
Save Fiona-J-W/e6f34a8e9f812c5d7890 to your computer and use it in GitHub Desktop.
handle-manager
#include <type_traits>
#include <utility>
template<typename Handle, class Releaser>
Handle get_null_handle() {
return Handle{};
}
template<typename Handle, typename Releaser>
class resource {
public:
resource(Handle h, Releaser releaser): h{h}, releaser{releaser} {};
~resource() {
if (h != get_null_handle<Handle, Releaser>()) {
releaser(h);
}
}
resource(const resource&) = delete;
resource& operator=(const resource&) = delete;
resource(resource&& other): h{std::move(other.h)}, releaser{other.releaser} {
other.h = get_null_handle<Handle, Releaser>();
}
resource& operator=(resource&& other) {
h = std::move(other.h);
other.h = get_null_handle<Handle, Releaser>();
releaser = other.releaser;
}
operator Handle&() {
return h;
}
operator const Handle&() const {
return h;
}
private:
Handle h;
Releaser releaser;
};
template<typename Creator, typename Releaser, typename...Args>
auto make_resource(Creator creator, Releaser releaser, Args&&... args) {
using handle = decltype(creator(std::forward<Args...>(args...)));
return resource<handle, Releaser>{creator(std::forward<Args...>(args...)), releaser};
}
////////////////////////////////////////////////////////////////
#include <yoga/yoga.hpp>
int create_resource(int i){
yoga::writefln("creating ressource %s", i);
return i;
}
void release_resource(int i) {
yoga::writefln("releasing %s", i);
}
auto my_ressource_maker(int i) {
return make_resource(create_resource, release_resource, i);
}
template<typename T>
auto fun(const T& arg) {
auto y = my_ressource_maker(arg + 1);
yoga::writeln("inside fun");
return y;
}
int main() {
auto x = make_resource(create_resource, release_resource, 3);
yoga::writeln("before fun");
auto y = fun(x);
yoga::writeln("after fun");
yoga::writeln("y = ", y);
//auto z = y; // guaranteed compiler-error
auto z = std::move(y); // this works
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment