mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-09-01 05:07:46 +00:00
Master commit of OpenFace.
This commit is contained in:
819
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_1.h
vendored
Normal file
819
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_1.h
vendored
Normal file
@@ -0,0 +1,819 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_HASH_TABLE_KERNEl_1_
|
||||
#define DLIB_HASH_TABLE_KERNEl_1_
|
||||
|
||||
#include "hash_table_kernel_abstract.h"
|
||||
#include "../general_hash/general_hash.h"
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../assert.h"
|
||||
#include "../serialize.h"
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<domain>
|
||||
>
|
||||
class hash_table_kernel_1 : public enumerable<map_pair<domain, range> >,
|
||||
public pair_remover<domain,range>
|
||||
{
|
||||
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
hash_size == 0
|
||||
table == pointer to an array of num_of_buckets node pointers
|
||||
num_of_buckets == the number of buckets in the hash table
|
||||
current_element == 0
|
||||
at_start_ == true
|
||||
mask == num_of_buckets-1
|
||||
|
||||
CONVENTION
|
||||
current_element_valid() == (current_element != 0)
|
||||
element() == current_element->d and current_element->r
|
||||
at_start_ == at_start()
|
||||
if (current_element != 0) then
|
||||
table[current_bucket] == a pointer to the linked list that contains
|
||||
the node pointed to by current_element
|
||||
|
||||
mask == num_of_buckets-1
|
||||
|
||||
|
||||
|
||||
hash_size = size() == the number of elements in the hash_table and
|
||||
table == pointer to an array of num_of_buckets node pointers and
|
||||
num_of_buckets == the number of buckets in the hash table and
|
||||
for all i:
|
||||
table[i] == pointer to the first node in a linked list or
|
||||
table[i] == 0 if this bucket is currently not in use
|
||||
|
||||
|
||||
for all nodes:
|
||||
d == the domain element stored in this node
|
||||
r == the range element stored in this node which is associated with
|
||||
d.
|
||||
next == pointer to the next node in the linked list or
|
||||
next == 0 if this is the last node in the linked list
|
||||
|
||||
!*/
|
||||
|
||||
struct node
|
||||
{
|
||||
node* next;
|
||||
domain d;
|
||||
range r;
|
||||
};
|
||||
|
||||
|
||||
class mpair : public map_pair<domain,range>
|
||||
{
|
||||
public:
|
||||
const domain* d;
|
||||
range* r;
|
||||
|
||||
const domain& key(
|
||||
) const { return *d; }
|
||||
|
||||
const range& value(
|
||||
) const { return *r; }
|
||||
|
||||
range& value(
|
||||
) { return *r; }
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef domain domain_type;
|
||||
typedef range range_type;
|
||||
typedef compare compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
explicit hash_table_kernel_1(
|
||||
unsigned long expnum
|
||||
);
|
||||
|
||||
virtual ~hash_table_kernel_1(
|
||||
);
|
||||
|
||||
void clear(
|
||||
);
|
||||
|
||||
unsigned long count (
|
||||
const domain& item
|
||||
) const;
|
||||
|
||||
void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
const range* operator[] (
|
||||
const domain& d
|
||||
) const;
|
||||
|
||||
range* operator[] (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
void swap (
|
||||
hash_table_kernel_1& item
|
||||
);
|
||||
|
||||
// functions from the remover interface
|
||||
void remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
// functions from the enumerable interface
|
||||
inline unsigned long size (
|
||||
) const;
|
||||
|
||||
bool at_start (
|
||||
) const;
|
||||
|
||||
inline void reset (
|
||||
) const;
|
||||
|
||||
bool current_element_valid (
|
||||
) const;
|
||||
|
||||
const map_pair<domain,range>& element (
|
||||
) const;
|
||||
|
||||
map_pair<domain,range>& element (
|
||||
);
|
||||
|
||||
bool move_next (
|
||||
) const;
|
||||
|
||||
private:
|
||||
|
||||
// data members
|
||||
typename mem_manager::template rebind<node>::other pool;
|
||||
typename mem_manager::template rebind<node*>::other ppool;
|
||||
unsigned long hash_size;
|
||||
node** table;
|
||||
general_hash<domain> hash;
|
||||
unsigned long num_of_buckets;
|
||||
unsigned long mask;
|
||||
|
||||
mutable mpair p;
|
||||
|
||||
mutable unsigned long current_bucket;
|
||||
mutable node* current_element;
|
||||
mutable bool at_start_;
|
||||
compare comp;
|
||||
|
||||
// restricted functions
|
||||
hash_table_kernel_1(hash_table_kernel_1&);
|
||||
hash_table_kernel_1& operator=(hash_table_kernel_1&);
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
inline void swap (
|
||||
hash_table_kernel_1<domain,range,mem_manager,compare>& a,
|
||||
hash_table_kernel_1<domain,range,mem_manager,compare>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void deserialize (
|
||||
hash_table_kernel_1<domain,range,mem_manager,compare>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.clear();
|
||||
unsigned long size;
|
||||
deserialize(size,in);
|
||||
domain d;
|
||||
range r;
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
deserialize(d,in);
|
||||
deserialize(r,in);
|
||||
item.add(d,r);
|
||||
}
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type hash_table_kernel_1");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
hash_table_kernel_1(
|
||||
unsigned long expnum
|
||||
) :
|
||||
hash_size(0),
|
||||
current_element(0),
|
||||
at_start_(true)
|
||||
{
|
||||
|
||||
num_of_buckets = 1;
|
||||
while (expnum != 0)
|
||||
{
|
||||
--expnum;
|
||||
num_of_buckets <<= 1;
|
||||
}
|
||||
mask = num_of_buckets-1;
|
||||
|
||||
table = ppool.allocate_array(num_of_buckets);
|
||||
for (unsigned long i = 0; i < num_of_buckets; ++i)
|
||||
{
|
||||
table[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
~hash_table_kernel_1(
|
||||
)
|
||||
{
|
||||
for (unsigned long i = 0; i < num_of_buckets; ++i)
|
||||
{
|
||||
// delete this linked list
|
||||
node* temp = table[i];
|
||||
while (temp)
|
||||
{
|
||||
node* t = temp;
|
||||
temp = temp->next;
|
||||
pool.deallocate(t);
|
||||
}
|
||||
table[i] = 0;
|
||||
}
|
||||
ppool.deallocate_array(table);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
clear(
|
||||
)
|
||||
{
|
||||
if (hash_size > 0)
|
||||
{
|
||||
for (unsigned long i = 0; i < num_of_buckets; ++i)
|
||||
{
|
||||
// delete this linked list
|
||||
node* temp = table[i];
|
||||
while (temp)
|
||||
{
|
||||
node* t = temp;
|
||||
temp = temp->next;
|
||||
pool.deallocate(t);
|
||||
}
|
||||
table[i] = 0;
|
||||
}
|
||||
hash_size = 0;
|
||||
}
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
unsigned long hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
size(
|
||||
) const
|
||||
{
|
||||
return hash_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
unsigned long hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
count(
|
||||
const domain& d
|
||||
) const
|
||||
{
|
||||
unsigned long items_found = 0;
|
||||
node* temp = table[hash(d)&mask];
|
||||
|
||||
while (temp != 0)
|
||||
{
|
||||
// look for an element equivalent to d
|
||||
if ( !(comp(temp->d , d) || comp(d , temp->d)) )
|
||||
{
|
||||
++items_found;
|
||||
}
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
return items_found;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
add(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
unsigned long hash_value = hash(d)&mask;
|
||||
|
||||
// make a new node for this item
|
||||
node& temp = *(pool.allocate());
|
||||
exchange(d,temp.d);
|
||||
exchange(r,temp.r);
|
||||
|
||||
// add this new node to the head of the linked list in bucket number hash_value
|
||||
temp.next = table[hash_value];
|
||||
table[hash_value] = &temp;
|
||||
|
||||
++hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
destroy(
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
node* last;
|
||||
const unsigned long hash_value = hash(d)&mask;
|
||||
node* temp = table[hash_value];
|
||||
|
||||
// if there is more than one thing in this bucket
|
||||
if (temp->next != 0)
|
||||
{
|
||||
// start looking with the second item in the list
|
||||
last = temp;
|
||||
temp = temp->next;
|
||||
while (true)
|
||||
{
|
||||
// if we hit the end of the list without finding item then it must
|
||||
// be the first element in the list so splice it out
|
||||
if (temp == 0)
|
||||
{
|
||||
temp = table[hash_value];
|
||||
table[hash_value] = temp->next;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// look for an element equivalent to item
|
||||
if ( !(comp(temp->d , d) || comp(d , temp->d)) )
|
||||
{
|
||||
// splice out the node we want to remove
|
||||
last->next = temp->next;
|
||||
break;
|
||||
}
|
||||
|
||||
last = temp;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
}
|
||||
// else there is only one node in this linked list
|
||||
else
|
||||
{
|
||||
table[hash_value] = 0;
|
||||
}
|
||||
|
||||
pool.deallocate(temp);
|
||||
|
||||
--hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
remove(
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
node* last;
|
||||
const unsigned long hash_value = hash(d)&mask;
|
||||
node* temp = table[hash_value];
|
||||
|
||||
// if there is more than one thing in this bucket
|
||||
if (temp->next != 0)
|
||||
{
|
||||
// start looking with the second item in the list
|
||||
last = temp;
|
||||
temp = temp->next;
|
||||
while (true)
|
||||
{
|
||||
// if we hit the end of the list without finding item then it must
|
||||
// be the first element in the list so splice it out
|
||||
if (temp == 0)
|
||||
{
|
||||
temp = table[hash_value];
|
||||
table[hash_value] = temp->next;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// look for an element equivalent to item
|
||||
if ( !(comp(temp->d , d) || comp(d , temp->d)) )
|
||||
{
|
||||
// splice out the node we want to remove
|
||||
last->next = temp->next;
|
||||
break;
|
||||
}
|
||||
|
||||
last = temp;
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
}
|
||||
// else there is only one node in this linked list
|
||||
else
|
||||
{
|
||||
table[hash_value] = 0;
|
||||
}
|
||||
|
||||
|
||||
exchange(d_copy,temp->d);
|
||||
exchange(r,temp->r);
|
||||
pool.deallocate(temp);
|
||||
|
||||
--hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
remove_any(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
|
||||
// while the ith bucket is empty keep looking
|
||||
while (table[i] == 0)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
// remove the first node in the linked list in the ith bucket
|
||||
node& temp = *(table[i]);
|
||||
|
||||
exchange(temp.d,d);
|
||||
exchange(temp.r,r);
|
||||
table[i] = temp.next;
|
||||
|
||||
pool.deallocate(&temp);
|
||||
|
||||
--hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
const range* hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
operator[](
|
||||
const domain& d
|
||||
) const
|
||||
{
|
||||
node* temp = table[hash(d)&mask];
|
||||
|
||||
while (temp != 0)
|
||||
{
|
||||
// look for an element equivalent to item
|
||||
if ( !(comp(temp->d , d) || comp(d , temp->d)) )
|
||||
return &(temp->r);
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
range* hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
operator[](
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
node* temp = table[hash(d)&mask];
|
||||
|
||||
while (temp != 0)
|
||||
{
|
||||
// look for an element equivalent to item
|
||||
if ( !(comp(temp->d , d) || comp(d , temp->d)) )
|
||||
return &(temp->r);
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
swap(
|
||||
hash_table_kernel_1<domain,range,mem_manager,compare>& item
|
||||
)
|
||||
{
|
||||
exchange(mask,item.mask);
|
||||
exchange(table,item.table);
|
||||
exchange(hash_size,item.hash_size);
|
||||
exchange(num_of_buckets,item.num_of_buckets);
|
||||
exchange(current_bucket,item.current_bucket);
|
||||
exchange(current_element,item.current_element);
|
||||
exchange(at_start_,item.at_start_);
|
||||
pool.swap(item.pool);
|
||||
ppool.swap(item.ppool);
|
||||
exchange(p,item.p);
|
||||
exchange(comp,item.comp);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// enumerable function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
bool hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
at_start (
|
||||
) const
|
||||
{
|
||||
return at_start_;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
reset (
|
||||
) const
|
||||
{
|
||||
at_start_ = true;
|
||||
current_element = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
bool hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
current_element_valid (
|
||||
) const
|
||||
{
|
||||
return (current_element != 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
const map_pair<domain,range>& hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
p.d = &(current_element->d);
|
||||
p.r = &(current_element->r);
|
||||
return p;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
map_pair<domain,range>& hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
p.d = &(current_element->d);
|
||||
p.r = &(current_element->r);
|
||||
return p;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
bool hash_table_kernel_1<domain,range,mem_manager,compare>::
|
||||
move_next (
|
||||
) const
|
||||
{
|
||||
if (at_start_)
|
||||
{
|
||||
at_start_ = false;
|
||||
// if the queue is empty then there is nothing to do
|
||||
if (hash_size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the first element in the hash table
|
||||
for (current_bucket = 0; true ; ++current_bucket)
|
||||
{
|
||||
if (table[current_bucket] != 0)
|
||||
{
|
||||
current_element = table[current_bucket];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we have already enumerated every element
|
||||
if (current_element == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the next element if it exists
|
||||
if (current_element->next != 0)
|
||||
{
|
||||
current_element = current_element->next;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find next bucket with something in it
|
||||
for (current_bucket+=1; current_bucket<num_of_buckets; ++current_bucket)
|
||||
{
|
||||
if (table[current_bucket] != 0)
|
||||
{
|
||||
// we just found the next bucket
|
||||
current_element = table[current_bucket];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// make sure we actually found another nonempty bucket
|
||||
if (current_bucket == num_of_buckets)
|
||||
{
|
||||
// we didn't find anything
|
||||
current_element = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we found another bucket
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_HASH_TABLE_KERNEl_1_
|
||||
|
||||
612
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_2.h
vendored
Normal file
612
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_2.h
vendored
Normal file
@@ -0,0 +1,612 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_HASH_TABLE_KERNEl_2_
|
||||
#define DLIB_HASH_TABLE_KERNEl_2_
|
||||
|
||||
#include "hash_table_kernel_abstract.h"
|
||||
#include "../general_hash/general_hash.h"
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../assert.h"
|
||||
#include "../serialize.h"
|
||||
#include <functional>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<domain>
|
||||
>
|
||||
class hash_table_kernel_2 : public enumerable<map_pair<domain,range> >,
|
||||
public pair_remover<domain,range>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON bst_base
|
||||
bst_base is instantiated with domain and range and
|
||||
implements binray_search_tree/binary_search_tree_kernel_abstract.h
|
||||
|
||||
INITIAL VALUE
|
||||
hash_size == 0
|
||||
table == pointer to an array of num_of_buckets bst_base objects
|
||||
num_of_buckets == the number of buckets in the hash table
|
||||
current_bucket == 0
|
||||
at_start_ == true
|
||||
|
||||
CONVENTION
|
||||
current_element_valid() == (current_bucket != 0)
|
||||
element() == current_bucket->element()
|
||||
at_start_ == at_start()
|
||||
|
||||
mask == num_of_buckets-1
|
||||
|
||||
for all integers i where &table[i] != current_bucket
|
||||
table[i].at_start() == true
|
||||
|
||||
|
||||
hash_size = size() == the number of elements in the hash_table and
|
||||
table == pointer to an array of num_of_buckets bst_base objects
|
||||
num_of_buckets == the number of buckets in the hash table and
|
||||
the elements in this hash table are stored in the bst_base objects in the
|
||||
array table
|
||||
|
||||
!*/
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef domain domain_type;
|
||||
typedef range range_type;
|
||||
typedef compare compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
explicit hash_table_kernel_2(
|
||||
unsigned long expnum
|
||||
);
|
||||
|
||||
virtual ~hash_table_kernel_2(
|
||||
)
|
||||
{ pool.deallocate_array(table); }
|
||||
|
||||
void clear(
|
||||
);
|
||||
|
||||
unsigned long count (
|
||||
const domain& item
|
||||
) const;
|
||||
|
||||
inline void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
|
||||
const range* operator[] (
|
||||
const domain& item
|
||||
) const;
|
||||
|
||||
range* operator[] (
|
||||
const domain& item
|
||||
);
|
||||
|
||||
inline void swap (
|
||||
hash_table_kernel_2& item
|
||||
);
|
||||
|
||||
// functions from the remover interface
|
||||
void remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
// functions from the enumerable interface
|
||||
inline unsigned long size (
|
||||
) const;
|
||||
|
||||
inline bool at_start (
|
||||
) const;
|
||||
|
||||
inline void reset (
|
||||
) const;
|
||||
|
||||
bool current_element_valid (
|
||||
) const;
|
||||
|
||||
inline const map_pair<domain,range>& element (
|
||||
) const;
|
||||
|
||||
inline map_pair<domain,range>& element (
|
||||
);
|
||||
|
||||
bool move_next (
|
||||
) const;
|
||||
|
||||
private:
|
||||
|
||||
// data members
|
||||
typename mem_manager::template rebind<bst_base>::other pool;
|
||||
unsigned long mask;
|
||||
unsigned long hash_size;
|
||||
unsigned long num_of_buckets;
|
||||
bst_base* table;
|
||||
general_hash<domain> hash;
|
||||
mutable bst_base* current_bucket;
|
||||
mutable bool at_start_;
|
||||
compare comp;
|
||||
|
||||
// restricted functions
|
||||
hash_table_kernel_2(hash_table_kernel_2&);
|
||||
hash_table_kernel_2& operator=(hash_table_kernel_2&);
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
inline void swap (
|
||||
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& a,
|
||||
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void deserialize (
|
||||
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.clear();
|
||||
unsigned long size;
|
||||
deserialize(size,in);
|
||||
domain d;
|
||||
range r;
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
deserialize(d,in);
|
||||
deserialize(r,in);
|
||||
item.add(d,r);
|
||||
}
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type hash_table_kernel_2");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
hash_table_kernel_2(
|
||||
unsigned long expnum
|
||||
) :
|
||||
hash_size(0),
|
||||
current_bucket(0),
|
||||
at_start_(true)
|
||||
{
|
||||
|
||||
num_of_buckets = 1;
|
||||
while (expnum != 0)
|
||||
{
|
||||
--expnum;
|
||||
num_of_buckets <<= 1;
|
||||
}
|
||||
mask = num_of_buckets-1;
|
||||
|
||||
table = pool.allocate_array(num_of_buckets);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
clear(
|
||||
)
|
||||
{
|
||||
if (hash_size != 0)
|
||||
{
|
||||
hash_size = 0;
|
||||
for (unsigned long i = 0; i < num_of_buckets; ++i)
|
||||
table[i].clear();
|
||||
}
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
unsigned long hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
size(
|
||||
) const
|
||||
{
|
||||
return hash_size;
|
||||
}
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
unsigned long hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
count(
|
||||
const domain& item
|
||||
) const
|
||||
{
|
||||
return table[hash(item)&mask].count(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
destroy(
|
||||
const domain& item
|
||||
)
|
||||
{
|
||||
table[hash(item)&mask].destroy(item);
|
||||
--hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
add(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
table[hash(d)&mask].add(d,r);
|
||||
++hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
remove(
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
table[hash(d)&mask].remove(d,d_copy,r);
|
||||
--hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
remove_any(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
unsigned long i = 0;
|
||||
while (table[i].size() == 0)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
table[i].remove_any(d,r);
|
||||
--hash_size;
|
||||
|
||||
// reset the enumerator
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
const range* hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
operator[](
|
||||
const domain& d
|
||||
) const
|
||||
{
|
||||
return table[hash(d)&mask][d];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
range* hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
operator[](
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
return table[hash(d)&mask][d];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
swap(
|
||||
hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>& item
|
||||
)
|
||||
{
|
||||
pool.swap(item.pool);
|
||||
exchange(mask,item.mask);
|
||||
exchange(hash_size,item.hash_size);
|
||||
exchange(num_of_buckets,item.num_of_buckets);
|
||||
exchange(table,item.table);
|
||||
exchange(current_bucket,item.current_bucket);
|
||||
exchange(at_start_,item.at_start_);
|
||||
exchange(comp,item.comp);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// enumerable function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
bool hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
at_start (
|
||||
) const
|
||||
{
|
||||
return at_start_;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
reset (
|
||||
) const
|
||||
{
|
||||
at_start_ = true;
|
||||
if (current_bucket != 0)
|
||||
{
|
||||
current_bucket->reset();
|
||||
current_bucket = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
bool hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
current_element_valid (
|
||||
) const
|
||||
{
|
||||
return (current_bucket != 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
const map_pair<domain,range>& hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
return current_bucket->element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
map_pair<domain,range>& hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
return current_bucket->element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
bool hash_table_kernel_2<domain,range,bst_base,mem_manager,compare>::
|
||||
move_next (
|
||||
) const
|
||||
{
|
||||
if (at_start_)
|
||||
{
|
||||
at_start_ = false;
|
||||
// if the queue is empty then there is nothing to do
|
||||
if (hash_size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the first element in the hash table
|
||||
current_bucket = table;
|
||||
while (current_bucket->size() == 0)
|
||||
{
|
||||
++current_bucket;
|
||||
}
|
||||
|
||||
current_bucket->move_next();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we have already enumerated every element
|
||||
if (current_bucket == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current_bucket->move_next())
|
||||
{
|
||||
// if there is another element in this current bucket then use that
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the next bucket
|
||||
bst_base* end = table + num_of_buckets;
|
||||
current_bucket->reset();
|
||||
|
||||
while (true)
|
||||
{
|
||||
++current_bucket;
|
||||
// if we ran out of buckets and didn't find anything
|
||||
if (current_bucket == end)
|
||||
{
|
||||
current_bucket = 0;
|
||||
return false;
|
||||
}
|
||||
if (current_bucket->size() > 0)
|
||||
{
|
||||
current_bucket->move_next();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_HASH_TABLE_KERNEl_2_
|
||||
|
||||
253
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_abstract.h
vendored
Normal file
253
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_abstract.h
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_HASH_TABLE_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_HASH_TABLE_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "../general_hash/general_hash.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
#include "../algs.h"
|
||||
#include <functional>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<domain>
|
||||
>
|
||||
class hash_table : public enumerable<map_pair<domain,range> >,
|
||||
public pair_remover<domain,range>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON domain
|
||||
domain must be comparable by compare where compare is a functor compatible with std::less and
|
||||
domain must be hashable by general_hash
|
||||
(general_hash is defined in dlib/general_hash) and
|
||||
domain must be swappable by a global swap() and
|
||||
domain must have a default constructor
|
||||
|
||||
REQUIREMENTS ON range
|
||||
range must be swappable by a global swap() and
|
||||
range must have a default constructor
|
||||
|
||||
REQUIREMENTS ON mem_manager
|
||||
must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
||||
mem_manager::type can be set to anything.
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
swap(), count(), and operator[] functions do
|
||||
not invalidate pointers or references to internal data.
|
||||
All other functions have no such guarantee.
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
|
||||
ENUMERATION ORDER
|
||||
No order is specified. Only that each element will be visited once
|
||||
and only once.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
hash_table contains items of type T
|
||||
|
||||
This object represents a data dictionary that is built on top of some
|
||||
kind of hash table. The number of buckets in the hash table is
|
||||
defined by the constructor argument and is some power of 2.
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
|
||||
NOTE:
|
||||
definition of equivalent:
|
||||
a is equivalent to b if
|
||||
a < b == false and
|
||||
b < a == false
|
||||
!*/
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef domain domain_type;
|
||||
typedef range range_type;
|
||||
typedef compare compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
explicit hash_table(
|
||||
unsigned long expnum
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- expnum < 32
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
- #*this will use 2^expnum as a suggestion for the initial number
|
||||
of buckets.
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
!*/
|
||||
|
||||
virtual ~hash_table(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all memory associated with *this has been released
|
||||
!*/
|
||||
|
||||
void clear(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this has its initial value
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
if this exception is thrown then *this is unusable
|
||||
until clear() is called and succeeds
|
||||
!*/
|
||||
|
||||
unsigned long count (
|
||||
const domain& d
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements in the domain of *this that are
|
||||
equivalent to d
|
||||
!*/
|
||||
|
||||
void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- &d != &r (i.e. d and r cannot be the same variable)
|
||||
ensures
|
||||
- adds a mapping between d and r to *this
|
||||
- if (count(d) == 0) then
|
||||
- #*(*this)[d] == r
|
||||
- else
|
||||
- #(*this)[d] != 0
|
||||
- #d and #r have initial values for their types
|
||||
- #count(d) == count(d) + 1
|
||||
- #at_start() == true
|
||||
- #size() == size() + 1
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
if add() throws then it has no effect
|
||||
!*/
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- (*this)[d] != 0
|
||||
- &d != &r (i.e. d and r cannot be the same variable)
|
||||
- &d != &d_copy (i.e. d and d_copy cannot be the same variable)
|
||||
- &r != &d_copy (i.e. r and d_copy cannot be the same variable)
|
||||
ensures
|
||||
- some element in the domain of *this that is equivalent to d has
|
||||
been removed and swapped into #d_copy. Additionally, its
|
||||
associated range element has been removed and swapped into #r.
|
||||
- #count(d) = count(d) - 1
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- (*this)[d] != 0
|
||||
ensures
|
||||
- an element in the domain of *this equivalent to d has been removed.
|
||||
The element in the range of *this associated with d has also been
|
||||
removed.
|
||||
- #count(d) == count(d) - 1
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
const range* operator[] (
|
||||
const domain& d
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (there is an element in the domain equivalent to d) then
|
||||
- returns a pointer to an element in the range of *this that
|
||||
is associated with an element in the domain of *this
|
||||
equivalent to d.
|
||||
- else
|
||||
- returns 0
|
||||
!*/
|
||||
|
||||
range* operator[] (
|
||||
const domain& d
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (there is an element in the domain equivalent to d) then
|
||||
- returns a pointer to an element in the range of *this that
|
||||
is associated with an element in the domain of *this
|
||||
equivalent to d.
|
||||
- else
|
||||
- returns 0
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
hash_table& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
hash_table(hash_table&);
|
||||
hash_table& operator=(hash_table&);
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
hash_table<domain,range,mem_manager>& a,
|
||||
hash_table<domain,range,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
hash_table<domain,range,mem_manager>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_HASH_TABLE_KERNEl_ABSTRACT_
|
||||
|
||||
194
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_c.h
vendored
Normal file
194
lib/3rdParty/dlib/include/dlib/hash_table/hash_table_kernel_c.h
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_HASH_TABLE_KERNEl_C_
|
||||
#define DLIB_HASH_TABLE_KERNEl_C_
|
||||
|
||||
#include "hash_table_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "../assert.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename ht_base
|
||||
>
|
||||
class hash_table_kernel_c : public ht_base
|
||||
{
|
||||
typedef typename ht_base::domain_type domain;
|
||||
typedef typename ht_base::range_type range;
|
||||
public:
|
||||
|
||||
explicit hash_table_kernel_c (
|
||||
unsigned long expnum
|
||||
) :
|
||||
ht_base(expnum)
|
||||
{
|
||||
DLIB_CASSERT(expnum < 32,
|
||||
"\thash_table::hash_table(unsigned long)"
|
||||
<< "\n\tyou can't set expnum >= 32"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\texpnum: " << expnum
|
||||
);
|
||||
}
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
|
||||
void remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
const map_pair<domain,range>& element (
|
||||
) const
|
||||
{
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tconst map_pair<domain,range>& hash_table::element() const"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return ht_base::element();
|
||||
}
|
||||
|
||||
map_pair<domain,range>& element (
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tmap_pair<domain,range>& hash_table::element()"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return ht_base::element();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <
|
||||
typename ht_base
|
||||
>
|
||||
inline void swap (
|
||||
hash_table_kernel_c<ht_base>& a,
|
||||
hash_table_kernel_c<ht_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename ht_base
|
||||
>
|
||||
void hash_table_kernel_c<ht_base>::
|
||||
remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->operator[](d) != 0 &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&d_copy)) &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&r)) &&
|
||||
(static_cast<const void*>(&r) != static_cast<void*>(&d_copy)),
|
||||
"\tvoid binary_search_tree::remove"
|
||||
<< "\n\tthe element must be in the table for it to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
<< "\n\t&d_copy: " << &d_copy
|
||||
<< "\n\t&r: " << &r
|
||||
);
|
||||
|
||||
ht_base::remove(d,d_copy,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename ht_base
|
||||
>
|
||||
void hash_table_kernel_c<ht_base>::
|
||||
add(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT( static_cast<const void*>(&d) != static_cast<void*>(&r),
|
||||
"\tvoid binary_search_tree::add"
|
||||
<< "\n\tyou can't call add() and give the same object to both arguments."
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
<< "\n\t&r: " << &r
|
||||
<< "\n\tsize(): " << this->size()
|
||||
);
|
||||
|
||||
ht_base::add(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename ht_base
|
||||
>
|
||||
void hash_table_kernel_c<ht_base>::
|
||||
destroy(
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT((*this)[d] != 0,
|
||||
"\tvoid hash_table::destroy"
|
||||
<< "\n\tthe element must be in the table for it to be destroyed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
);
|
||||
|
||||
ht_base::destroy(d);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename ht_base
|
||||
>
|
||||
void hash_table_kernel_c<ht_base>::
|
||||
remove_any(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->size() != 0 &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&r)),
|
||||
"\tvoid hash_table::remove_any"
|
||||
<< "\n\ttable must not be empty if something is going to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
<< "\n\t&r: " << &r
|
||||
);
|
||||
|
||||
ht_base::remove_any(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_HASH_TABLE_KERNEl_C_
|
||||
|
||||
Reference in New Issue
Block a user