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

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
template< class Key>
class hash
{
private:
hash() {}
};
template<>
class hash< char>:
public unary_function< char, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< unsigned char>:
public unary_function< unsigned char, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< signed char>:
public unary_function< signed char, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< short>:
public unary_function< short, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< unsigned short>:
public unary_function< unsigned short, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< int>:
public unary_function< int, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< unsigned int>:
public unary_function< unsigned int, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< long>:
public unary_function< long, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template<>
class hash< unsigned long>:
public unary_function< unsigned long, size_t>
{
public:
result_type operator()( argument_type Arg) const
{ return static_cast<result_type>(Arg); }
};
template< class T, const size_t Buckets, class Key, class HashFun,
class ExtractKey, class EqualKey, class Allocator>
class static_hash_table:
public list< T, Allocator>
{
public: // Types
typedef static_hash_table< T, Buckets, Key, HashFun, ExtractKey, EqualKey,
Allocator> table_type;
typedef list< T, Allocator> list_type;
typedef Key key_type;
using list_type::value_type;
typedef HashFun hasher;
typedef EqualKey key_equal;
typedef ExtractKey key_extract;
using list_type::pointer;
using list_type::const_pointer;
using list_type::reference;
using list_type::const_reference;
using list_type::size_type;
using list_type::difference_type;
using list_type::iterator;
using list_type::const_iterator;
using list_type::reverse_iterator;
using list_type::const_reverse_iterator;
protected: // Types
typedef block< iterator, Buckets+ 1> table_buckets_type;
protected: // Variables
table_buckets_type m_buckets;
hasher m_hasher;
key_equal m_key_equal;
key_extract m_key_extract;
public: // Functions
using list_type::begin;
using list_type::end;
using list_type::rbegin;
using list_type::rend;
using list_type::size;
using list_type::max_size;
using list_type::empty;
size_type bucket_count() const
{ return m_buckets.size()- 1; }
void resize( size_type n)
{ const bool NYI( false); assert( NYI); /* TODO: NYI */ }
hasher hash_funct() const
{ return m_hasher; }
key_equal key_eq() const
{ return m_key_equal; }
static_hash_table( const HashFun& H, const EqualKey& EqK,
const ExtractKey& ExK, const allocator_type& A): list_type( A),
m_hasher( H), m_key_equal( EqK), m_key_extract( ExK)
{
fill( m_buckets.begin(), m_buckets.end(), end());
}
static_hash_table( const table_type& HT): list_type( HT.get_allocator())
{
fill( m_buckets.begin(), m_buckets.end(), end());
(*this)= HT;
}
~static_hash_table()
{
}
table_type& operator=( const table_type& Other)
{
if( this!= &Other)
{
clear();
m_hasher= Other.m_hasher;
m_key_equal= Other.m_key_equal;
m_key_extract= Other.m_key_extract;
// TODO: insert_equal( Other.begin(), Other.end());
insert_unique( Other.begin(), Other.end());
}
return *this;
}
using list_type::get_allocator;
void swap( table_type& Other)
{
const bool NYI( false); assert( NYI);
/* TODO: NYI
swap( m_hasher, Other.m_hasher);
swap( m_key_equal, Other.m_key_equal);
swap( m_key_extract, Other.m_key_extract);
if( m_Allocator== Other.m_Allocator)
{
list_type::swap( Other);
m_buckets.swap( Other.m_buckets);
}
else
insert_equal( Other.begin(), Other.end());
*/
}
pair< iterator, bool> insert_unique( const value_type& NewVal)
{
const key_type NewKey( m_key_extract( NewVal));
const size_t uiBucket( m_hasher( NewKey)% bucket_count());
table_buckets_type::iterator itBucket( m_buckets.begin());
itBucket+= uiBucket;
table_buckets_type::iterator itNextBucket( itBucket);
++itNextBucket;
for( iterator itFound( *itBucket); itFound!= *itNextBucket; ++itFound)
if( m_key_equal( NewKey, m_key_extract( *itFound)))
return pair< iterator, bool>( itFound, false);
iterator itInsertPos( *itNextBucket);
table_buckets_type::iterator itBeginFill( m_buckets.begin());
if( begin()!= itInsertPos)
{
iterator itPrevNode( itInsertPos);
itBeginFill+= ( m_hasher( m_key_extract( *(--itPrevNode)))%
bucket_count())+ 1;
}
iterator itNewNode( insert( itInsertPos, NewVal));
fill( itBeginFill, ++itBucket, itNewNode);
return pair< iterator, bool>( itNewNode, true);
}
template <class InputIterator>
void insert_unique( InputIterator f, InputIterator l)
{
while( f!= l)
{
insert_unique( *f);
++f;
}
}
iterator insert_equal( const value_type& NewVal)
{
// TODO: NYI
const bool NYI( false); assert( NYI);
return end();
}
template< class InputIterator>
void insert_equal( InputIterator f, InputIterator l)
{
while( f!= l)
{
insert_equal( *f);
++f;
}
}
void erase( iterator pos)
{
table_buckets_type::iterator itBeginFill( m_buckets.begin());
if( begin()!= pos)
{
iterator itPrevNode( pos);
itBeginFill+= ( m_hasher( m_key_extract( *(--itPrevNode)))%
bucket_count())+ 1;
}
table_buckets_type::iterator itEndFill( m_buckets.begin());
itEndFill+= ( m_hasher( m_key_extract( *pos))% bucket_count())+ 1;
iterator itNextNode( pos);
++itNextNode;
fill( itBeginFill, itEndFill, itNextNode);
list_type::erase( pos);
}
size_type erase( const key_type& k)
{
size_type uiErased( 0);
const size_type uiBucket( m_hasher( k)% bucket_count());
table_buckets_type::iterator itBucket( m_buckets.begin());
itBucket+= uiBucket;
table_buckets_type::iterator itNextBucket( itBucket);
++itNextBucket;
iterator itChk( *itBucket);
// Only the first in the bucket could modify the bucket values.
if( itChk!= *itNextBucket)
{
if( m_key_equal( k, m_key_extract( *itChk)))
{
iterator itDel( itChk);
++itChk;
erase( itDel);
++uiErased;
}
else
++itChk;
}
while( itChk!= *itNextBucket)
{
if( m_key_equal( k, m_key_extract( *itChk)))
{
iterator itDel( itChk);
++itChk;
list_type::erase( itDel);
++uiErased;
}
else
++itChk;
}
return uiErased;
}
void erase( iterator f, iterator l)
{
while( f!= l)
{
erase( f);
++f;
}
}
iterator find( const key_type& k)
{
const size_type uiBucket( m_hasher( k)% bucket_count());
table_buckets_type::iterator itBucket( m_buckets.begin());
itBucket+= uiBucket;
table_buckets_type::iterator itNextBucket( itBucket);
++itNextBucket;
for( iterator itFound( *itBucket); itFound!= *itNextBucket; ++itFound)
if( m_key_equal( k, m_key_extract( *itFound)))
return itFound;
return end();
}
const_iterator find( const key_type& k) const
{
const size_type uiBucket( m_hasher( k)% bucket_count());
table_buckets_type::const_iterator itBucket( m_buckets.begin());
itBucket+= uiBucket;
table_buckets_type::const_iterator itNextBucket( itBucket);
++itNextBucket;
for( const_iterator itFound( *itBucket); itFound!= *itNextBucket; ++itFound)
if( m_key_equal( k, m_key_extract( *itFound)))
return itFound;
return end();
}
size_type count( const key_type& k) const
{
// TODO: NYI
const bool NYI( false); assert( NYI);
return 0;
}
pair< iterator, iterator> equal_range( const key_type& k)
{
// TODO: NYI
const bool NYI( false); assert( NYI);
return pair< iterator, iterator>( end(), end());
}
pair< const_iterator, const_iterator> equal_range( const key_type& k) const
{
// TODO: NYI
const bool NYI( false); assert( NYI);
return pair< const_iterator, const_iterator>( end(), end());
}
void clear()
{
if( 0!= size())
{
fill( m_buckets.begin(), m_buckets.end(), end());
list_type::clear();
}
}
};
// TODO: Global operators.