Last active
August 29, 2015 14:21
-
-
Save 3noch/2633bb06f2bf4d8d48a2 to your computer and use it in GitHub Desktop.
RAII Encapsulation
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
| #pragma once | |
| #include <CePrelude.h> | |
| #include <FunctionObject.h> | |
| /** | |
| * Encapsulates RAII by providing a safe interface to a scarce resource, closing it on destruction. | |
| */ | |
| template<typename T> | |
| struct Resource : FunctionObject<T &>, private Noncopyable | |
| { | |
| using CloseFn = ce::function<void (T &) noexcept>; | |
| Resource(T t, CloseFn closeFn) | |
| : t_ (std::move(t)) | |
| , closeFn_(std::move(closeFn)) {} | |
| Resource(Resource && r) | |
| : t_ (std::move(r.t_)) | |
| , closeFn_(r.closeFn_) | |
| { | |
| r.closeFn_ = [](T & t){}; // Set upstream to no-op for when he dies. | |
| } | |
| ~Resource() noexcept { closeFn_(t_); } | |
| const T & get() const noexcept { return t_; } | |
| T & get() noexcept { return t_; } | |
| const T & operator()() const noexcept { return t_; } | |
| T & operator()() noexcept { return t_; } | |
| const T & operator*() const noexcept { return t_; } | |
| T & operator*() noexcept { return t_; } | |
| const T * operator->() const { return &t_; } | |
| T * operator->() { return &t_; } | |
| private: | |
| T t_; | |
| CloseFn closeFn_; | |
| }; | |
| /** | |
| * Builds a new resource with an opening function to help prevent improper sharing of references to it. | |
| */ | |
| template<typename T, typename CloseFn, typename OpenFn> | |
| inline Resource<T> manageResourceWith(OpenFn openFn, CloseFn closeFn) | |
| { | |
| return Resource<T>(openFn(), [closeFn](T & t) noexcept { closeFn(t); }); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment