00001 #ifndef COMMONS_ARRAY_H
00002 #define COMMONS_ARRAY_H
00003
00004 #include <boost/unique_ptr.hpp>
00005 #include <commons/algo.h>
00006 #include <commons/check.h>
00007 #include <commons/nullptr.h>
00008 #include <commons/utility.h>
00009
00010 namespace commons {
00011
00012 using namespace boost;
00013
00014 template<typename T> class array;
00015 template<typename T> class sized_array;
00016 template<typename T> void swap(array<T> &a, array<T> &b);
00017 template<typename T> void swap(sized_array<T> &a, sized_array<T> &b);
00018
00019
00024 template<typename T>
00025 class sized_array {
00026 friend void swap<>(sized_array<T> &a, sized_array<T> &b);
00027 public:
00028 explicit sized_array(char *p, size_t n) : p_(p), n_(n) {}
00029 size_t size() const { return n_; }
00030 T *get() const { return p_; }
00031 T *end() const { return p_ + n_; }
00032 T operator[](size_t i) const { return p_[i]; }
00033 void reset(T *p, size_t n) { p_ = p; n_ = n; }
00034 private:
00035 T *p_;
00036 size_t n_;
00037 };
00038
00039
00044 template<typename T>
00045 class array {
00046 EXPAND(unique_ptr<T[]>)
00047 friend void swap<>(array<T> &a, array<T> &b);
00048 public:
00049 explicit array(size_t n) : p_(new T[n]), n_(n) {}
00050 size_t size() const { return n_; }
00051 T *get() const { return p_.get(); }
00052 T *release() { return p_.release(); }
00053 T *end() const { return this->get() + n_; }
00054 T operator[](size_t i) const { return p_[i]; }
00055 void reset(T *p, size_t n) { p_.reset(p); n_ = n; }
00056 private:
00057 unique_ptr<T[]> p_;
00058 size_t n_;
00059 };
00060
00064 template<typename T>
00065 void
00066 swap(array<T> &a, array<T> &b)
00067 {
00068 swap(a.p_, b.p_);
00069 swap(a.n_, b.n_);
00070 }
00071
00072
00076 template<typename T>
00077 void
00078 swap(sized_array<T> &a, sized_array<T> &b)
00079 {
00080 swap(a.p_, b.p_);
00081 swap(a.n_, b.n_);
00082 }
00083
00087 template<typename T>
00088 class managed_array {
00089 NONCOPYABLE(managed_array)
00090 public:
00091 managed_array(T *p, bool scoped) : p_(p), scoped_(scoped) {}
00092 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00093 managed_array(managed_array<T> &&a) : p_(a.p_), scoped_(a.scoped_) { a.release(); }
00094 #endif
00095 ~managed_array() { if (scoped_) delete [] p_; }
00096 T *release() { T *p = p_; p_ = nullptr; scoped_ = false; return p; }
00097 T *get() { return p_; }
00098 const T *get() const { return p_; }
00099 operator T*() { return p_; }
00100 operator const T*() const { return p_; }
00101 bool scoped() const { return scoped_; }
00102 bool &scoped() { return scoped_; }
00103 private:
00104 T *p_;
00105 bool scoped_;
00106 };
00107
00108 }
00109
00110 #endif