Skip to content

Instantly share code, notes, and snippets.

@3noch
Last active August 29, 2015 14:21
Show Gist options
  • Select an option

  • Save 3noch/2633bb06f2bf4d8d48a2 to your computer and use it in GitHub Desktop.

Select an option

Save 3noch/2633bb06f2bf4d8d48a2 to your computer and use it in GitHub Desktop.
RAII Encapsulation
#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