1 // VirtualDub - Video processing and capture application
2 // System library component
3 // Copyright (C) 1998-2010 Avery Lee, All Rights Reserved.
5 // Beginning with 1.6.0, the VirtualDub system library is licensed
6 // differently than the remainder of VirtualDub. This particular file is
7 // thus licensed as follows (the "zlib" license):
9 // This software is provided 'as-is', without any express or implied
10 // warranty. In no event will the authors be held liable for any
11 // damages arising from the use of this software.
13 // Permission is granted to anyone to use this software for any purpose,
14 // including commercial applications, and to alter it and redistribute it
15 // freely, subject to the following restrictions:
17 // 1. The origin of this software must not be misrepresented; you must
18 // not claim that you wrote the original software. If you use this
19 // software in a product, an acknowledgment in the product
20 // documentation would be appreciated but is not required.
21 // 2. Altered source versions must be plainly marked as such, and must
22 // not be misrepresented as being the original software.
23 // 3. This notice may not be removed or altered from any source
26 #ifndef f_VD2_SYSTEM_VDSTL_HASHTABLE_H
27 #define f_VD2_SYSTEM_VDSTL_HASHTABLE_H
29 ///////////////////////////////////////////////////////////////////////////////
30 // vdhashtable_base_node
32 struct vdhashtable_base_node
{
33 vdhashtable_base_node
*mpHashNext
;
36 ///////////////////////////////////////////////////////////////////////////////
39 class vdhashtable_base
{
41 typedef size_t size_type
;
42 typedef ptrdiff_t difference_type
;
47 bool empty() const { return mElementCount
== 0; }
48 size_type
size() const { return mElementCount
; }
49 size_type
max_size() const { return (size_type
)-1 >> 1; }
52 size_type
bucket_count() const;
53 size_type
max_bucket_count() const;
54 size_type
bucket_size(size_type n
) const;
57 static size_type
compute_bucket_count(size_type n
);
59 size_type mBucketCount
;
60 size_type mElementCount
;
61 vdhashtable_base_node
**mpBucketStart
;
62 vdhashtable_base_node
**mpBucketEnd
;
64 static vdhashtable_base_node
*const sEmptyBucket
;
67 ///////////////////////////////////////////////////////////////////////////
70 struct vdhashtable_node
: public vdhashtable_base_node
{
74 vdhashtable_node(vdhashtable_node
<T
> *next
) : mData() {
78 vdhashtable_node(vdhashtable_node
<T
> *next
, const T
& val
) : mData(val
) {
83 ///////////////////////////////////////////////////////////////////////////
86 class vdhashtable_local_iterator
{
88 typedef std::forward_iterator_tag iterator_category
;
92 typedef size_t size_type
;
93 typedef ptrdiff_t difference_type
;
95 vdhashtable_local_iterator(vdhashtable_base_node
*node
);
97 vdhashtable_local_iterator
& operator++();
98 vdhashtable_local_iterator
operator++(int);
100 T
& operator*() const;
101 T
* operator->() const;
104 template<class U
> friend bool operator==(const vdhashtable_local_iterator
<U
>& x
, const vdhashtable_local_iterator
<U
>& y
);
105 template<class U
> friend bool operator==(const vdhashtable_local_iterator
<const U
>& x
, const vdhashtable_local_iterator
<U
>& y
);
106 template<class U
> friend bool operator==(const vdhashtable_local_iterator
<U
>& x
, const vdhashtable_local_iterator
<const U
>& y
);
107 template<class U
> friend bool operator!=(const vdhashtable_local_iterator
<U
>& x
, const vdhashtable_local_iterator
<U
>& y
);
108 template<class U
> friend bool operator!=(const vdhashtable_local_iterator
<const U
>& x
, const vdhashtable_local_iterator
<U
>& y
);
109 template<class U
> friend bool operator!=(const vdhashtable_local_iterator
<U
>& x
, const vdhashtable_local_iterator
<const U
>& y
);
111 vdhashtable_base_node
*mpNode
;
115 vdhashtable_local_iterator
<T
>::vdhashtable_local_iterator(vdhashtable_base_node
*node
)
121 vdhashtable_local_iterator
<T
>& vdhashtable_local_iterator
<T
>::operator++() {
122 mpNode
= mpNode
->mpHashNext
;
127 vdhashtable_local_iterator
<T
> vdhashtable_local_iterator
<T
>::operator++(int) {
128 vdhashtable_local_iterator
prev(*this);
129 mpNode
= mpNode
->mpHashNext
;
134 T
& vdhashtable_local_iterator
<T
>::operator*() const {
135 return static_cast<vdhashtable_node
<T
> *>(mpNode
)->mData
;
139 T
* vdhashtable_local_iterator
<T
>::operator->() const {
140 return &static_cast<vdhashtable_node
<T
> *>(mpNode
)->mData
;
144 bool operator==(const vdhashtable_local_iterator
<T
>& x
, const vdhashtable_local_iterator
<T
>& y
) {
145 return x
.mpNode
== y
.mpNode
;
149 bool operator==(const vdhashtable_local_iterator
<const T
>& x
, const vdhashtable_local_iterator
<T
>& y
) {
150 return x
.mpNode
== y
.mpNode
;
154 bool operator==(const vdhashtable_local_iterator
<T
>& x
, const vdhashtable_local_iterator
<const T
>& y
) {
155 return x
.mpNode
== y
.mpNode
;
159 bool operator!=(const vdhashtable_local_iterator
<T
>& x
, const vdhashtable_local_iterator
<T
>& y
) {
160 return x
.mpNode
!= y
.mpNode
;
164 bool operator!=(const vdhashtable_local_iterator
<const T
>& x
, const vdhashtable_local_iterator
<T
>& y
) {
165 return x
.mpNode
!= y
.mpNode
;
169 bool operator!=(const vdhashtable_local_iterator
<T
>& x
, const vdhashtable_local_iterator
<const T
>& y
) {
170 return x
.mpNode
!= y
.mpNode
;
173 ///////////////////////////////////////////////////////////////////////////
175 template<class T
> struct vdhashtable_iterator_nonconst
{
179 template<class T
> struct vdhashtable_iterator_nonconst
<const T
> {
184 class vdhashtable_iterator
{
185 typedef typename vdhashtable_iterator_nonconst
<T
>::result T_NonConst
;
187 typedef std::forward_iterator_tag iterator_category
;
188 typedef T value_type
;
190 typedef T
& reference
;
191 typedef size_t size_type
;
192 typedef ptrdiff_t difference_type
;
194 vdhashtable_iterator();
195 vdhashtable_iterator(vdhashtable_base_node
*node
, vdhashtable_base_node
**bucket
, vdhashtable_base_node
**bucketEnd
);
196 vdhashtable_iterator(const vdhashtable_iterator
<T_NonConst
>& src
);
198 vdhashtable_iterator
& operator++();
199 vdhashtable_iterator
operator++(int);
201 T
& operator*() const;
202 T
* operator->() const;
205 friend class vdhashtable_iterator
<const T
>;
206 template<class U
> friend bool operator==(const vdhashtable_iterator
<U
>& x
, const vdhashtable_iterator
<U
>& y
);
207 template<class U
> friend bool operator==(const vdhashtable_iterator
<const U
>& x
, const vdhashtable_iterator
<U
>& y
);
208 template<class U
> friend bool operator==(const vdhashtable_iterator
<U
>& x
, const vdhashtable_iterator
<const U
>& y
);
209 template<class U
> friend bool operator!=(const vdhashtable_iterator
<U
>& x
, const vdhashtable_iterator
<U
>& y
);
210 template<class U
> friend bool operator!=(const vdhashtable_iterator
<const U
>& x
, const vdhashtable_iterator
<U
>& y
);
211 template<class U
> friend bool operator!=(const vdhashtable_iterator
<U
>& x
, const vdhashtable_iterator
<const U
>& y
);
213 vdhashtable_base_node
*mpNode
;
214 vdhashtable_base_node
**mpBucket
;
215 vdhashtable_base_node
**mpBucketEnd
;
219 vdhashtable_iterator
<T
>::vdhashtable_iterator()
227 vdhashtable_iterator
<T
>::vdhashtable_iterator(vdhashtable_base_node
*node
, vdhashtable_base_node
**bucket
, vdhashtable_base_node
**bucketEnd
)
230 , mpBucketEnd(bucketEnd
)
235 vdhashtable_iterator
<T
>::vdhashtable_iterator(const vdhashtable_iterator
<T_NonConst
>& src
)
237 , mpBucket(src
.mpBucket
)
238 , mpBucketEnd(src
.mpBucketEnd
)
243 vdhashtable_iterator
<T
>& vdhashtable_iterator
<T
>::operator++() {
244 mpNode
= mpNode
->mpHashNext
;
246 while(!mpNode
&& ++mpBucket
!= mpBucketEnd
)
247 mpNode
= static_cast<vdhashtable_node
<T
> *>(*mpBucket
);
253 vdhashtable_iterator
<T
> vdhashtable_iterator
<T
>::operator++(int) {
254 vdhashtable_iterator
prev(*this);
255 mpNode
= mpNode
->mpHashNext
;
260 T
& vdhashtable_iterator
<T
>::operator*() const {
261 return static_cast<vdhashtable_node
<T
> *>(mpNode
)->mData
;
265 T
* vdhashtable_iterator
<T
>::operator->() const {
266 return &static_cast<vdhashtable_node
<T
> *>(mpNode
)->mData
;
270 bool operator==(const vdhashtable_iterator
<T
>& x
, const vdhashtable_iterator
<T
>& y
) {
271 return x
.mpNode
== y
.mpNode
;
275 bool operator==(const vdhashtable_iterator
<const T
>& x
, const vdhashtable_iterator
<T
>& y
) {
276 return x
.mpNode
== y
.mpNode
;
280 bool operator==(const vdhashtable_iterator
<T
>& x
, const vdhashtable_iterator
<const T
>& y
) {
281 return x
.mpNode
== y
.mpNode
;
285 bool operator!=(const vdhashtable_iterator
<T
>& x
, const vdhashtable_iterator
<T
>& y
) {
286 return x
.mpNode
!= y
.mpNode
;
290 bool operator!=(const vdhashtable_iterator
<const T
>& x
, const vdhashtable_iterator
<T
>& y
) {
291 return x
.mpNode
!= y
.mpNode
;
295 bool operator!=(const vdhashtable_iterator
<T
>& x
, const vdhashtable_iterator
<const T
>& y
) {
296 return x
.mpNode
!= y
.mpNode
;
299 ///////////////////////////////////////////////////////////////////////////
302 class vdhashtable
: public vdhashtable_base
{
304 typedef T value_type
;
305 typedef vdhashtable_node
<value_type
> node_type
;
306 typedef value_type
*pointer
;
307 typedef const value_type
*const_pointer
;
308 typedef value_type
& reference
;
309 typedef const value_type
& const_reference
;
310 typedef vdhashtable_iterator
<value_type
> iterator
;
311 typedef vdhashtable_iterator
<const value_type
> const_iterator
;
312 typedef vdhashtable_local_iterator
<value_type
> local_iterator
;
313 typedef vdhashtable_local_iterator
<const value_type
> const_local_iterator
;
317 const_iterator
begin() const;
319 const_iterator
end() const;
324 typename vdhashtable
<T
>::iterator vdhashtable
<T
>::begin() {
325 vdhashtable_base_node
**bucket
= mpBucketStart
;
326 vdhashtable_base_node
*p
= NULL
;
328 while(bucket
!= mpBucketEnd
) {
336 return iterator(static_cast<node_type
*>(p
), bucket
, mpBucketEnd
);
340 typename vdhashtable
<T
>::const_iterator vdhashtable
<T
>::begin() const {
341 vdhashtable_base_node
**bucket
= mpBucketStart
;
342 vdhashtable_base_node
*p
= NULL
;
344 while(bucket
!= mpBucketEnd
) {
352 return const_iterator(static_cast<node_type
*>(p
), bucket
, mpBucketEnd
);
356 typename vdhashtable
<T
>::iterator vdhashtable
<T
>::end() {
357 return iterator(NULL
, NULL
, NULL
);
361 typename vdhashtable
<T
>::const_iterator vdhashtable
<T
>::end() const {
362 return const_iterator(NULL
, NULL
, NULL
);
365 #endif // f_VD2_SYSTEM_VDSTL_HASHTABLE_H