00001 /* 00002 * xyzzy 00003 * Copyright (C) 2007 Karl W. Pfalzer 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the 00017 * Free Software Foundation, Inc. 00018 * 51 Franklin Street, Fifth Floor 00019 * Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #if !defined(_xyzzy_array_hxx_) 00023 # define _xyzzy_array_hxx_ 00024 00025 #include "xyzzy/exception.hxx" 00026 #include "xyzzy/refcnt.hxx" 00027 00028 namespace xyzzy 00029 { 00033 class TArray 00034 { 00035 public: 00036 typedef signed long len_t; 00037 00038 class IndexOutOfBoundsException : public TException 00039 { 00040 public: 00041 explicit IndexOutOfBoundsException(len_t max, len_t ix); 00042 00043 private: 00044 len_t m_max, m_ix; 00045 }; 00046 00047 len_t length() const 00048 { 00049 return m_len; 00050 } 00051 00052 protected: 00053 explicit TArray(); 00054 00055 explicit TArray(len_t len); 00056 00057 len_t checkIx(len_t ix) const throw(IndexOutOfBoundsException); 00058 00059 len_t m_len; 00060 }; 00061 00063 template<class T> 00064 class PTArray : public TArray 00065 { 00066 public: 00067 explicit PTArray() 00068 : TArray(0), mp_ar(0) 00069 {} 00070 00071 explicit PTArray(len_t len) 00072 : mp_ar(0) 00073 { 00074 resize(len); 00075 } 00076 00077 PTArray(const PTArray &r) 00078 : mp_ar(0) 00079 { 00080 resize(r.length()); 00081 copy(r); 00082 } 00083 00084 explicit PTArray(const T* const p, const T stopAt) 00085 : mp_ar(0) 00086 { 00087 int n = 0; 00088 for (; stopAt != p[n]; n++) 00089 ; 00090 resize(n); 00091 for (n = 0; n < length(); n++) 00092 this->operator[](n) = p[n]; 00093 } 00094 00095 PTArray& operator=(const PTArray &r) 00096 { 00097 resize(r.length()); 00098 copy(r); 00099 return *this; 00100 } 00101 00102 void resize(len_t len) 00103 { 00104 delete [] mp_ar; 00105 m_len = len; 00106 mp_ar = new T[m_len]; 00107 } 00108 00109 T& operator[](len_t ix) 00110 { 00111 return mp_ar[checkIx(ix)]; 00112 } 00113 00114 const T& operator[](len_t ix) const 00115 { 00116 return mp_ar[checkIx(ix)]; 00117 } 00118 00119 ~PTArray() 00120 { 00121 delete [] mp_ar; 00122 } 00123 00124 static void copy(const PTArray &from, PTArray &to) 00125 { 00126 invariant(from.length() == to.length()); 00127 for (int i = 0; i < from.length(); i++) 00128 { 00129 to[i] = from[i]; 00130 } 00131 } 00132 00133 private: 00134 T *mp_ar; 00135 00136 void copy(const PTArray &from) 00137 { 00138 copy(from, *this); 00139 } 00140 }; 00141 00142 template<class T> 00143 class PTRcArray 00144 { 00145 public: 00146 typedef TArray::len_t len_t; 00147 00148 explicit PTRcArray() 00149 : m_ar(0) 00150 {} 00151 00152 PTRcArray(PTArray<T> *p) 00153 : m_ar(p) 00154 {} 00155 00156 PTRcArray(const PTRcArray &r) 00157 : m_ar(r.m_ar) 00158 {} 00159 00160 const PTRcArray& operator=(const PTRcArray &r) 00161 { 00162 if (this != &r) 00163 { 00164 m_ar = r.m_ar; 00165 } 00166 return *this; 00167 } 00168 00169 len_t length() const 00170 { 00171 return m_ar->length(); 00172 } 00173 00174 T& operator[](len_t ix) 00175 { 00176 return m_ar->operator[](ix); 00177 } 00178 00179 const T& operator[](len_t ix) const 00180 { 00181 return m_ar->operator[](ix); 00182 } 00183 00184 bool isNull() const 00185 { 00186 return m_ar.isNull(); 00187 } 00188 00189 private: 00190 PTRcPtr<PTArray<T> > m_ar; 00191 }; 00192 }; 00193 00194 #endif //_xyzzy_array_hxx_