]> cygwin.com Git - cygwin-apps/setup.git/blame - list.h
2002-07-02 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / list.h
CommitLineData
bb849dbd
RC
1/*
2 * Copyright (c) 2001, Robert Collins.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16#ifndef _LIST_H_
17#define _LIST_H_
18
cbfc4215 19#include "stdlib.h"
bb849dbd
RC
20#include "sys/types.h"
21
aa1e3b4d
RC
22#include "LogSingleton.h"
23
bb849dbd
RC
24/* Creates a list/array of type T (must have a field key of type U),
25 * with index type U and U comparison Ucmp.
26 */
27template < class T, class U, int
28Ucmp (U, U) >
29class list
30{
31 T **pointerblock;
32 size_t _number;
33 size_t _space;
34
35public:
36list ():pointerblock (0), _number (0), _space (0)
37 {
38 };
39 // ~list () ...
40 /* get an element if it exists */
7e8fc33c 41 T *getbykey (const U);
bb849dbd
RC
42 /* add an element if it does not exist and return a reference */
43 T & registerbykey (U);
44 /* add an element if one with the same key does not exist */
45 T & registerbyobject (T &);
de6a1a64 46 /* remove by index */
cc7493c3 47 T *removebyindex (size_t);
cbfc4215 48 size_t number () const
bb849dbd
RC
49 {
50 return _number;
51 };
52 /* get by offset - not thread safe - starts at 1 */
cbfc4215 53 T *operator [] (size_t n) const
bb849dbd
RC
54 {
55 return n && n <= _number ? pointerblock[n - 1] : 0;
56 };
57 /* TODO: delete */
cc7493c3
RC
58private:
59 // ensure there is enough array space.
60 void checksize (void);
61 // perform an insertion.
62 void insert (size_t, T *);
aa1e3b4d
RC
63 // find the index for a given element.
64 // if the element is not present, return the index of an element beside
65 // where it should be inserted. This may be above or below the actual
66 // insertion point
67 size_t findindex (const U) const;
bb849dbd
RC
68};
69
70template < class T, class U, int
71Ucmp (U, U) >
7e8fc33c 72T * list < T, U, Ucmp >::getbykey (const U key)
bb849dbd 73{
aa1e3b4d
RC
74 /* trivial corner case */
75 if (_number == 0)
76 return 0;
77 size_t index = findindex (key);
78 if (index < _number && Ucmp (pointerblock[index]->key, key) == 0)
79 return pointerblock[index];
bb849dbd
RC
80 return 0;
81}
82
83
84template < class T, class U, int
85Ucmp (U, U) >
86T & list < T, U, Ucmp >::registerbykey (U key)
87{
88 T *tempT = getbykey (key);
89 if (!tempT)
90 {
bb849dbd 91 tempT = new T (key);
aa1e3b4d
RC
92
93 size_t index = _number ? findindex (tempT->key) : 0;
94 insert (index, tempT);
bb849dbd
RC
95 }
96 return *tempT;
97}
98
99/* TODO: factor both insertion routines into one */
100template < class T, class U, int
101Ucmp (U, U) >
102T & list < T, U, Ucmp >::registerbyobject (T & newobj)
103{
104 T *tempT = getbykey (newobj.key);
105 if (!tempT)
106 {
bb849dbd 107 tempT = &newobj;
aa1e3b4d
RC
108 size_t index = _number ? findindex (tempT->key) : 0;
109 insert (index, tempT);
bb849dbd
RC
110 }
111 return *tempT;
112}
113
cc7493c3
RC
114template < class T, class U, int
115Ucmp (U, U) >
de6a1a64
RC
116T * list < T, U, Ucmp >::removebyindex (size_t index)
117{
118 if (index && index <= _number)
119 {
cc7493c3 120 T *rv = pointerblock[index - 1];
de6a1a64 121 /* remove from index - 1 */
cc7493c3
RC
122 for (size_t i = index; i < _number; ++i)
123 pointerblock[i - 1] = pointerblock[i];
124 --_number;
de6a1a64
RC
125 return rv;
126 }
127 return 0;
128}
129
cc7493c3
RC
130template < class T, class U, int
131 Ucmp (U, U) > void
132 list < T, U, Ucmp >::checksize ()
133{
134 if (_number == _space)
135 {
136 T **newptr = new (T *)[_space + 20];
137 if (!newptr)
138 {
139 //die - todo enable exceptions
140 exit (100);
141 }
142 for (size_t i = 0; i < _number; ++i)
143 newptr[i] = pointerblock[i];
144 delete[]pointerblock;
145 pointerblock = newptr;
146 /* TODO: Parameterise this too */
147 _space += 20;
148 }
149}
150template < class T, class U, int
151 Ucmp (U, U) > void
152 list < T, U, Ucmp >::insert (size_t where, T * someT)
153{
154 // doesn't change where
155 checksize ();
156 /* insert at where */
157 for (size_t i = _number; where < i; --i)
158 pointerblock[i] = pointerblock[i - 1];
159 pointerblock[where] = someT;
160 ++_number;
161}
162
163
aa1e3b4d
RC
164/* Precondition: _number != 0 */
165template < class T, class U, int
166Ucmp (U, U) >
167size_t list < T, U, Ucmp >::findindex (const U key) const
168{
169 for (size_t n = _number - 1; n < _number; --n)
170 {
171 int direction = Ucmp (key, pointerblock[n]->key);
172 if (!direction)
173 return n;
174 else if (direction > 0)
175 return n+1;
176 }
177 return 0;
178}
179
bb849dbd 180#endif /* _LIST_H_ */
This page took 0.039864 seconds and 5 git commands to generate.