OpenBSD fixed for lib/DtSvc.
[oweals/cde.git] / cde / lib / DtSvc / include / codelibs / dynarray.h
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $TOG: dynarray.h /main/5 1999/10/15 17:22:58 mgreess $
25  *
26  * (c) Copyright 1996 Digital Equipment Corporation.
27  * (c) Copyright 1993,1994,1996 Hewlett-Packard Company.
28  * (c) Copyright 1993,1994,1996 International Business Machines Corp.
29  * (c) Copyright 1993,1994,1996 Sun Microsystems, Inc.
30  * (c) Copyright 1993,1994,1996 Novell, Inc. 
31  * (c) Copyright 1996 FUJITSU LIMITED.
32  * (c) Copyright 1996 Hitachi.
33  */
34 /* Handle dynamic arrays of arbitrary type and range. */
35
36 #ifndef __DYNARRAY_H_
37 #define __DYNARRAY_H_
38
39 #if !defined(linux) && !defined(CSRG_BASED)
40 #include <generic.h>
41 #endif
42 #if defined(USL) || defined(__uxp__) || defined(__osf__) || defined(sun) || defined(linux) || defined(CSRG_BASED)
43 #define _DELETE_ARRAY(sz) delete[]
44 #else
45 #define _DELETE_ARRAY(sz) delete[(sz)]
46 #endif
47
48
49 // this is used to create an ARRAY of a TYPE
50 #define declare_array(ARRAY, TYPE, BUMP) \
51 class ARRAY \
52 { \
53         long len; \
54         long max; \
55         TYPE *arr; \
56 protected: \
57         TYPE &bumpsize(long); \
58 public: \
59         ARRAY() { arr = 0; max = len = 0; } \
60         ARRAY(long siz) \
61                 { arr = 0; max = len = 0; if (siz > 0) bumpsize(siz-1); } \
62         ARRAY(const ARRAY &); \
63         ~ARRAY() { _DELETE_ARRAY(max) arr; } \
64         ARRAY &operator=(const ARRAY &); \
65         long size() const { return len; } \
66         void reset(long l = 0) { bumpsize(l); len = l; } \
67         TYPE &operator[](long e) \
68                 { if (e < len) return arr[e]; else return bumpsize(e); } \
69         TYPE &elt(long e) const { return arr[e]; } \
70         TYPE &end() { return bumpsize(len); } \
71         TYPE *getarr() const { return arr; } \
72         TYPE *operator()() const { return arr; } \
73 };
74
75 // this implements an ARRAY of a TYPE
76 // - this must be done once and only once in the user code
77 //      printf("0x%X:  max=%d  len=%d  elt=%d\n", this, max, len, elt);
78 #define implement_array(ARRAY, TYPE, BUMP) \
79 TYPE &ARRAY::bumpsize(long elt) \
80 { \
81         if (elt < 0) \
82             elt = 0; \
83         if (elt >= max) \
84         { \
85                 if (max <= 0) \
86                         max = 1; \
87                 long omax = max; \
88                 TYPE *narr = new TYPE[max = elt + (omax > BUMP ? BUMP : omax)]; \
89                 for (long i = 0; i < len; i++) \
90                         narr[i] = arr[i]; \
91                 _DELETE_ARRAY(omax) arr; \
92                 arr = narr; \
93         } \
94         if (elt >= len) \
95                 len = elt + 1; \
96         return arr[elt]; \
97 } \
98 ARRAY &ARRAY::operator=(const ARRAY &a) \
99 { \
100         if (&a == this) \
101             return *this; \
102         if (a.len > len) \
103                 bumpsize(a.len); \
104         len = a.len; \
105         for (long i = 0; i < len; i++) \
106                 arr[i] = a.arr[i]; \
107         return *this; \
108 } \
109 ARRAY::ARRAY(const ARRAY &t) \
110 { \
111         arr = 0; \
112         max = len = 0; \
113         *this = t; \
114 }
115
116 // the user can also use these to define an array of any type
117 #define darray(TYPE) name2(TYPE,array)
118 #define darraydeclare(TYPE) declare_array(darray(TYPE), TYPE, 1024)
119 #define darrayimplement(TYPE) implement_array(darray(TYPE), TYPE, 1024)
120 #define darraydeclare2(TYPE,BUMP) declare_array(darray(TYPE), TYPE, BUMP)
121 #define darrayimplement2(TYPE,BUMP) implement_array(darray(TYPE), TYPE, BUMP)
122
123
124 // this is used to define a DYNARRAY of a TYPE
125 #define declare_dynarray(DYNARRAY, TYPE) \
126 class DYNARRAY \
127 { \
128         long low; \
129         long high; \
130         long min; \
131         long max; \
132         unsigned bump; \
133         TYPE *arr; \
134         TYPE *aptr; \
135         void init(long, long, unsigned); \
136         void chsize(long, long); \
137 public: \
138         DYNARRAY(long l, long s = 0, unsigned b = 1024) { init(l, s, b); } \
139         DYNARRAY() { init(0, 0, 1024); } \
140         DYNARRAY(const DYNARRAY &t) \
141                 { init(t.high - t.low + 1, t.low, t.bump); *this = t; } \
142         ~DYNARRAY() { _DELETE_ARRAY(max - min + 1) arr; } \
143         DYNARRAY &operator=(const DYNARRAY &); \
144         long size() const { return high - low + 1; } \
145         void reset(long len = 0, long st = 0) \
146                 { chsize(st, st + len - 1); high = st + len - 1; low = st; } \
147         long smallest() const { return low; } \
148         long largest() const { return high; } \
149         TYPE &operator[](long e) \
150                 { if (e <= low || e >= high) chsize(e,e); return aptr[e]; } \
151         TYPE &elt(long e) const { return aptr[e]; } \
152         TYPE &end() { return (*this)[largest() + 1]; } \
153         TYPE *getarr() const { return aptr; } \
154         TYPE *operator()() const { return aptr; } \
155 };
156
157 // this creates the code needed for a DYNARRAY of TYPE
158 // - this must be done once and only once in the user code
159 #define implement_dynarray(DYNARRAY, TYPE) \
160 void DYNARRAY::init(long len, long start, unsigned bmp) \
161 { \
162         if (len < 0) \
163             len = 0; \
164         high = start + len - 1; \
165         low = start; \
166         max = high; \
167         min = low; \
168         bump = bmp > 0 ? bmp : 1024; \
169         if (max < min) \
170             max = min; \
171         arr = new TYPE[max - min + 1]; \
172         aptr = arr - min; \
173 } \
174 void DYNARRAY::chsize(long lelt, long helt) \
175 { \
176         long nlow = lelt < low ? lelt : low; \
177         long nhigh = helt > high ? helt : high; \
178         if (nlow <= min || nhigh >= max) \
179         { \
180                 long nmin = nlow < min ? nlow : min; \
181                 long nmax = nhigh > max ? nhigh : max; \
182                 long m = max - min + 1; \
183                 long nm = nmax - nmin + 1 + (m > bump ? bump : m); \
184                 long nl = nhigh - nlow + 1; \
185                 TYPE *narr = new TYPE[nm]; \
186                 TYPE *naptr = narr - nmin; \
187                 for (long i = low; i <= high; i++) \
188                         naptr[i] = aptr[i]; \
189                 _DELETE_ARRAY(m) arr; \
190                 arr = narr; \
191                 aptr = naptr; \
192                 min = nmin; \
193                 max = nmax; \
194         } \
195         high = nhigh; \
196         low = nlow; \
197 } \
198 DYNARRAY &DYNARRAY::operator=(const DYNARRAY &a) \
199 { \
200         if (&a == this) \
201             return *this; \
202         if (a.low < low || a.high > high) \
203                 chsize(a.low, a.high); \
204         low = a.low; \
205         high = a.high; \
206         for (long i = a.low; i <= a.high; i++) \
207                 aptr[i] = a.aptr[i]; \
208         bump = a.bump; \
209         return *this; \
210 }
211
212 // the user can also use these to define arrays of any type
213 #define dynarray(TYPE) name2(TYPE,dynarray)
214 #define dynarraydeclare(TYPE) declare_dynarray(dynarray(TYPE), TYPE)
215 #define dynarrayimplement(TYPE) implement_dynarray(dynarray(TYPE), TYPE)
216
217 // Predefined dynarrays for most common uses
218 /* declare_array(Charbuf, char, 256) */
219
220
221 #endif /* __DYNARRAY_H_ */