source: trunk/src/emx/include/Attic/cpp/gen/CHMap.ccP@ 18

Last change on this file since 18 was 18, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 3.7 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2/*
3Copyright (C) 1988 Free Software Foundation
4 written by Doug Lea ([email protected])
5
6This file is part of the GNU C++ Library. This library is free
7software; you can redistribute it and/or modify it under the terms of
8the GNU Library General Public License as published by the Free
9Software Foundation; either version 2 of the License, or (at your
10option) any later version. This library is distributed in the hope
11that it will be useful, but WITHOUT ANY WARRANTY; without even the
12implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13PURPOSE. See the GNU Library General Public License for more details.
14You should have received a copy of the GNU Library General Public
15License along with this library; if not, write to the Free Software
16Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19#ifdef __GNUG__
20#pragma implementation
21#endif
22#include "<T>.<C>.CHMap.h"
23
24// The nodes are linked together serially via a version
25// of a trick used in some vtables: odd pointers are
26// actually links to the next table entry.
27// Not terrible, but not wonderful either
28
29static inline int goodCHptr(<T><C>CHNode* t)
30{
31 return ((((unsigned)t) & 1) == 0);
32}
33
34static inline <T><C>CHNode* index_to_CHptr(int i)
35{
36 return (<T><C>CHNode*)((i << 1) + 1);
37}
38
39static inline int CHptr_to_index(<T><C>CHNode* t)
40{
41 return ( ((unsigned) t) >> 1);
42}
43
44<T><C>CHMap::<T><C>CHMap(<C&> dflt, unsigned int sz)
45 :<T><C>Map(dflt)
46{
47 tab = (<T><C>CHNode**)(new <T><C>CHNodePtr[size = sz]);
48 for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
49 count = 0;
50}
51
52<T><C>CHMap::<T><C>CHMap(<T><C>CHMap& a) :<T><C>Map(a.def)
53{
54 tab = (<T><C>CHNode**)(new <T><C>CHNodePtr[size = a.size]);
55 for (unsigned int i = 0; i < size; ++i) tab[i] = index_to_CHptr(i+1);
56 count = 0;
57 for (Pix p = a.first(); p; a.next(p)) (*this)[a.key(p)] = a.contents(p);
58}
59
60
61Pix <T><C>CHMap::seek(<T&> key)
62{
63 unsigned int h = <T>HASH(key) % size;
64
65 for (<T><C>CHNode* t = tab[h]; goodCHptr(t); t = t->tl)
66 if (<T>EQ(key, t->hd))
67 return Pix(t);
68
69 return 0;
70}
71
72
73<C>& <T><C>CHMap::operator [](<T&> item)
74{
75 unsigned int h = <T>HASH(item) % size;
76 <T><C>CHNode* t;
77
78 for (t = tab[h]; goodCHptr(t); t = t->tl)
79 if (<T>EQ(item, t->hd))
80 return t->cont;
81
82 t = new <T><C>CHNode(item, def, tab[h]);
83 tab[h] = t;
84 ++count;
85 return t->cont;
86}
87
88
89void <T><C>CHMap::del(<T&> key)
90{
91 unsigned int h = <T>HASH(key) % size;
92
93 <T><C>CHNode* t = tab[h];
94 <T><C>CHNode* trail = t;
95 while (goodCHptr(t))
96 {
97 if (<T>EQ(key, t->hd))
98 {
99 if (trail == t)
100 tab[h] = t->tl;
101 else
102 trail->tl = t->tl;
103 delete t;
104 --count;
105 return;
106 }
107 trail = t;
108 t = t->tl;
109 }
110}
111
112
113void <T><C>CHMap::clear()
114{
115 for (unsigned int i = 0; i < size; ++i)
116 {
117 <T><C>CHNode* p = tab[i];
118 tab[i] = index_to_CHptr(i+1);
119 while (goodCHptr(p))
120 {
121 <T><C>CHNode* nxt = p->tl;
122 delete(p);
123 p = nxt;
124 }
125 }
126 count = 0;
127}
128
129Pix <T><C>CHMap::first()
130{
131 for (unsigned int i = 0; i < size; ++i) if (goodCHptr(tab[i])) return Pix(tab[i]);
132 return 0;
133}
134
135void <T><C>CHMap::next(Pix& p)
136{
137 <T><C>CHNode* t = ((<T><C>CHNode*)p)->tl;
138 if (goodCHptr(t))
139 p = Pix(t);
140 else
141 {
142 for (unsigned int i = CHptr_to_index(t); i < size; ++i)
143 {
144 if (goodCHptr(tab[i]))
145 {
146 p = Pix(tab[i]);
147 return;
148 }
149 }
150 p = 0;
151 }
152}
153
154
155int <T><C>CHMap::OK()
156{
157 int v = tab != 0;
158 int n = 0;
159 for (unsigned int i = 0; i < size; ++i)
160 {
161 <T><C>CHNode* p;
162 for (p = tab[i]; goodCHptr(p); p = p->tl) ++n;
163 v &= CHptr_to_index(p) == i + 1;
164 }
165 v &= count == n;
166 if (!v) error("invariant failure");
167 return v;
168}
Note: See TracBrowser for help on using the repository browser.