00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CS_GARRAY_H__
00021 #define __CS_GARRAY_H__
00022
00026 #define CS_GARRAY_GROWSTEP 16
00027
00032 #define CS_GARRAY_SHRINKLIMIT 1000
00033
00034
00035 #define CS_TYPEDEF_GROWING_ARRAY_EXT(Name, Type, ExtraConstructor, Extra) \
00036 class Name \
00037 { \
00038 typedef Type ga_type; \
00039 ga_type *root; \
00040 int limit; \
00041 int length; \
00042 public: \
00043 int Limit () const \
00044 { return limit; } \
00045 void SetLimit (int inlimit) \
00046 { \
00047 if (limit == inlimit) return; \
00048 if ((limit = inlimit)!=0) \
00049 root = (ga_type *)realloc (root, limit * sizeof (ga_type)); \
00050 else \
00051 { if (root) { free (root); root = NULL; } } \
00052 } \
00053 Name () \
00054 { limit = length = 0; root = NULL; ExtraConstructor; } \
00055 ~Name () \
00056 { SetLimit (0); } \
00057 int Length () const \
00058 { return length; } \
00059 void SetLength (int inlength, int growstep = CS_GARRAY_GROWSTEP) \
00060 { \
00061 length = inlength; \
00062 int newlimit = ((length + (growstep - 1)) / growstep) * growstep; \
00063 if (newlimit > limit || newlimit < limit-CS_GARRAY_SHRINKLIMIT) \
00064 SetLimit (newlimit); \
00065 } \
00066 ga_type &operator [] (int n) \
00067 { CS_ASSERT (n >= 0 && n < limit); return root [n]; } \
00068 const ga_type &operator [] (int n) const \
00069 { CS_ASSERT (n >= 0 && n < limit); return root [n]; } \
00070 ga_type &Get (int n) \
00071 { CS_ASSERT (n >= 0 && n < limit); return root [n]; } \
00072 void Delete (int n) \
00073 { CS_ASSERT (n >= 0 && n < limit); \
00074 memmove (root + n, root + n + 1, (limit - n - 1) * sizeof (ga_type)); \
00075 SetLength (length-1); } \
00076 ga_type *GetArray () \
00077 { return root; } \
00078 int Push (const ga_type &val, int growstep = CS_GARRAY_GROWSTEP) \
00079 { \
00080 SetLength (length + 1, growstep); \
00081 memcpy (root + length - 1, &val, sizeof (ga_type)); \
00082 return length-1; \
00083 } \
00084 void Insert (int pos, const ga_type &val, int growstep=CS_GARRAY_GROWSTEP)\
00085 { \
00086 CS_ASSERT (pos>=0 && pos<=length); \
00087 SetLength (length + 1, growstep); \
00088 memmove (root+pos+1, root+pos, sizeof(ga_type) * (length-pos-1)); \
00089 memcpy (root + pos, &val, sizeof (ga_type)); \
00090 } \
00091 Extra \
00092 }
00093
00113 #define CS_TYPEDEF_GROWING_ARRAY(Name, Type) \
00114 CS_TYPEDEF_GROWING_ARRAY_EXT (Name, Type, ;, ;)
00115
00127 #define CS_TYPEDEF_GROWING_ARRAY_REF(Name, Type) \
00128 CS_TYPEDEF_GROWING_ARRAY_EXT (Name, Type, RefCount = 0, \
00129 int RefCount; \
00130 void IncRef () \
00131 { RefCount++; } \
00132 void DecRef () \
00133 { \
00134 if (RefCount == 1) SetLimit (0); \
00135 RefCount--; \
00136 })
00137
00148 #define CS_DECLARE_GROWING_ARRAY(Name, Type) \
00149 CS_TYPEDEF_GROWING_ARRAY(__##Name##_##Type,Type) Name
00150
00154 #define CS_DECLARE_GROWING_ARRAY_REF(Name, Type) \
00155 CS_TYPEDEF_GROWING_ARRAY_REF(__##Name,Type) Name
00156
00157 #endif // __CS_GARRAY_H__