Joshua
open source statistical hierarchical phrase-based machine translation system
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
src/kenlm/util/scoped.hh
00001 #ifndef UTIL_SCOPED_H
00002 #define UTIL_SCOPED_H
00003 /* Other scoped objects in the style of scoped_ptr. */
00004 
00005 #include "util/exception.hh"
00006 #include <cstddef>
00007 #include <cstdlib>
00008 
00009 namespace util {
00010 
00011 class MallocException : public ErrnoException {
00012   public:
00013     explicit MallocException(std::size_t requested) throw();
00014     ~MallocException() throw();
00015 };
00016 
00017 void *MallocOrThrow(std::size_t requested);
00018 void *CallocOrThrow(std::size_t requested);
00019 
00020 /* Unfortunately, defining the operator* for void * makes the compiler complain.
00021  * So scoped is specialized to void.  This includes the functionality common to
00022  * both, namely everything except reference.
00023  */
00024 template <class T, class Closer> class scoped_base {
00025   public:
00026     explicit scoped_base(T *p = NULL) : p_(p) {}
00027 
00028     ~scoped_base() { Closer::Close(p_); }
00029 
00030     void reset(T *p = NULL) {
00031       scoped_base other(p_);
00032       p_ = p;
00033     }
00034 
00035     T *get() { return p_; }
00036     const T *get() const { return p_; }
00037 
00038     T *operator->() { return p_; }
00039     const T *operator->() const { return p_; }
00040 
00041     T *release() {
00042       T *ret = p_;
00043       p_ = NULL;
00044       return ret;
00045     }
00046 
00047   protected:
00048     T *p_;
00049 
00050   private:
00051     scoped_base(const scoped_base &);
00052     scoped_base &operator=(const scoped_base &);
00053 };
00054 
00055 template <class T, class Closer> class scoped : public scoped_base<T, Closer> {
00056   public:
00057     explicit scoped(T *p = NULL) : scoped_base<T, Closer>(p) {}
00058 
00059     T &operator*() { return *scoped_base<T, Closer>::p_; }
00060     const T&operator*() const { return *scoped_base<T, Closer>::p_; }
00061 };
00062 
00063 template <class Closer> class scoped<void, Closer> : public scoped_base<void, Closer> {
00064   public:
00065     explicit scoped(void *p = NULL) : scoped_base<void, Closer>(p) {}
00066 };
00067 
00068 /* Closer for c functions like std::free and cmph cleanup functions */
00069 template <class T, void (*clean)(T*)> struct scoped_c_forward {
00070   static void Close(T *p) { clean(p); }
00071 };
00072 // Call a C function to delete stuff
00073 template <class T, void (*clean)(T*)> class scoped_c : public scoped<T, scoped_c_forward<T, clean> > {
00074   public:
00075     explicit scoped_c(T *p = NULL) : scoped<T, scoped_c_forward<T, clean> >(p) {}
00076 };
00077 
00078 class scoped_malloc : public scoped_c<void, std::free> {
00079   public:
00080     explicit scoped_malloc(void *p = NULL) : scoped_c<void, std::free>(p) {}
00081 
00082     void call_realloc(std::size_t to);
00083 };
00084 
00085 /* scoped_array using delete[] */
00086 struct scoped_delete_array_forward {
00087   template <class T> static void Close(T *p) { delete [] p; }
00088 };
00089 // Hat tip to boost.
00090 template <class T> class scoped_array : public scoped<T, scoped_delete_array_forward> {
00091   public:
00092     explicit scoped_array(T *p = NULL) : scoped<T, scoped_delete_array_forward>(p) {}
00093 
00094     T &operator[](std::size_t idx) { return scoped<T, scoped_delete_array_forward>::p_[idx]; }
00095     const T &operator[](std::size_t idx) const { return scoped<T, scoped_delete_array_forward>::p_[idx]; }
00096 };
00097 
00098 /* scoped_ptr using delete.  If only there were a template typedef. */
00099 struct scoped_delete_forward {
00100   template <class T> static void Close(T *p) { delete p; }
00101 };
00102 template <class T> class scoped_ptr : public scoped<T, scoped_delete_forward> {
00103   public:
00104     explicit scoped_ptr(T *p = NULL) : scoped<T, scoped_delete_forward>(p) {}
00105 };
00106 
00107 void AdviseHugePages(const void *addr, std::size_t size);
00108 
00109 } // namespace util
00110 
00111 #endif // UTIL_SCOPED_H