Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

353 lines
10 KiB

  1. #if _MSC_VER > 1000
  2. #pragma once
  3. #endif // _MSC_VER > 1000
  4. template< class Key>
  5. class hash
  6. {
  7. private:
  8. hash() {}
  9. };
  10. template<>
  11. class hash< char>:
  12. public unary_function< char, size_t>
  13. {
  14. public:
  15. result_type operator()( argument_type Arg) const
  16. { return static_cast<result_type>(Arg); }
  17. };
  18. template<>
  19. class hash< unsigned char>:
  20. public unary_function< unsigned char, size_t>
  21. {
  22. public:
  23. result_type operator()( argument_type Arg) const
  24. { return static_cast<result_type>(Arg); }
  25. };
  26. template<>
  27. class hash< signed char>:
  28. public unary_function< signed char, size_t>
  29. {
  30. public:
  31. result_type operator()( argument_type Arg) const
  32. { return static_cast<result_type>(Arg); }
  33. };
  34. template<>
  35. class hash< short>:
  36. public unary_function< short, size_t>
  37. {
  38. public:
  39. result_type operator()( argument_type Arg) const
  40. { return static_cast<result_type>(Arg); }
  41. };
  42. template<>
  43. class hash< unsigned short>:
  44. public unary_function< unsigned short, size_t>
  45. {
  46. public:
  47. result_type operator()( argument_type Arg) const
  48. { return static_cast<result_type>(Arg); }
  49. };
  50. template<>
  51. class hash< int>:
  52. public unary_function< int, size_t>
  53. {
  54. public:
  55. result_type operator()( argument_type Arg) const
  56. { return static_cast<result_type>(Arg); }
  57. };
  58. template<>
  59. class hash< unsigned int>:
  60. public unary_function< unsigned int, size_t>
  61. {
  62. public:
  63. result_type operator()( argument_type Arg) const
  64. { return static_cast<result_type>(Arg); }
  65. };
  66. template<>
  67. class hash< long>:
  68. public unary_function< long, size_t>
  69. {
  70. public:
  71. result_type operator()( argument_type Arg) const
  72. { return static_cast<result_type>(Arg); }
  73. };
  74. template<>
  75. class hash< unsigned long>:
  76. public unary_function< unsigned long, size_t>
  77. {
  78. public:
  79. result_type operator()( argument_type Arg) const
  80. { return static_cast<result_type>(Arg); }
  81. };
  82. template< class T, const size_t Buckets, class Key, class HashFun,
  83. class ExtractKey, class EqualKey, class Allocator>
  84. class static_hash_table:
  85. public list< T, Allocator>
  86. {
  87. public: // Types
  88. typedef static_hash_table< T, Buckets, Key, HashFun, ExtractKey, EqualKey,
  89. Allocator> table_type;
  90. typedef list< T, Allocator> list_type;
  91. typedef Key key_type;
  92. using list_type::value_type;
  93. typedef HashFun hasher;
  94. typedef EqualKey key_equal;
  95. typedef ExtractKey key_extract;
  96. using list_type::pointer;
  97. using list_type::const_pointer;
  98. using list_type::reference;
  99. using list_type::const_reference;
  100. using list_type::size_type;
  101. using list_type::difference_type;
  102. using list_type::iterator;
  103. using list_type::const_iterator;
  104. using list_type::reverse_iterator;
  105. using list_type::const_reverse_iterator;
  106. protected: // Types
  107. typedef block< iterator, Buckets+ 1> table_buckets_type;
  108. protected: // Variables
  109. table_buckets_type m_buckets;
  110. hasher m_hasher;
  111. key_equal m_key_equal;
  112. key_extract m_key_extract;
  113. public: // Functions
  114. using list_type::begin;
  115. using list_type::end;
  116. using list_type::rbegin;
  117. using list_type::rend;
  118. using list_type::size;
  119. using list_type::max_size;
  120. using list_type::empty;
  121. size_type bucket_count() const
  122. { return m_buckets.size()- 1; }
  123. void resize( size_type n)
  124. { const bool NYI( false); assert( NYI); /* TODO: NYI */ }
  125. hasher hash_funct() const
  126. { return m_hasher; }
  127. key_equal key_eq() const
  128. { return m_key_equal; }
  129. static_hash_table( const HashFun& H, const EqualKey& EqK,
  130. const ExtractKey& ExK, const allocator_type& A): list_type( A),
  131. m_hasher( H), m_key_equal( EqK), m_key_extract( ExK)
  132. {
  133. fill( m_buckets.begin(), m_buckets.end(), end());
  134. }
  135. static_hash_table( const table_type& HT): list_type( HT.get_allocator())
  136. {
  137. fill( m_buckets.begin(), m_buckets.end(), end());
  138. (*this)= HT;
  139. }
  140. ~static_hash_table()
  141. {
  142. }
  143. table_type& operator=( const table_type& Other)
  144. {
  145. if( this!= &Other)
  146. {
  147. clear();
  148. m_hasher= Other.m_hasher;
  149. m_key_equal= Other.m_key_equal;
  150. m_key_extract= Other.m_key_extract;
  151. // TODO: insert_equal( Other.begin(), Other.end());
  152. insert_unique( Other.begin(), Other.end());
  153. }
  154. return *this;
  155. }
  156. using list_type::get_allocator;
  157. void swap( table_type& Other)
  158. {
  159. const bool NYI( false); assert( NYI);
  160. /* TODO: NYI
  161. swap( m_hasher, Other.m_hasher);
  162. swap( m_key_equal, Other.m_key_equal);
  163. swap( m_key_extract, Other.m_key_extract);
  164. if( m_Allocator== Other.m_Allocator)
  165. {
  166. list_type::swap( Other);
  167. m_buckets.swap( Other.m_buckets);
  168. }
  169. else
  170. insert_equal( Other.begin(), Other.end());
  171. */
  172. }
  173. pair< iterator, bool> insert_unique( const value_type& NewVal)
  174. {
  175. const key_type NewKey( m_key_extract( NewVal));
  176. const size_t uiBucket( m_hasher( NewKey)% bucket_count());
  177. table_buckets_type::iterator itBucket( m_buckets.begin());
  178. itBucket+= uiBucket;
  179. table_buckets_type::iterator itNextBucket( itBucket);
  180. ++itNextBucket;
  181. for( iterator itFound( *itBucket); itFound!= *itNextBucket; ++itFound)
  182. if( m_key_equal( NewKey, m_key_extract( *itFound)))
  183. return pair< iterator, bool>( itFound, false);
  184. iterator itInsertPos( *itNextBucket);
  185. table_buckets_type::iterator itBeginFill( m_buckets.begin());
  186. if( begin()!= itInsertPos)
  187. {
  188. iterator itPrevNode( itInsertPos);
  189. itBeginFill+= ( m_hasher( m_key_extract( *(--itPrevNode)))%
  190. bucket_count())+ 1;
  191. }
  192. iterator itNewNode( insert( itInsertPos, NewVal));
  193. fill( itBeginFill, ++itBucket, itNewNode);
  194. return pair< iterator, bool>( itNewNode, true);
  195. }
  196. template <class InputIterator>
  197. void insert_unique( InputIterator f, InputIterator l)
  198. {
  199. while( f!= l)
  200. {
  201. insert_unique( *f);
  202. ++f;
  203. }
  204. }
  205. iterator insert_equal( const value_type& NewVal)
  206. {
  207. // TODO: NYI
  208. const bool NYI( false); assert( NYI);
  209. return end();
  210. }
  211. template< class InputIterator>
  212. void insert_equal( InputIterator f, InputIterator l)
  213. {
  214. while( f!= l)
  215. {
  216. insert_equal( *f);
  217. ++f;
  218. }
  219. }
  220. void erase( iterator pos)
  221. {
  222. table_buckets_type::iterator itBeginFill( m_buckets.begin());
  223. if( begin()!= pos)
  224. {
  225. iterator itPrevNode( pos);
  226. itBeginFill+= ( m_hasher( m_key_extract( *(--itPrevNode)))%
  227. bucket_count())+ 1;
  228. }
  229. table_buckets_type::iterator itEndFill( m_buckets.begin());
  230. itEndFill+= ( m_hasher( m_key_extract( *pos))% bucket_count())+ 1;
  231. iterator itNextNode( pos);
  232. ++itNextNode;
  233. fill( itBeginFill, itEndFill, itNextNode);
  234. list_type::erase( pos);
  235. }
  236. size_type erase( const key_type& k)
  237. {
  238. size_type uiErased( 0);
  239. const size_type uiBucket( m_hasher( k)% bucket_count());
  240. table_buckets_type::iterator itBucket( m_buckets.begin());
  241. itBucket+= uiBucket;
  242. table_buckets_type::iterator itNextBucket( itBucket);
  243. ++itNextBucket;
  244. iterator itChk( *itBucket);
  245. // Only the first in the bucket could modify the bucket values.
  246. if( itChk!= *itNextBucket)
  247. {
  248. if( m_key_equal( k, m_key_extract( *itChk)))
  249. {
  250. iterator itDel( itChk);
  251. ++itChk;
  252. erase( itDel);
  253. ++uiErased;
  254. }
  255. else
  256. ++itChk;
  257. }
  258. while( itChk!= *itNextBucket)
  259. {
  260. if( m_key_equal( k, m_key_extract( *itChk)))
  261. {
  262. iterator itDel( itChk);
  263. ++itChk;
  264. list_type::erase( itDel);
  265. ++uiErased;
  266. }
  267. else
  268. ++itChk;
  269. }
  270. return uiErased;
  271. }
  272. void erase( iterator f, iterator l)
  273. {
  274. while( f!= l)
  275. {
  276. erase( f);
  277. ++f;
  278. }
  279. }
  280. iterator find( const key_type& k)
  281. {
  282. const size_type uiBucket( m_hasher( k)% bucket_count());
  283. table_buckets_type::iterator itBucket( m_buckets.begin());
  284. itBucket+= uiBucket;
  285. table_buckets_type::iterator itNextBucket( itBucket);
  286. ++itNextBucket;
  287. for( iterator itFound( *itBucket); itFound!= *itNextBucket; ++itFound)
  288. if( m_key_equal( k, m_key_extract( *itFound)))
  289. return itFound;
  290. return end();
  291. }
  292. const_iterator find( const key_type& k) const
  293. {
  294. const size_type uiBucket( m_hasher( k)% bucket_count());
  295. table_buckets_type::const_iterator itBucket( m_buckets.begin());
  296. itBucket+= uiBucket;
  297. table_buckets_type::const_iterator itNextBucket( itBucket);
  298. ++itNextBucket;
  299. for( const_iterator itFound( *itBucket); itFound!= *itNextBucket; ++itFound)
  300. if( m_key_equal( k, m_key_extract( *itFound)))
  301. return itFound;
  302. return end();
  303. }
  304. size_type count( const key_type& k) const
  305. {
  306. // TODO: NYI
  307. const bool NYI( false); assert( NYI);
  308. return 0;
  309. }
  310. pair< iterator, iterator> equal_range( const key_type& k)
  311. {
  312. // TODO: NYI
  313. const bool NYI( false); assert( NYI);
  314. return pair< iterator, iterator>( end(), end());
  315. }
  316. pair< const_iterator, const_iterator> equal_range( const key_type& k) const
  317. {
  318. // TODO: NYI
  319. const bool NYI( false); assert( NYI);
  320. return pair< const_iterator, const_iterator>( end(), end());
  321. }
  322. void clear()
  323. {
  324. if( 0!= size())
  325. {
  326. fill( m_buckets.begin(), m_buckets.end(), end());
  327. list_type::clear();
  328. }
  329. }
  330. };
  331. // TODO: Global operators.