Teh first one
[mldemos:kalians-mldemos.git] / _AlgorithmsPlugins / KernelMethods / dlib / sliding_buffer / sliding_buffer_kernel_1.h
1 // Copyright (C) 2004  Davis E. King (davis@dlib.net)\r
2 // License: Boost Software License   See LICENSE.txt for the full license.\r
3 #ifndef DLIB_SLIDING_BUFFER_KERNEl_1_\r
4 #define DLIB_SLIDING_BUFFER_KERNEl_1_\r
5 \r
6 #include "sliding_buffer_kernel_abstract.h"\r
7 #include "../algs.h"\r
8 #include "../interfaces/enumerable.h"\r
9 #include "../serialize.h"\r
10 \r
11 namespace dlib\r
12 {\r
13 \r
14     template <\r
15         typename T\r
16         >\r
17     class sliding_buffer_kernel_1 : public enumerable<T>\r
18     {\r
19         /*!\r
20             INITIAL VALUE\r
21                 - buffer_size == 0\r
22                 - buffer == 0\r
23                 - buffer_start == 0\r
24                 - current == 0\r
25                 - at_start_ == true\r
26 \r
27             CONVENTION\r
28                 - buffer_size == size()\r
29                 \r
30                 - element() == (*this)[current]\r
31                 - current_element_valid() == (current < buffer_size) && at_start_ == false\r
32                 - at_start() == at_start_\r
33 \r
34                 - if (buffer_size != 0) then                    \r
35                     - buffer[(buffer_start+i)&(mask)] == operator[](i)   \r
36                     - mask == buffer_size-1\r
37                 - else\r
38                     - buffer == 0\r
39                     - buffer_size == 0\r
40         !*/\r
41 \r
42     public:\r
43 \r
44         typedef T type;\r
45 \r
46         sliding_buffer_kernel_1 (\r
47         ) :\r
48             buffer_start(0),\r
49             buffer_size(0),\r
50             buffer(0),\r
51             current(0),\r
52             at_start_(true)\r
53         {}\r
54 \r
55         virtual ~sliding_buffer_kernel_1 (\r
56         ) { if (buffer) delete [] buffer; }\r
57 \r
58         void clear(\r
59         ) \r
60         {\r
61             buffer_size = 0; \r
62             if (buffer) delete [] buffer;\r
63             buffer = 0;\r
64             at_start_ = true;\r
65             current = 0;\r
66         }\r
67 \r
68         void set_size (\r
69             unsigned long exp_size\r
70         )\r
71         {\r
72             at_start_ = true;\r
73             if (buffer) delete [] buffer;\r
74             buffer_size = 1;\r
75             while (exp_size != 0)\r
76             {\r
77                 --exp_size;\r
78                 buffer_size <<= 1;            \r
79             }\r
80             mask = buffer_size-1;\r
81             try { buffer = new T[buffer_size]; }\r
82             catch (...) { buffer = 0; buffer_size = 0; throw; }\r
83         }\r
84 \r
85         unsigned long size (\r
86         ) const { return buffer_size; }\r
87 \r
88         void rotate_left (\r
89             unsigned long amount\r
90         ) { buffer_start = ((buffer_start-amount)&mask); at_start_ = true; }\r
91 \r
92         void rotate_right (\r
93             unsigned long amount\r
94         ) { buffer_start = ((buffer_start+amount)&mask); at_start_ = true;}\r
95 \r
96         const T& operator[] (\r
97             unsigned long index\r
98         ) const { return buffer[(buffer_start+index)&mask]; }\r
99 \r
100         T& operator[] (\r
101             unsigned long index\r
102         ) { return buffer[(buffer_start+index)&mask]; }\r
103 \r
104         unsigned long get_element_id(\r
105             unsigned long index\r
106         ) const { return ((buffer_start+index)&mask); }\r
107 \r
108         unsigned long get_element_index (\r
109             unsigned long element_id \r
110         ) const { return ((element_id-buffer_start)&mask);}\r
111 \r
112         void swap (\r
113             sliding_buffer_kernel_1<T>& item\r
114         )\r
115         {\r
116             exchange(buffer_start,item.buffer_start);\r
117             exchange(buffer_size,item.buffer_size);\r
118             exchange(buffer,item.buffer);\r
119             exchange(mask,item.mask);\r
120             exchange(current,item.current);\r
121             exchange(at_start_,item.at_start_);\r
122         }\r
123 \r
124 \r
125         bool at_start (\r
126         ) const { return at_start_; }\r
127 \r
128         void reset (\r
129         ) const { at_start_ = true; }\r
130 \r
131         bool current_element_valid (\r
132         ) const { return (current < buffer_size) && (at_start_ == false); }\r
133 \r
134         const T& element (\r
135         ) const { return (*this)[current]; }\r
136 \r
137         T& element (\r
138         ) { return (*this)[current]; }\r
139 \r
140         bool move_next (\r
141         ) const \r
142         { \r
143             if (at_start_ == false)\r
144             {\r
145                 if (current+1 < buffer_size)\r
146                 {\r
147                     ++current;\r
148                     return true;\r
149                 }\r
150                 else\r
151                 {\r
152                     current = buffer_size;\r
153                     return false;\r
154                 }\r
155             }\r
156             else \r
157             {\r
158                 at_start_ = false;\r
159                 current = 0;\r
160                 return (buffer_size != 0);\r
161             }\r
162         }\r
163 \r
164 \r
165     private:\r
166 \r
167         // data members\r
168         unsigned long buffer_start;\r
169         unsigned long buffer_size;\r
170         T* buffer;\r
171         unsigned long mask;\r
172 \r
173 \r
174         mutable unsigned long current;\r
175         mutable bool at_start_;\r
176 \r
177         // restricted functions\r
178         sliding_buffer_kernel_1(sliding_buffer_kernel_1<T>&);        // copy constructor\r
179         sliding_buffer_kernel_1<T>& operator=(sliding_buffer_kernel_1<T>&);    // assignment operator\r
180 \r
181     };      \r
182 \r
183     template <\r
184         typename T\r
185         >\r
186     inline void swap (\r
187         sliding_buffer_kernel_1<T>& a, \r
188         sliding_buffer_kernel_1<T>& b \r
189     ) { a.swap(b); }   \r
190 \r
191     template <\r
192         typename T\r
193         >\r
194     void deserialize (\r
195         sliding_buffer_kernel_1<T>& item, \r
196         std::istream& in\r
197     )   \r
198     {\r
199         try\r
200         {\r
201             item.clear();\r
202             unsigned long size;\r
203             deserialize(size,in);\r
204             if (size > 0)\r
205             {\r
206                 int count = 0;\r
207                 while (size != 1)\r
208                 {\r
209                     size /= 2;\r
210                     ++count;\r
211                 }\r
212                 item.set_size(count);\r
213 \r
214                 for (unsigned long i = 0; i < item.size(); ++i)\r
215                     deserialize(item[i],in);\r
216             }\r
217         }\r
218         catch (serialization_error e)\r
219         { \r
220             item.clear();\r
221             throw serialization_error(e.info + "\n   while deserializing object of type sliding_buffer_kernel_1"); \r
222         }\r
223     }\r
224 }\r
225 \r
226 #endif // DLIB_SLIDING_BUFFER_KERNEl_1_\r
227 \r