mirror of https://github.com/CGAL/cgal
194 lines
5.9 KiB
C++
194 lines
5.9 KiB
C++
// ============================================================================
|
|
//
|
|
// Copyright (c) 1997-2000 The CGAL Consortium
|
|
//
|
|
// This software and related documentation is part of an INTERNAL release
|
|
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
|
// intended for general use.
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
//
|
|
// release : $CGAL_Revision$
|
|
// release_date : $CGAL_Date$
|
|
//
|
|
// file : include/CGAL/Hash_map.h
|
|
// package : Nef_2
|
|
// chapter : Nef Polyhedra
|
|
//
|
|
// revision : $Revision$
|
|
// revision_date : $Date$
|
|
//
|
|
// author(s) : Michael Seel <seel@mpi-sb.mpg.de>
|
|
// maintainer : Michael Seel <seel@mpi-sb.mpg.de>
|
|
// coordinator : Michael Seel <seel@mpi-sb.mpg.de>
|
|
//
|
|
// implementation: Hashing Map by chained hashing
|
|
// ============================================================================
|
|
#ifndef CGAL_HASH_MAP_H
|
|
#define CGAL_HASH_MAP_H
|
|
|
|
#include <CGAL/basic.h>
|
|
#include <CGAL/Tools/chained_map.h>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
struct Handle_index {
|
|
template <class H>
|
|
size_t operator() (const H& h) const
|
|
{ return size_t(&*h); }
|
|
};
|
|
|
|
struct VoidPtr_index {
|
|
size_t operator() (void* p) const
|
|
{ return size_t(p); }
|
|
};
|
|
|
|
|
|
/*{\Manpage {Hash_map} {D,E,I}
|
|
{Data Association for uniquely indexed objects}{M}}*/
|
|
|
|
template <class D, class E, class I=Handle_index>
|
|
class Hash_map : private CGALi::chained_map<E> {
|
|
|
|
/*{\Mdefinition An instance |\Mvar| of the parameterized data type
|
|
|\Mname| is an injective mapping from the set of indexed objects of
|
|
type |D|, called the domain type of |\Mvar|, to the set of variables
|
|
of data type |E|, called the element type of |\Mvar|.
|
|
|
|
An object |i| of the index data type |I| delivers a unique integer
|
|
index |i(d)| for objects $d \in D$.
|
|
|
|
We use |M(d)| to denote the variable associated to |d|. All variables
|
|
are initialized to |default_element|, an element of |E| that is
|
|
specified in the definition of |M|. A subset of |D| is designated as
|
|
the domain of |M|. Elements are added to |dom(M)| by the array
|
|
operator; however, the domain may also contain indices for which the
|
|
access operator was never executed.
|
|
|
|
There's one default index schemes already defined: |Handle_index|. It
|
|
allows to index all handles, iterators and circulators. Thus
|
|
|\Mtype<D,E>| can be used for any handle or iterator type |D| (handles
|
|
are static iterators).}*/
|
|
|
|
typedef Hash_map<D,E,I> Self;
|
|
typedef CGALi::chained_map<E> Base;
|
|
I _index;
|
|
|
|
public:
|
|
/*{\Mtypes 5}*/
|
|
|
|
typedef typename Base::item item;
|
|
/*{\Mtypemember the item type.}*/
|
|
|
|
typedef D domain_type;
|
|
/*{\Mtypemember the domain type.}*/
|
|
|
|
typedef E element_type;
|
|
/*{\Mtypemember the element type.}*/
|
|
|
|
typedef I index_type;
|
|
/*{\Mtypemember the index type.}*/
|
|
|
|
class element_iterator {
|
|
/*{\Mtypemember a forward iterator over all element entries.}*/
|
|
item it; Self* pM;
|
|
public:
|
|
typedef E value_type;
|
|
typedef ptrdiff_t difference_type;
|
|
typedef E* pointer;
|
|
typedef E& reference;
|
|
typedef std::forward_iterator_tag iterator_category;
|
|
|
|
element_iterator(item p, Self* pMi) : it(p), pM(pMi) {}
|
|
element_iterator() : it(0), pM(0) {}
|
|
bool operator==( const element_iterator& i) const
|
|
{ return ( it == i.it); }
|
|
bool operator!=( const element_iterator& i) const
|
|
{ return !(*this == i); }
|
|
const E& operator*() const { return pM->inf(it); }
|
|
const E* operator->() const { return &(pM->inf(it)); }
|
|
element_iterator& operator++()
|
|
{ it=pM->next_item(it); return *this; }
|
|
element_iterator operator++(int)
|
|
{ element_iterator tmp=*this; ++*this; return tmp; }
|
|
|
|
operator item() const { return it; }
|
|
};
|
|
|
|
protected:
|
|
friend class element_iterator;
|
|
|
|
item next_item(item it) const
|
|
{ return Base::next_item(it); }
|
|
const E& inf(item it) const
|
|
{ return Base::inf(it); }
|
|
public:
|
|
|
|
/*{\Mcreation 4}*/
|
|
|
|
Hash_map() { Base::xdef() = E(); }
|
|
/*{\Mcreate creates an injective function $m$ from $D$ to the set of unused
|
|
variables of type $E$, sets |default_value| to the default value of type |E|
|
|
(if |E| has no default value then |default_value| is set to an unspecified
|
|
element of |E|), and initializes $M$ with $m$.}*/
|
|
|
|
Hash_map(const E& def) { Base::xdef() = def; }
|
|
/*{\Mcreate creates an injective function $m$ from $D$ to the set of unused
|
|
variables of type $E$, sets |default_value| to |def|, and initializes $M$ with
|
|
$m$.}*/
|
|
|
|
Hash_map(const E& def, int table_sz) : Base(table_sz)
|
|
{ Base::xdef() = def; }
|
|
|
|
Hash_map<D,E,I>& operator=(const Hash_map<D,E,I>& M)
|
|
{ Base::operator=((Base&)M);
|
|
return *this;
|
|
}
|
|
Hash_map(const Hash_map<D,E,I>& M) : Base((Base&)M) {}
|
|
~Hash_map() { clear_entries(); }
|
|
|
|
/*{\Moperations 2 4.5 }*/
|
|
|
|
void clear() { Base::clear(); }
|
|
/*{\Mop makes |\Mvar| empty.}*/
|
|
void clear(const E& def) { Base::clear(); Base::xdef() = def; }
|
|
/*{\Mop makes |\Mvar| empty and sets |default_value| to |x|. }*/
|
|
|
|
bool is_defined(const D& d) const { return Base::lookup(_index(d)) != 0; }
|
|
/*{\Mop returns true if $d \in |dom(M)|$.}*/
|
|
|
|
const E& operator[](const D& d) const
|
|
{ item p = Base::lookup(_index(d));
|
|
if ( p != 0 ) return Base::inf(p);
|
|
else return Base::cxdef();
|
|
}
|
|
|
|
E& operator[](const D& d)
|
|
/*{\Marrop returns the variable $M(d)$ and adds $d$ to |dom(M)|. If |M|
|
|
is a const-object then |M(d)| is read-only and $d$ is not added to
|
|
|dom(M)|.}*/
|
|
{ return Base::access(_index(d)); }
|
|
|
|
element_iterator begin()
|
|
/*{\Mop returns the element iterator pointing to the first element
|
|
stored.}*/
|
|
{ return element_iterator(Base::first_item(),this); }
|
|
|
|
element_iterator end()
|
|
/*{\Mop returns the element iterator pointing beyond the last element
|
|
stored.}*/
|
|
{ return element_iterator();}
|
|
|
|
void statistics() const { Base::statistics(); }
|
|
|
|
};
|
|
|
|
/*{\Mimplementation |Hash_maps| are implemented via chained hashing
|
|
scheme. Access operations |M[i]| take expected time $O(1)$.
|
|
The design was derived from the LEDA type map. }*/
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif // CGAL_HASH_MAP_H
|
|
|