00001 /*
00002 File: ObjArray.cc
00003
00004 Function: See header file
00005
00006 Author(s): Andrew Willmott
00007
00008 Copyright: (c) 1995-2000, Andrew Willmott
00009
00010 Notes: Parse routines yet to be finished
00011 Object may have to be split out.
00012
00013 */
00014
00015 #include "cl/ObjArray.h"
00016 #include "cl/String.h"
00017
00018
00019 ObjArray::ObjArray(Int size, Int alloc) : items(size),
00020 allocated(alloc)
00021 {
00022 Assert(size > 0, "(ObjArray) Initial array size must be positive!");
00023 Assert(alloc >= size, "(ObjArray) Initial array allocation must be >= size!");
00024
00025 item = new ObjectPtr[allocated];
00026 }
00027
00028 ObjArray::ObjArray(const ObjArray &array) : items(array.items), allocated(array.allocated)
00029 {
00030 Int i;
00031
00032 if (allocated)
00033 {
00034 item = new ObjectPtr[allocated];
00035 }
00036 else
00037 item = 0;
00038
00039
00040 for (i = 0; i < array.items; i++)
00041 item[i] = array.item[i]->Clone();
00042 }
00043
00044 ObjArray::~ObjArray()
00045 {
00046 }
00047
00048
00049 // --- ObjArray operators ----------------------------------------
00050
00051
00052 ObjArray &ObjArray::operator >> (Action<ObjectPtr> &a)
00053 {
00054 Int i;
00055
00056 a.Start();
00057
00058 for (i = 0; i < items; i++)
00059 a.Process(item[i]);
00060
00061 a.Stop();
00062
00063 return(SELF);
00064 }
00065
00066 ObjArray &ObjArray::operator = (const ObjArray &array)
00067 {
00068 Int i;
00069
00070 Clear();
00071
00072 if (allocated < array.allocated)
00073 {
00074 delete[] item;
00075 allocated = array.allocated;
00076 item = new ObjectPtr[allocated];
00077 }
00078
00079 for (i = 0; i < array.items; i++)
00080 item[i] = array.item[i]->Clone();
00081
00082 items = array.items;
00083
00084 return(SELF);
00085 }
00086
00087 Void ObjArray::Print(ostream &s) const
00088 {
00089 Int i;
00090
00091 s << '[';
00092
00093 if (NumItems() > 0)
00094 {
00095 item[0]->Print(s);
00096
00097 for (i = 1; i < NumItems(); i++)
00098 item[i]->Print(s << ' ');
00099 }
00100
00101 s << ']';
00102 }
00103
00104 Void ObjArray::Parse(istream &s)
00105 {
00106 Char c;
00107
00108 // Expected format: [a b c d ...]
00109
00110 ChompWhiteSpace(s);
00111
00112 if (s.peek() == '[')
00113 {
00114 s.get(c);
00115 Clear();
00116
00117 ChompWhiteSpace(s);
00118
00119 while (s.peek() != ']')
00120 {
00121 Add(1);
00122 Top()->Parse(s); // read an item
00123
00124 if (!s)
00125 {
00126 Expect(false, "Couldn't read array component");
00127 return;
00128 }
00129
00130 ChompWhiteSpace(s);
00131 }
00132 s.get(c);
00133 }
00134 else
00135 {
00136 s.clear(ios::failbit);
00137 Expect(false, "Error: Expected '[' while reading array");
00138 }
00139 }
00140
00141
00142 // --- ObjArray Methods --------------------------------------------
00143
00144
00145 Void ObjArray::Clear()
00146 {
00147 Int i;
00148
00149 for (i = 0; i < items; i++)
00150 item[i]->Free();
00151
00152 items = 0;
00153 }
00154
00155 Void ObjArray::Free()
00156 {
00157 Clear();
00158 delete[] item;
00159 }
00160
00161 ObjectPtr ObjArray::Clone() const
00162 {
00163 ObjectPtr result = new ObjArray(SELF);
00164
00165 return(result);
00166 }
00167
00168 Void ObjArray::SetSize(Int newSize)
00169 {
00170 Int i;
00171 ObjectPtr *newObjArray;
00172
00173 if (newSize > allocated)
00174 {
00175 if (allocated == 0)
00176 allocated = kFirstObjAlloc;
00177 else
00178 allocated *= 2;
00179
00180 while (newSize > allocated)
00181 allocated *= 2;
00182
00183 newObjArray = new ObjectPtr[allocated];
00184
00185 for (i = 0; i < items; i++)
00186 newObjArray[i] = item[i];
00187
00188 delete[] item;
00189 item = newObjArray;
00190 }
00191 items = newSize;
00192 }
00193
00194 Void ObjArray::Add(Int n)
00195 {
00196 SetSize(items + n);
00197 }
00198
00199 Void ObjArray::Shrink(Int n)
00200 // take away n items.
00201 {
00202 items -= n;
00203 }
00204
00205 Void ObjArray::Insert(Int i, Int n)
00206 // Make space at position i for n items.
00207 {
00208 Assert(i >= 0 && i <= items, "(ObjArray:InsertSpace) Illegal index");
00209
00210 Int j;
00211
00212 Add(n);
00213
00214 for (j = items - 1; j >= i + n; j--)
00215 item[j] = (item - n)[j];
00216
00217 for (j = i; j < i + n; j++)
00218 item[j] = 0;
00219 }
00220
00221 Void ObjArray::Delete(Int i, Int n)
00222 // Delete n items at position i.
00223 {
00224 Assert(i >= 0 && i <= items, "(ObjArray:InsertSpace) Illegal index");
00225
00226 Int j;
00227
00228 for (j = i; j < i + n; j++)
00229 item[j]->Free();
00230
00231 items -= n;
00232
00233 for (j = i; j < items; j++)
00234 item[j] = (item + n)[j];
00235 }
00236
00237 Void ObjArray::ShrinkWrap()
00238 // Shrink allocated space to be only the current size of array
00239 {
00240 // There is no realloc version of new in C++, so this involves another copy...
00241
00242 Int i;
00243 ObjectPtr *newObjArray;
00244
00245 allocated = items;
00246
00247 newObjArray = new ObjectPtr[allocated];
00248
00249 for (i = 0; i < items; i++)
00250 newObjArray[i] = item[i];
00251
00252 delete[] item;
00253 item = newObjArray;
00254 }
00255
00256 Void ObjArray::Grow()
00257 // Allocate more space for the array. Used internally prior to an items++.
00258 {
00259 Int i;
00260 ObjectPtr *newObjArray;
00261
00262 if (allocated == 0)
00263 allocated = kFirstObjAlloc;
00264 else
00265 allocated *= 2;
00266
00267 newObjArray = new ObjectPtr[allocated];
00268
00269 for (i = 0; i < items; i++)
00270 newObjArray[i] = item[i];
00271
00272 delete[] item;
00273 item = newObjArray;
00274 }