Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/moses-smt/mosesdecoder.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorKenneth Heafield <github@kheafield.com>2014-10-08 16:42:53 +0400
committerKenneth Heafield <github@kheafield.com>2014-10-08 16:42:53 +0400
commit36da8d1e0c17cbdecb7613398464bb9cabb56d20 (patch)
tree640641c55ac102f2fb5178fc816e260c1c0965b7 /util
parente9f0ae951e59b5853ef677b1c627b4e7bc5b48b7 (diff)
KenLM 370f97fa549f02e162a3a0f17bf3ad6cce2c3813
Diffstat (limited to 'util')
-rw-r--r--util/file.cc6
-rw-r--r--util/file.hh26
-rw-r--r--util/scoped.cc4
-rw-r--r--util/scoped.hh123
4 files changed, 71 insertions, 88 deletions
diff --git a/util/file.cc b/util/file.cc
index 25ff8183a..aa61cf9a9 100644
--- a/util/file.cc
+++ b/util/file.cc
@@ -41,9 +41,9 @@ scoped_fd::~scoped_fd() {
}
}
-scoped_FILE::~scoped_FILE() {
- if (file_ && std::fclose(file_)) {
- std::cerr << "Could not close file " << std::endl;
+void scoped_FILE_closer::Close(std::FILE *file) {
+ if (file && std::fclose(file)) {
+ std::cerr << "Could not close file " << file << std::endl;
std::abort();
}
}
diff --git a/util/file.hh b/util/file.hh
index f2bb319d5..7204b6a04 100644
--- a/util/file.hh
+++ b/util/file.hh
@@ -2,6 +2,7 @@
#define UTIL_FILE_H
#include "util/exception.hh"
+#include "util/scoped.hh"
#include "util/string_piece.hh"
#include <cstddef>
@@ -42,29 +43,10 @@ class scoped_fd {
scoped_fd &operator=(const scoped_fd &);
};
-class scoped_FILE {
- public:
- explicit scoped_FILE(std::FILE *file = NULL) : file_(file) {}
-
- ~scoped_FILE();
-
- std::FILE *get() { return file_; }
- const std::FILE *get() const { return file_; }
-
- void reset(std::FILE *to = NULL) {
- scoped_FILE other(file_);
- file_ = to;
- }
-
- std::FILE *release() {
- std::FILE *ret = file_;
- file_ = NULL;
- return ret;
- }
-
- private:
- std::FILE *file_;
+struct scoped_FILE_closer {
+ static void Close(std::FILE *file);
};
+typedef scoped<std::FILE, scoped_FILE_closer> scoped_FILE;
/* Thrown for any operation where the fd is known. */
class FDException : public ErrnoException {
diff --git a/util/scoped.cc b/util/scoped.cc
index 6c5b0c2db..de1d9e940 100644
--- a/util/scoped.cc
+++ b/util/scoped.cc
@@ -32,10 +32,6 @@ void *CallocOrThrow(std::size_t requested) {
return InspectAddr(std::calloc(1, requested), requested, "calloc");
}
-scoped_malloc::~scoped_malloc() {
- std::free(p_);
-}
-
void scoped_malloc::call_realloc(std::size_t requested) {
p_ = InspectAddr(std::realloc(p_, requested), requested, "realloc");
}
diff --git a/util/scoped.hh b/util/scoped.hh
index ae70b6b53..60c36c36a 100644
--- a/util/scoped.hh
+++ b/util/scoped.hh
@@ -4,6 +4,7 @@
#include "util/exception.hh"
#include <cstddef>
+#include <cstdlib>
namespace util {
@@ -16,87 +17,91 @@ class MallocException : public ErrnoException {
void *MallocOrThrow(std::size_t requested);
void *CallocOrThrow(std::size_t requested);
-class scoped_malloc {
+/* Unfortunately, defining the operator* for void * makes the compiler complain.
+ * So scoped is specialized to void. This includes the functionality common to
+ * both, namely everything except reference.
+ */
+template <class T, class Closer> class scoped_base {
public:
- scoped_malloc() : p_(NULL) {}
+ explicit scoped_base(T *p = NULL) : p_(p) {}
- scoped_malloc(void *p) : p_(p) {}
+ ~scoped_base() { Closer::Close(p_); }
- ~scoped_malloc();
-
- void reset(void *p = NULL) {
- scoped_malloc other(p_);
+ void reset(T *p = NULL) {
+ scoped_base other(p_);
p_ = p;
}
- void call_realloc(std::size_t to);
-
- void *get() { return p_; }
- const void *get() const { return p_; }
-
- private:
- void *p_;
-
- scoped_malloc(const scoped_malloc &);
- scoped_malloc &operator=(const scoped_malloc &);
-};
-
-// Hat tip to boost.
-template <class T> class scoped_array {
- public:
- explicit scoped_array(T *content = NULL) : c_(content) {}
-
- ~scoped_array() { delete [] c_; }
-
- T *get() { return c_; }
- const T* get() const { return c_; }
+ T *get() { return p_; }
+ const T *get() const { return p_; }
- T &operator*() { return *c_; }
- const T&operator*() const { return *c_; }
+ T *operator->() { return p_; }
+ const T *operator->() const { return p_; }
- T &operator[](std::size_t idx) { return c_[idx]; }
- const T &operator[](std::size_t idx) const { return c_[idx]; }
-
- void reset(T *to = NULL) {
- scoped_array<T> other(c_);
- c_ = to;
+ T *release() {
+ T *ret = p_;
+ p_ = NULL;
+ return ret;
}
- private:
- T *c_;
+ protected:
+ T *p_;
- scoped_array(const scoped_array &);
- void operator=(const scoped_array &);
+ private:
+ scoped_base(const scoped_base &);
+ scoped_base &operator=(const scoped_base &);
};
-template <class T> class scoped_ptr {
+template <class T, class Closer> class scoped : public scoped_base<T, Closer> {
public:
- explicit scoped_ptr(T *content = NULL) : c_(content) {}
+ explicit scoped(T *p = NULL) : scoped_base<T, Closer>(p) {}
- ~scoped_ptr() { delete c_; }
+ T &operator*() { return *scoped_base<T, Closer>::p_; }
+ const T&operator*() const { return *scoped_base<T, Closer>::p_; }
+};
- T *get() { return c_; }
- const T* get() const { return c_; }
+template <class Closer> class scoped<void, Closer> : public scoped_base<void, Closer> {
+ public:
+ explicit scoped(void *p = NULL) : scoped_base<void, Closer>(p) {}
+};
- T &operator*() { return *c_; }
- const T&operator*() const { return *c_; }
+/* Closer for c functions like std::free and cmph cleanup functions */
+template <class T, void (*clean)(T*)> struct scoped_c_forward {
+ static void Close(T *p) { clean(p); }
+};
+// Call a C function to delete stuff
+template <class T, void (*clean)(T*)> class scoped_c : public scoped<T, scoped_c_forward<T, clean> > {
+ public:
+ explicit scoped_c(T *p = NULL) : scoped<T, scoped_c_forward<T, clean> >(p) {}
+};
- T *operator->() { return c_; }
- const T*operator->() const { return c_; }
+class scoped_malloc : public scoped_c<void, std::free> {
+ public:
+ explicit scoped_malloc(void *p = NULL) : scoped_c<void, std::free>(p) {}
- T &operator[](std::size_t idx) { return c_[idx]; }
- const T &operator[](std::size_t idx) const { return c_[idx]; }
+ void call_realloc(std::size_t to);
+};
- void reset(T *to = NULL) {
- scoped_ptr<T> other(c_);
- c_ = to;
- }
+/* scoped_array using delete[] */
+struct scoped_delete_array_forward {
+ template <class T> static void Close(T *p) { delete [] p; }
+};
+// Hat tip to boost.
+template <class T> class scoped_array : public scoped<T, scoped_delete_array_forward> {
+ public:
+ explicit scoped_array(T *p = NULL) : scoped<T, scoped_delete_array_forward>(p) {}
- private:
- T *c_;
+ T &operator[](std::size_t idx) { return scoped<T, scoped_delete_array_forward>::p_[idx]; }
+ const T &operator[](std::size_t idx) const { return scoped<T, scoped_delete_array_forward>::p_[idx]; }
+};
- scoped_ptr(const scoped_ptr &);
- void operator=(const scoped_ptr &);
+/* scoped_ptr using delete. If only there were a template typedef. */
+struct scoped_delete_forward {
+ template <class T> static void Close(T *p) { delete p; }
+};
+template <class T> class scoped_ptr : public scoped<T, scoped_delete_forward> {
+ public:
+ explicit scoped_ptr(T *p = NULL) : scoped<T, scoped_delete_forward>(p) {}
};
} // namespace util