summaryrefslogtreecommitdiff
path: root/klm/util/scoped.hh
diff options
context:
space:
mode:
Diffstat (limited to 'klm/util/scoped.hh')
-rw-r--r--klm/util/scoped.hh66
1 files changed, 66 insertions, 0 deletions
diff --git a/klm/util/scoped.hh b/klm/util/scoped.hh
new file mode 100644
index 00000000..ef62a74f
--- /dev/null
+++ b/klm/util/scoped.hh
@@ -0,0 +1,66 @@
+#ifndef UTIL_SCOPED__
+#define UTIL_SCOPED__
+
+/* Other scoped objects in the style of scoped_ptr. */
+
+#include <cstddef>
+
+namespace util {
+
+template <class T, class R, R (*Free)(T*)> class scoped_thing {
+ public:
+ explicit scoped_thing(T *c = static_cast<T*>(0)) : c_(c) {}
+
+ ~scoped_thing() { if (c_) Free(c_); }
+
+ void reset(T *c) {
+ if (c_) Free(c_);
+ c_ = c;
+ }
+
+ T &operator*() { return *c_; }
+ T &operator->() { return *c_; }
+
+ T *get() { return c_; }
+ const T *get() const { return c_; }
+
+ private:
+ T *c_;
+
+ scoped_thing(const scoped_thing &);
+ scoped_thing &operator=(const scoped_thing &);
+};
+
+class scoped_fd {
+ public:
+ scoped_fd() : fd_(-1) {}
+
+ explicit scoped_fd(int fd) : fd_(fd) {}
+
+ ~scoped_fd();
+
+ void reset(int to) {
+ scoped_fd other(fd_);
+ fd_ = to;
+ }
+
+ int get() const { return fd_; }
+
+ int operator*() const { return fd_; }
+
+ int release() {
+ int ret = fd_;
+ fd_ = -1;
+ return ret;
+ }
+
+ private:
+ int fd_;
+
+ scoped_fd(const scoped_fd &);
+ scoped_fd &operator=(const scoped_fd &);
+};
+
+} // namespace util
+
+#endif // UTIL_SCOPED__