Created
June 21, 2014 21:10
-
-
Save Fiona-J-W/e6f34a8e9f812c5d7890 to your computer and use it in GitHub Desktop.
handle-manager
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 <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