00001 /* $Id: array.hpp 18826 2010-01-16 14:22:19Z frosch $ */ 00002 00003 /* 00004 * This file is part of OpenTTD. 00005 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. 00006 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00007 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. 00008 */ 00009 00012 #ifndef ARRAY_HPP 00013 #define ARRAY_HPP 00014 00015 #include "fixedsizearray.hpp" 00016 #include "str.hpp" 00017 00020 template <class T, uint B = 1024, uint N = B> 00021 class SmallArray { 00022 protected: 00023 typedef FixedSizeArray<T, B> SubArray; 00024 typedef FixedSizeArray<SubArray, N> SuperArray; 00025 00026 static const uint Tcapacity = B * N; 00027 00028 SuperArray data; 00029 00031 FORCEINLINE SubArray& FirstFreeSubArray() 00032 { 00033 uint super_size = data.Length(); 00034 if (super_size > 0) { 00035 SubArray& s = data[super_size - 1]; 00036 if (!s.IsFull()) return s; 00037 } 00038 return *data.AppendC(); 00039 } 00040 00041 public: 00043 FORCEINLINE SmallArray() { } 00045 FORCEINLINE void Clear() {data.Clear();} 00047 FORCEINLINE uint Length() const 00048 { 00049 uint super_size = data.Length(); 00050 if (super_size == 0) return 0; 00051 uint sub_size = data[super_size - 1].Length(); 00052 return (super_size - 1) * B + sub_size; 00053 } 00055 FORCEINLINE bool IsEmpty() { return data.IsEmpty(); } 00057 FORCEINLINE bool IsFull() { return data.IsFull() && data[N - 1].IsFull(); } 00059 FORCEINLINE T *Append() { return FirstFreeSubArray().Append(); } 00061 FORCEINLINE T *AppendC() { return FirstFreeSubArray().AppendC(); } 00063 FORCEINLINE T& operator [] (uint index) 00064 { 00065 const SubArray& s = data[index / B]; 00066 T& item = s[index % B]; 00067 return item; 00068 } 00070 FORCEINLINE const T& operator [] (uint index) const 00071 { 00072 const SubArray& s = data[index / B]; 00073 const T& item = s[index % B]; 00074 return item; 00075 } 00076 00077 template <typename D> void Dump(D &dmp) const 00078 { 00079 dmp.WriteLine("capacity = %d", Tcapacity); 00080 uint num_items = Length(); 00081 dmp.WriteLine("num_items = %d", num_items); 00082 CStrA name; 00083 for (uint i = 0; i < num_items; i++) { 00084 const T& item = (*this)[i]; 00085 name.Format("item[%d]", i); 00086 dmp.WriteStructT(name.Data(), &item); 00087 } 00088 } 00089 }; 00090 00091 #endif /* ARRAY_HPP */