00001 #ifndef UTIL_SCOPED_H
00002 #define UTIL_SCOPED_H
00003
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
00021
00022
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
00069 template <class T, void (*clean)(T*)> struct scoped_c_forward {
00070 static void Close(T *p) { clean(p); }
00071 };
00072
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
00086 struct scoped_delete_array_forward {
00087 template <class T> static void Close(T *p) { delete [] p; }
00088 };
00089
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
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 }
00110
00111 #endif // UTIL_SCOPED_H