]> git.lyx.org Git - lyx.git/blob - development/Win32/vld/src/map.h
Add support for glue length in parskip (#12867)
[lyx.git] / development / Win32 / vld / src / map.h
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 //  Visual Leak Detector - Lightweight STL-like Map Template
4 //  Copyright (c) 2006 Dan Moulding
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License, or (at your option) any later version.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 //
20 //  See COPYING.txt for the full terms of the GNU Lesser General Public License.
21 //
22 ////////////////////////////////////////////////////////////////////////////////
23
24 #pragma once
25
26 #ifndef VLDBUILD
27 #error \
28 "This header should only be included by Visual Leak Detector when building it from source. \
29 Applications should never include this header."
30 #endif
31
32 #include "tree.h" // Provides access to the Tree template class.
33
34 ////////////////////////////////////////////////////////////////////////////////
35 //
36 //  The Pair Template Class
37 //
38 //  This is a lightweight STL-like pair template, for use with the lightweight
39 //  Map class template.
40 //
41 //  Note that while this is a STL-like class, it is not a full STL-compliant
42 //  implementation of the STL pair utility class. It provides just the bare
43 //  minimum functionality required by the Visual Leak Detector Map template
44 //  class below.
45 //
46 template <typename Tf, typename Ts>
47 class Pair {
48 public:
49     // Constructor
50     Pair ()
51     {
52         first = Tf();
53         second = Ts();
54     }
55
56     // Constructor with initializers.
57     Pair (const Tf &f, const Ts &s)
58     {
59         first = f;
60         second = s;
61     }
62
63     // Less-than operator - Compares this Pair with another Pair to determine
64     //   if this Pair is less than the other Pair. The Pair with the smallest
65     //   "first" value is the lesser Pair.
66     //
67     //  - other (IN): The other pair to compare against.
68     //
69     //  Return Value:
70     //
71     //    Returns true if this Pair is less than the other Pair. Otherwise
72     //    returns false.
73     //
74     BOOL operator < (const Pair &other) const
75     {
76         return (first < other.first);
77     }
78
79     // Public data.
80     Tf first;  // The first value of the pair.
81     Ts second; // The second value of the pair.
82 };
83
84 ////////////////////////////////////////////////////////////////////////////////
85 //
86 //  The Map Template Class
87 //
88 //  This is a lightweidht STL-like map template. It makes use of the Tree class
89 //  template to enable fast insert, find, and erase operations.
90 //
91 //  Note that while this is a STL-like class, it is not a full STL-compliant
92 //  implementation of the STL map container. It contains just the bare minimum
93 //  functionality required by Visual Leak Detector. Because of its "lightweight"
94 //  nature, this map class has a noticeable performance advantage over some
95 //  other standard STL map implementations.
96 //
97 template <typename Tk, typename Tv>
98 class Map {
99 public:
100     class Iterator {
101     public:
102         // Constructor
103         Iterator ()
104         {
105             // Plainly constructed iterators don't reference anything.
106             m_node = NULL;
107             m_tree = NULL;
108         }
109
110         // operator != - Inequality operator for Map Iterators. Two Map
111         //   Iterators are considered equal if and only if they both reference
112         //   the same key/value pair in the same Map.
113         //
114         //  - other (IN): The other Map Iterator to compare against.
115         //
116         //  Return Value:
117         //
118         //    Returns true if the specified Map Iterator is not equal to this
119         //    Map Iterator; otherwise, returns false.
120         //
121         BOOL operator != (const Iterator &other) const
122         {
123             return ((m_tree != other.m_tree) || (m_node != other.m_node));
124         }
125
126         // operator * - Dereference operator for Map Iterators.
127         //
128         //  Note:  The reference returned by this function is "const", so the
129         //    value referenced by the Iterator may not be modified through the
130         //    Iterator. This is a departure from STL iterator behavior.
131         //
132         //    Also, dereferencing an Iterator which does not reference a valid
133         //    value in the Map is undefined and will almost certainly cause a
134         //    crash.
135         //
136         //  Return Value:
137         //
138         //    Returns a const reference to the key/value pair in the Map
139         //    referenced by the Iterator.
140         //
141         const Pair<Tk, Tv>& operator * () const
142         {
143             return m_node->key;
144         }
145
146         // operator ++ - Prefix increment operator for Map Iterators. Causes the
147         //   Iterator to reference the in-oder successor of the key/value pair
148         //   currently referenced by the Iterator. If the Iterator is currently
149         //   referencing the largest key/value pair in the Map, then the
150         //   resulting Iterator will reference the Map's end (the NULL pair).
151         //
152         //  Note: Incrementing an Iterator which does not reference a valid
153         //    key/value pair in the Map is undefined and will almost certainly
154         //    cause a crash.
155         //
156         //  Return Value:
157         //
158         //    Returns the Iterator after it has been incremented.
159         // 
160         Iterator& operator ++ (int)
161         {
162             m_node = m_tree->next(m_node);
163             return *this;
164         }
165
166         // operator ++ - Postfix increment operator for Map Iterators. Causes
167         //   the Iterator to reference the in-order successor of the key/value
168         //   pair currently referenced by the Iterator. If the Iterator is
169         //   currently referencing the largest key/value pair in the Map, then
170         //   the resulting Iterator will reference the Map's end (the NULL
171         //   pair).
172         //
173         //  Note: Incrementing an Iterator which does not reference a valid
174         //    key/value pair in the Map is undefined and will almost certainly
175         //    cause a crash.
176         //
177         //  Return Value:
178         //
179         //    Returns the Iterator before it has been incremented.
180         // 
181         Iterator operator ++ ()
182         {
183             typename Tree<Pair<Tk, Tv> >::node_t *cur = m_node;
184
185             m_node = m_tree->next(m_node);
186             return Iterator(m_tree, cur);
187         }
188
189         // operator - - Subtraction operator for Map Iterators. Causes the
190         //   the Iterator to reference a key/value pair that is an in-order
191         //   predecessor of the currently refereced key/value pair.
192         //
193         //  - num (IN): Number indicating the number of preceding key/value
194         //      pairs to decrement the iterator.
195         //
196         //  Return Value:
197         //
198         //    Returns an Iterator referencing the key/value pair that precedes
199         //    the original Iterator by "num" pairs.
200         //
201         Iterator operator - (SIZE_T num) const
202         {
203             SIZE_T                                count;
204             typename Tree<Pair<Tk, Tv> >::node_t *cur = m_node;
205
206             cur = m_tree->prev(m_node);
207             for (count = 0; count < num; count++)  {
208                 cur = m_tree->prev(m_node);
209                 if (cur == NULL) {
210                     return Iterator(m_tree, NULL);
211                 }
212             }
213             return Iterator(m_tree, cur);
214         }
215
216         // operator == - Equality operator for Map Iterators. Map Iterators are
217         //   considered equal if and only if they both refernce the same
218         //   key/value pair in the same Map.
219         //
220         //  - other (IN): The other Map Iterator to compare against.
221         //
222         //  Return Value:
223         //
224         //    Returns true if the specified Map Iterator is equal to this Map
225         //    Iterator; otherwise returns false.
226         //
227         BOOL operator == (const Iterator &other) const
228         {
229             return ((m_tree == other.m_tree) && (m_node == other.m_node));
230         }
231
232     private:
233         // Private constructor. Only the Map class itself may use this
234         //   constructor. It is used for constructing Iterators which reference
235         //   specific nodes in the internal tree's structure.
236         Iterator (const Tree<Pair<Tk, Tv> > *tree, typename Tree<Pair<Tk, Tv> >::node_t *node)
237         {
238             m_node = node;
239             m_tree = tree;
240         }
241
242         typename Tree<Pair<Tk, Tv> >::node_t *m_node; // Pointer to the node referenced by the Map Iterator.
243         const Tree<Pair<Tk, Tv> >            *m_tree; // Pointer to the tree containing the referenced node.
244
245         // The Map class is a friend of Map Iterators.
246         friend class Map<Tk, Tv>;
247     };
248
249     // begin - Obtains an Iterator referencing the beginning of the Map (i.e.
250     //   the lowest key/value pair currently stored in the Map).
251     //
252     //  Return Value:
253     //
254     //    Returns an Iterator referencing the first key/value pair in the Map.
255     //    If no key/value pairs are currenly stored in the map, returns the
256     //    "NULL" Iterator.
257     //
258     Iterator begin () const
259     {
260         return Iterator(&m_tree, m_tree.begin());
261     }
262
263     // end - Obtains an Iterator referencing the end of the Map. The end of
264     //   the map does not reference an actual key/value pair. Instead it
265     //   represents a "null" key/value pair which signifies the end (i.e. just
266     //   beyond largest key/value pair currently stored in the Map). Also
267     //   known as the "NULL" Iterator.
268     //
269     //  Return Value:
270     //
271     //    Returns the "NULL" Iterator, signifying the end of the Map.
272     //
273     Iterator end () const
274     {
275         return Iterator(&m_tree, NULL);
276     }
277
278     // erase - Erases a key/value pair from the map.
279     //
280     //  - it (IN): Iterator referencing the key/value pair to be erased from
281     //      the map.
282     //
283     //  Return Value:
284     //
285     //    None.
286     //
287     VOID erase (Iterator& it)
288     {
289         m_tree.erase(it.m_node);
290     }
291
292     // erase - Erases a key/value pair from the map.
293     //
294     //  - key (IN): The key corresponding to the key/value pair to be erased
295     //      from the map.
296     //
297     //  Return Value:
298     //
299     //    None.
300     //
301     VOID erase (const Tk &key)
302     {
303         m_tree.erase(Pair<Tk, Tv>(key, Tv()));
304     }
305
306     // find - Finds a key/value pair in the map.
307     //
308     //  - key (IN): The key corresponding to the key/value pair to be found.
309     //
310     //  Return Value:
311     //
312     //    Returns an Iterator referencing the found key/value pair. If no
313     //    key/value pair with the specified key could be found, then the "NULL"
314     //    Iterator is returned.
315     //
316     Iterator find (const Tk &key) const
317     {
318         return Iterator(&m_tree, m_tree.find(Pair<Tk, Tv>(key, Tv())));
319     }
320
321     // insert - Inserts a key/value pair into the map.
322     //
323     //  - key (IN): The key of the key/value pair to be inserted.
324     //
325     //  - data (IN): The value of the key/value pair to be inserted.
326     //
327     //  Return Value:
328     //
329     //    Returns an Iterator referencing the resulting key/value pair after
330     //    if has been inserted into the map.
331     //
332     Iterator insert (const Tk &key, const Tv &data)
333     {
334         return Iterator(&m_tree, m_tree.insert(Pair<Tk, Tv>(key, data)));
335     }
336
337     // reserve - Sets the reserve size of the map. The reserve size is the
338     //   number of key/value pairs for which space should be pre-allocated
339     //   to avoid frequent heap hits when inserting new key/value pairs into
340     //   the map.
341     //
342     //  - count (IN): The number of key/value pairs for which to reserve space
343     //      in advance.
344     //
345     //  Return Value:
346     //
347     //    Returns the reserve size previously in use by the map.
348     //
349     size_t reserve (size_t count)
350     {
351         return m_tree.reserve(count);
352     }
353
354 private:
355     // Private data
356     Tree<Pair<Tk, Tv> > m_tree; // The key/value pairs are actually stored in a tree.
357 };