- Added maximization features, with corresponding plugins. Added painting feature...
[mldemos:mldemos.git] / _3rdParty / dlib / binary_search_tree / binary_search_tree_kernel_abstract.h
1 // Copyright (C) 2003  Davis E. King (davis@dlib.net)\r
2 // License: Boost Software License   See LICENSE.txt for the full license.\r
3 #undef DLIB_BINARY_SEARCH_TREE_KERNEl_ABSTRACT_\r
4 #ifdef DLIB_BINARY_SEARCH_TREE_KERNEl_ABSTRACT_\r
5 \r
6 #include "../interfaces/map_pair.h"\r
7 #include "../interfaces/enumerable.h"\r
8 #include "../interfaces/remover.h"\r
9 #include "../serialize.h"\r
10 #include "../memory_manager/memory_manager_kernel_abstract.h"\r
11 #include <functional>\r
12 \r
13 namespace dlib \r
14 {\r
15 \r
16     template <\r
17         typename domain,\r
18         typename range,\r
19         typename mem_manager = memory_manager<char>::kernel_1a,\r
20         typename compare = std::less<domain>\r
21         >\r
22     class binary_search_tree : public enumerable<map_pair<domain,range> >, \r
23                                public asc_pair_remover<domain,range,compare>\r
24     {\r
25 \r
26         /*!\r
27             REQUIREMENTS ON domain\r
28                 domain must be comparable by compare where compare is a functor compatible with std::less and\r
29                 domain is swappable by a global swap() and             \r
30                 domain must have a default constructor\r
31 \r
32             REQUIREMENTS ON range\r
33                 range is swappable by a global swap() and\r
34                 range must have a default constructor\r
35 \r
36             REQUIREMENTS ON mem_manager\r
37                 must be an implementation of memory_manager/memory_manager_kernel_abstract.h or\r
38                 must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or\r
39                 must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h \r
40                 mem_manager::type can be set to anything.\r
41 \r
42 \r
43             POINTERS AND REFERENCES TO INTERNAL DATA\r
44                 swap(), count(), height(),  and operator[] functions \r
45                 do not invalidate pointers or references to internal data.\r
46 \r
47                 position_enumerator() invalidates pointers or references to \r
48                 data returned by element() and only by element() (i.e. pointers and\r
49                 references returned by operator[] are still valid).\r
50 \r
51                 All other functions have no such guarantees.\r
52 \r
53             INITIAL VALUE\r
54                 size() == 0\r
55                 height() == 0\r
56 \r
57             ENUMERATION ORDER\r
58                 The enumerator will iterate over the domain (and each associated\r
59                 range element) elements in ascending order according to the compare functor.  \r
60                 (i.e. the elements are enumerated in sorted order)              \r
61 \r
62             WHAT THIS OBJECT REPRESENTS\r
63                 this object represents a data dictionary that is built on top of some \r
64                 kind of binary search tree.  It maps objects of type domain to objects\r
65                 of type range.  \r
66 \r
67                 Also note that unless specified otherwise, no member functions\r
68                 of this object throw exceptions.\r
69                     \r
70                 NOTE:\r
71                     definition of equivalent:\r
72                     a is equivalent to b if\r
73                     a < b == false and\r
74                     b < a == false\r
75         !*/\r
76 \r
77 \r
78     public:\r
79 \r
80         typedef domain domain_type;\r
81         typedef range range_type;\r
82         typedef compare compare_type;\r
83         typedef mem_manager mem_manager_type;\r
84 \r
85         binary_search_tree(\r
86         );\r
87         /*!\r
88             ensures \r
89                 - #*this is properly initialized\r
90             throws\r
91                 - std::bad_alloc or any exception thrown by domain's or range's \r
92                   constructor.\r
93         !*/\r
94 \r
95         virtual ~binary_search_tree(\r
96         ); \r
97         /*!\r
98             ensures\r
99                 - all memory associated with *this has been released\r
100         !*/\r
101 \r
102         void clear(\r
103         );\r
104         /*!\r
105             ensures\r
106                 - #*this has its initial value\r
107             throws\r
108                 - std::bad_alloc or any exception thrown by domain's or range's \r
109                   constructor.\r
110                     if this exception is thrown then *this is unusable \r
111                     until clear() is called and succeeds\r
112         !*/\r
113 \r
114         short height (\r
115         ) const;\r
116         /*!\r
117             ensures\r
118                 - returns the number of elements in the longest path from the root \r
119                   of the tree to a leaf\r
120         !*/\r
121 \r
122         unsigned long count (\r
123             const domain& d\r
124         ) const;\r
125         /*!\r
126             ensures\r
127                 - returns the number of elements in the domain of *this that are \r
128                   equivalent to d\r
129         !*/ \r
130 \r
131         void add (\r
132             domain& d,\r
133             range& r\r
134         );\r
135         /*!\r
136             requires    \r
137                 - &d != &r (i.e. d and r cannot be the same variable)\r
138             ensures             \r
139                 - adds a mapping between d and r to *this\r
140                 - if (count(d) == 0) then\r
141                     - #*(*this)[d] == r\r
142                 - else\r
143                     - #(*this)[d] != 0\r
144                 - #d and #r have initial values for their types\r
145                 - #count(d) == count(d) + 1\r
146                 - #at_start() == true\r
147                 - #size() == size() + 1\r
148             throws  \r
149                 - std::bad_alloc or any exception thrown by domain's or range's \r
150                   constructor.\r
151                     if add() throws then it has no effect\r
152         !*/\r
153 \r
154         void remove (\r
155             const domain& d,\r
156             domain& d_copy,\r
157             range& r\r
158         );\r
159         /*!\r
160             requires\r
161                 - (*this)[d] != 0 \r
162                 - &d != &r (i.e. d and r cannot be the same variable) \r
163                 - &d != &d_copy (i.e. d and d_copy cannot be the same variable) \r
164                 - &r != &d_copy (i.e. r and d_copy cannot be the same variable) \r
165             ensures\r
166                 - some element in the domain of *this that is equivalent to d has\r
167                   been removed and swapped into #d_copy.  Additionally, its \r
168                   associated range element has been removed and swapped into #r.\r
169                 - #count(d) == count(d) - 1\r
170                 - #size() == size() - 1\r
171                 - #at_start() == true  \r
172         !*/\r
173 \r
174         void destroy (\r
175             const domain& d\r
176         );\r
177         /*!\r
178             requires\r
179                 - (*this)[d] != 0 \r
180             ensures\r
181                 - an element in the domain of *this equivalent to d has been removed.  \r
182                   The element in the range of *this associated with d has also been \r
183                   removed.\r
184                 - #count(d) == count(d) - 1\r
185                 - #size() == size() - 1\r
186                 - #at_start() == true  \r
187         !*/\r
188 \r
189         void remove_last_in_order (\r
190             domain& d,\r
191             range& r\r
192         );\r
193         /*!\r
194             requires\r
195                 - size() > 0\r
196             ensures\r
197                 - the last/biggest (according to the compare functor) element in the domain of *this has\r
198                   been removed and swapped into #d.  The element in the range of *this\r
199                   associated with #d has also been removed and swapped into #r.\r
200                 - #count(#d) == count(#d) - 1\r
201                 - #size() == size() - 1\r
202                 - #at_start() == true\r
203         !*/\r
204 \r
205         void remove_current_element (\r
206             domain& d,\r
207             range& r\r
208         );\r
209         /*!\r
210             requires\r
211                 - current_element_valid() == true\r
212             ensures\r
213                 - the current element given by element() has been removed and swapped into d and r.\r
214                 - #d == element().key()\r
215                 - #r == element().value()\r
216                 - #count(#d) == count(#d) - 1\r
217                 - #size() == size() - 1\r
218                 - moves the enumerator to the next element.  If element() was the last \r
219                   element in enumeration order then #current_element_valid() == false \r
220                   and #at_start() == false.\r
221         !*/\r
222 \r
223         void position_enumerator (\r
224             const domain& d\r
225         ) const;\r
226         /*!\r
227             ensures\r
228                 - #at_start() == false\r
229                 - if (count(d) > 0) then\r
230                     - #element().key() == d\r
231                 - else if (there are any items in the domain of *this that are bigger than \r
232                   d according to the compare functor) then\r
233                     - #element().key() == the smallest item in the domain of *this that is\r
234                       bigger than d according to the compare functor.\r
235                 - else\r
236                     - #current_element_valid() == false\r
237         !*/\r
238 \r
239         const range* operator[] (\r
240             const domain& d\r
241         ) const;\r
242         /*!\r
243             ensures\r
244                 - if (there is an element in the domain equivalent to d) then\r
245                     - returns a pointer to an element in the range of *this that\r
246                       is associated with an element in the domain of *this \r
247                       equivalent to d.\r
248                 - else\r
249                     - returns 0\r
250         !*/\r
251 \r
252         range* operator[] (\r
253             const domain& d\r
254         );\r
255         /*!\r
256             ensures\r
257                 - if (there is an element in the domain equivalent to d) then\r
258                     - returns a pointer to an element in the range of *this that\r
259                       is associated with an element in the domain of *this \r
260                       equivalent to d.\r
261                 - else\r
262                     - returns 0\r
263         !*/\r
264 \r
265         void swap (\r
266             binary_search_tree& item\r
267         );\r
268         /*!\r
269             ensures\r
270                 - swaps *this and item\r
271         !*/ \r
272 \r
273     private:\r
274 \r
275         // restricted functions\r
276         binary_search_tree(binary_search_tree&);      \r
277         binary_search_tree& operator=(binary_search_tree&);\r
278 \r
279     };\r
280 \r
281     template <\r
282         typename domain,\r
283         typename range,\r
284         typename mem_manager,\r
285         typename compare\r
286         >\r
287     inline void swap (\r
288         binary_search_tree<domain,range,mem_manager,compare>& a, \r
289         binary_search_tree<domain,range,mem_manager,compare>& b \r
290     ) { a.swap(b); }\r
291     /*!\r
292         provides a global swap function\r
293     !*/\r
294 \r
295     template <\r
296         typename domain,\r
297         typename range,\r
298         typename mem_manager,\r
299         typename compare\r
300         >\r
301     void deserialize (\r
302         binary_search_tree<domain,range,mem_manager,compare>& item, \r
303         std::istream& in\r
304     );   \r
305     /*!\r
306         provides deserialization support \r
307     !*/\r
308 }\r
309 \r
310 #endif // DLIB_BINARY_SEARCH_TREE_KERNEl_ABSTRACT_\r
311 \r