ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/libptytty/src/estl.h
Revision: 1.30
Committed: Sun Jun 27 16:45:42 2021 UTC (5 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.29: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.30 /* this file lives in libptytty/src/estl.h, only edit it there and copy it here */
2 root 1.4 #ifndef ESTL_H_
3     #define ESTL_H_
4 sf-exg 1.2
5 sf-exg 1.1 #include <stdlib.h>
6     #include <string.h>
7    
8 root 1.9 #include "ecb.h"
9    
10 sf-exg 1.5 template<typename T, typename U> static inline T min (T a, U b) { return a < (T)b ? a : (T)b; }
11     template<typename T, typename U> static inline T max (T a, U b) { return a > (T)b ? a : (T)b; }
12 sf-exg 1.1
13 root 1.3 template<typename T, typename U> static inline void swap (T& a, U& b) { T t = a; a = (T)b; b = (U)t; }
14 sf-exg 1.1
15     template <typename I, typename T>
16     I find (I first, I last, const T& value)
17     {
18     while (first != last && *first != value)
19     ++first;
20    
21     return first;
22     }
23    
24 root 1.8 #include <new>
25    
26 root 1.21 #if ECB_CPP11
27 root 1.8 #include <type_traits>
28     #endif
29    
30 sf-exg 1.28 namespace estl
31     {
32     #if ESTL_LARGE_MEMORY_MODEL
33     // should use size_t/ssize_t, but that's not portable enough for us
34     typedef unsigned long size_type;
35     typedef long difference_type;
36     #else
37     typedef uint32_t size_type;
38     typedef int32_t difference_type;
39     #endif
40    
41     template<typename T>
42     struct scoped_ptr
43     {
44     T *p;
45    
46     scoped_ptr () : p (0) { }
47    
48     explicit
49     scoped_ptr (T *a) : p (a) { }
50    
51     ~scoped_ptr ()
52     {
53     delete p;
54     }
55    
56     void reset (T *a)
57     {
58     delete p;
59     p = a;
60     }
61    
62     T *operator ->() const { return p; }
63     T &operator *() const { return *p; }
64    
65     operator T *() { return p; }
66     T *get () const { return p; }
67 sf-exg 1.29
68     private:
69     scoped_ptr (const scoped_ptr &);
70     scoped_ptr &operator =(const scoped_ptr &);
71 sf-exg 1.28 };
72    
73     template<typename T>
74     struct scoped_array
75     {
76     T *p;
77    
78     scoped_array () : p (0) { }
79    
80     explicit
81     scoped_array (T *a) : p (a) { }
82    
83     ~scoped_array ()
84     {
85     delete [] p;
86     }
87    
88     void reset (T *a)
89     {
90     delete [] p;
91     p = a;
92     }
93    
94     operator T *() { return p; }
95     T *get () const { return p; }
96 sf-exg 1.29
97     private:
98     scoped_array (const scoped_array &);
99     scoped_array &operator =(const scoped_array &);
100 sf-exg 1.28 };
101     }
102    
103 root 1.9 // original version taken from MICO, but this has been completely rewritten
104     // known limitations w.r.t. std::vector
105     // - many methods missing
106 root 1.12 // - no error checking, no exceptions thrown (e.g. at())
107 root 1.9 // - size_type is 32bit even on 64 bit hosts, so limited to 2**31 elements
108     // - no allocator support
109     // - we don't really care about const correctness, but we try
110     // - we don't care about namespaces and stupid macros the user might define
111 root 1.12 // - no bool specialisation
112 sf-exg 1.1 template<class T>
113     struct simplevec
114     {
115 sf-exg 1.28 typedef estl::size_type size_type;
116 root 1.9
117     typedef T value_type;
118     typedef T *iterator;
119 root 1.3 typedef const T *const_iterator;
120 root 1.9 typedef T *pointer;
121     typedef const T *const_pointer;
122     typedef T &reference;
123     typedef const T &const_reference;
124     // missing: allocator_type
125     // missing: reverse iterator
126    
127     private:
128     size_type sze, res;
129     T *buf;
130 sf-exg 1.1
131 root 1.9 // we shamelessly optimise for "simple" types. everything
132     // "not simple enough" will use the slow path.
133 root 1.8 static bool is_simple_enough ()
134     {
135 root 1.21 #if ECB_CPP11
136 root 1.8 return std::is_trivially_assignable<T, T>::value
137 sf-exg 1.26 && std::is_trivially_constructible<T>::value
138 root 1.8 && std::is_trivially_copyable<T>::value
139     && std::is_trivially_destructible<T>::value;
140 sf-exg 1.27 #elif ECB_GCC_VERSION(4,4) || ECB_CLANG_VERSION(2,8)
141 root 1.8 return __has_trivial_assign (T)
142     && __has_trivial_constructor (T)
143     && __has_trivial_copy (T)
144     && __has_trivial_destructor (T);
145     #else
146     return 0;
147     #endif
148     }
149    
150 root 1.9 static void construct (iterator a, size_type n = 1)
151 root 1.3 {
152 root 1.9 if (!is_simple_enough ())
153     while (n--)
154 sf-exg 1.17 new (a++) T ();
155 root 1.3 }
156    
157 root 1.9 static void destruct (iterator a, size_type n = 1)
158 root 1.3 {
159 root 1.8 if (!is_simple_enough ())
160 root 1.9 while (n--)
161     (*a++).~T ();
162 root 1.3 }
163    
164 root 1.11 template<class I>
165     static void cop_new (iterator a, I b) { new (a) T (*b); }
166     template<class I>
167     static void cop_set (iterator a, I b) { *a = *b ; }
168    
169 root 1.14 // MUST copy forwards
170 root 1.11 template<class I>
171 root 1.15 static void copy (iterator dst, I src, size_type n, void (*op)(iterator, I))
172 root 1.11 {
173 root 1.13 while (n--)
174     op (dst++, src++);
175 root 1.11 }
176    
177 root 1.15 static void copy (iterator dst, iterator src, size_type n, void (*op)(iterator, iterator))
178 root 1.8 {
179     if (is_simple_enough ())
180     memcpy (dst, src, sizeof (T) * n);
181     else
182 root 1.11 copy<iterator> (dst, src, n, op);
183 root 1.9 }
184    
185     static T *alloc (size_type n) ecb_cold
186     {
187     return (T *)::operator new ((size_t) (sizeof (T) * n));
188     }
189    
190     void dealloc () ecb_cold
191     {
192     destruct (buf, sze);
193     ::operator delete (buf);
194     }
195    
196     size_type good_size (size_type n) ecb_cold
197     {
198     return n ? 2UL << ecb_ld32 (n) : 5;
199 root 1.8 }
200    
201     void ins (iterator where, size_type n)
202 root 1.3 {
203 root 1.9 size_type pos = where - begin ();
204    
205     if (ecb_expect_false (sze + n > res))
206 root 1.3 {
207 root 1.9 res = good_size (sze + n);
208 root 1.3
209 root 1.9 T *nbuf = alloc (res);
210     copy (nbuf, buf, sze, cop_new);
211     dealloc ();
212     buf = nbuf;
213 root 1.3 }
214 root 1.9
215     construct (buf + sze, n);
216 root 1.14
217     iterator src = buf + pos;
218     if (is_simple_enough ())
219 sf-exg 1.23 memmove (src + n, src, sizeof (T) * (sze - pos));
220 root 1.14 else
221 sf-exg 1.23 for (size_type i = sze - pos; i--; )
222 sf-exg 1.17 cop_set (src + n + i, src + i);
223 sf-exg 1.23
224     sze += n;
225 root 1.3 }
226 sf-exg 1.1
227     public:
228 root 1.9 size_type capacity () const { return res; }
229     size_type size () const { return sze; }
230     bool empty () const { return size () == 0; }
231    
232 root 1.11 size_t max_size () const
233     {
234     return (~(size_type)0) >> 1;
235     }
236    
237 root 1.9 const_iterator begin () const { return &buf [ 0]; }
238     iterator begin () { return &buf [ 0]; }
239     const_iterator end () const { return &buf [sze ]; }
240     iterator end () { return &buf [sze ]; }
241     const_reference front () const { return buf [ 0]; }
242     reference front () { return buf [ 0]; }
243     const_reference back () const { return buf [sze - 1]; }
244     reference back () { return buf [sze - 1]; }
245    
246 root 1.3 void reserve (size_type sz)
247     {
248 root 1.9 if (ecb_expect_true (sz <= res))
249     return;
250 root 1.3
251 root 1.9 sz = good_size (sz);
252     T *nbuf = alloc (sz);
253 root 1.3
254 root 1.15 copy (nbuf, begin (), sze, cop_new);
255 root 1.9 dealloc ();
256    
257     buf = nbuf;
258     res = sz;
259 root 1.3 }
260    
261 root 1.7 void resize (size_type sz)
262     {
263     reserve (sz);
264 root 1.8
265     if (is_simple_enough ())
266 root 1.9 sze = sz;
267 root 1.8 else
268     {
269 root 1.9 while (sze < sz) construct (buf + sze++);
270     while (sze > sz) destruct (buf + --sze);
271 root 1.8 }
272 root 1.7 }
273    
274 root 1.3 simplevec ()
275 root 1.9 : sze(0), res(0), buf(0)
276 root 1.3 {
277     }
278    
279 root 1.9 simplevec (size_type n, const T &t = T ())
280 root 1.3 {
281 root 1.11 sze = res = n;
282     buf = alloc (sze);
283    
284     while (n--)
285     new (buf + n) T (t);
286 root 1.3 }
287    
288 sf-exg 1.25 simplevec (const_iterator first, const_iterator last)
289 root 1.3 {
290 root 1.11 sze = res = last - first;
291     buf = alloc (sze);
292 root 1.15 copy (buf, first, sze, cop_new);
293 root 1.3 }
294    
295     simplevec (const simplevec<T> &v)
296 root 1.9 : sze(0), res(0), buf(0)
297 root 1.3 {
298 root 1.11 sze = res = v.size ();
299     buf = alloc (sze);
300 root 1.15 copy (buf, v.begin (), sze, cop_new);
301 root 1.3 }
302    
303     ~simplevec ()
304     {
305 root 1.8 dealloc ();
306 root 1.3 }
307    
308 root 1.9 void swap (simplevec<T> &t)
309 root 1.3 {
310 root 1.9 ::swap (sze, t.sze);
311     ::swap (res, t.res);
312     ::swap (buf, t.buf);
313 root 1.3 }
314    
315     void clear ()
316     {
317 root 1.9 destruct (buf, sze);
318     sze = 0;
319 root 1.3 }
320    
321     void push_back (const T &t)
322     {
323 root 1.9 reserve (sze + 1);
324     new (buf + sze++) T (t);
325 root 1.3 }
326    
327     void pop_back ()
328     {
329 root 1.9 destruct (buf + --sze);
330 root 1.3 }
331    
332 root 1.11 const_reference operator [](size_type idx) const { return buf[idx]; }
333     reference operator [](size_type idx) { return buf[idx]; }
334    
335     const_reference at (size_type idx) const { return buf [idx]; }
336     reference at (size_type idx) { return buf [idx]; }
337    
338 sf-exg 1.25 void assign (const_iterator first, const_iterator last)
339 root 1.11 {
340 sf-exg 1.25 simplevec<T> v (first, last);
341     swap (v);
342 root 1.11 }
343    
344     void assign (size_type n, const T &t)
345     {
346 sf-exg 1.25 simplevec<T> v (n, t);
347     swap (v);
348 root 1.11 }
349    
350     simplevec<T> &operator= (const simplevec<T> &v)
351     {
352     assign (v.begin (), v.end ());
353     return *this;
354     }
355 root 1.3
356     iterator insert (iterator pos, const T &t)
357     {
358 root 1.8 size_type at = pos - begin ();
359 root 1.10
360 root 1.8 ins (pos, 1);
361 root 1.10 buf [at] = t;
362    
363     return buf + at;
364 root 1.3 }
365    
366 sf-exg 1.25 iterator insert (iterator pos, const_iterator first, const_iterator last)
367 root 1.3 {
368 root 1.8 size_type n = last - first;
369     size_type at = pos - begin ();
370 root 1.3
371 root 1.9 ins (pos, n);
372 root 1.10 copy (buf + at, first, n, cop_set);
373 root 1.3
374 root 1.10 return buf + at;
375 root 1.3 }
376    
377     iterator insert (iterator pos, size_type n, const T &t)
378     {
379 root 1.8 size_type at = pos - begin ();
380 root 1.3
381 root 1.9 ins (pos, n);
382    
383 root 1.10 for (iterator i = buf + at; n--; )
384     *i++ = t;
385 root 1.3
386 root 1.10 return buf + at;
387 root 1.3 }
388    
389 sf-exg 1.19 iterator erase (iterator first, iterator last)
390 root 1.3 {
391 root 1.20 size_type n = last - first;
392     size_type c = end () - last;
393 root 1.8
394 root 1.13 if (is_simple_enough ())
395 root 1.20 memmove (first, last, sizeof (T) * c);
396 root 1.13 else
397 sf-exg 1.22 copy (first, last, c, cop_set);
398 root 1.13
399 root 1.9 sze -= n;
400     destruct (buf + sze, n);
401 sf-exg 1.19
402     return first;
403 root 1.3 }
404    
405 sf-exg 1.19 iterator erase (iterator pos)
406 root 1.3 {
407     if (pos != end ())
408 root 1.8 erase (pos, pos + 1);
409 sf-exg 1.19
410     return pos;
411 root 1.3 }
412 sf-exg 1.1 };
413    
414     template<class T>
415 root 1.3 bool operator ==(const simplevec<T> &v1, const simplevec<T> &v2)
416 sf-exg 1.1 {
417 root 1.3 if (v1.size () != v2.size ()) return false;
418    
419     return !v1.size () || !memcmp (&v1[0], &v2[0], v1.size () * sizeof (T));
420 sf-exg 1.1 }
421    
422     template<class T>
423 root 1.3 bool operator <(const simplevec<T> &v1, const simplevec<T> &v2)
424 sf-exg 1.1 {
425 root 1.3 unsigned long minlast = min (v1.size (), v2.size ());
426    
427     for (unsigned long i = 0; i < minlast; ++i)
428     {
429     if (v1[i] < v2[i]) return true;
430     if (v2[i] < v1[i]) return false;
431 sf-exg 1.1 }
432 root 1.3 return v1.size () < v2.size ();
433 sf-exg 1.1 }
434    
435     template<typename T>
436     struct vector : simplevec<T>
437     {
438     };
439 sf-exg 1.2
440     #endif
441 root 1.3