|
|
@ -133,6 +133,93 @@ namespace DJVU {
|
|
|
|
#$Id: GContainer.h,v 1.15 2004/05/13 15:16:34 leonb Exp $# */
|
|
|
|
#$Id: GContainer.h,v 1.15 2004/05/13 15:16:34 leonb Exp $# */
|
|
|
|
//@{
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
|
|
|
// HASH FUNCTIONS
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @name Hash functions
|
|
|
|
|
|
|
|
These functions let you use template class \Ref{GMap} with the
|
|
|
|
|
|
|
|
corresponding elementary types. The returned hash code may be reduced to
|
|
|
|
|
|
|
|
an arbitrary range by computing its remainder modulo the upper bound of
|
|
|
|
|
|
|
|
the range.
|
|
|
|
|
|
|
|
@memo Hash functions for elementary types. */
|
|
|
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (unsigned int). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const unsigned int & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (int). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const int & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned int)x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (long). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const long & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned int)x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (unsigned long). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const unsigned long & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned int)x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (void *). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(void * const & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned long) x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (const void *). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const void * const & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned long) x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (float). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const float & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// optimizer will get rid of unnecessary code
|
|
|
|
|
|
|
|
unsigned int *addr = (unsigned int*)&x;
|
|
|
|
|
|
|
|
if (sizeof(float)<2*sizeof(unsigned int))
|
|
|
|
|
|
|
|
return addr[0];
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return addr[0]^addr[1];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (double). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const double & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// optimizer will get rid of unnecessary code
|
|
|
|
|
|
|
|
unsigned int *addr = (unsigned int*)&x;
|
|
|
|
|
|
|
|
if (sizeof(double)<2*sizeof(unsigned int))
|
|
|
|
|
|
|
|
return addr[0];
|
|
|
|
|
|
|
|
else if (sizeof(double)<4*sizeof(unsigned int))
|
|
|
|
|
|
|
|
return addr[0]^addr[1];
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return addr[0]^addr[1]^addr[2]^addr[3];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ------------ THE END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
// ------------------------------------------------------------
|
|
|
@ -887,21 +974,21 @@ public:
|
|
|
|
/** Inserts an element after the last element of the list.
|
|
|
|
/** Inserts an element after the last element of the list.
|
|
|
|
The new element is initialized with a copy of argument #elt#. */
|
|
|
|
The new element is initialized with a copy of argument #elt#. */
|
|
|
|
void append(const TYPE &elt)
|
|
|
|
void append(const TYPE &elt)
|
|
|
|
{ GListImpl<TI>::append(newnode((const TI&)elt)); }
|
|
|
|
{ GListImpl<TI>::append(this->newnode((const TI&)elt)); }
|
|
|
|
/** Inserts an element before the first element of the list.
|
|
|
|
/** Inserts an element before the first element of the list.
|
|
|
|
The new element is initialized with a copy of argument #elt#. */
|
|
|
|
The new element is initialized with a copy of argument #elt#. */
|
|
|
|
void prepend(const TYPE &elt)
|
|
|
|
void prepend(const TYPE &elt)
|
|
|
|
{ GListImpl<TI>::prepend(newnode((const TI&)elt)); }
|
|
|
|
{ GListImpl<TI>::prepend(this->newnode((const TI&)elt)); }
|
|
|
|
/** Inserts a new element after the list element at position #pos#. When
|
|
|
|
/** Inserts a new element after the list element at position #pos#. When
|
|
|
|
position #pos# is null the element is inserted at the beginning of the
|
|
|
|
position #pos# is null the element is inserted at the beginning of the
|
|
|
|
list. The new element is initialized with a copy of #elt#. */
|
|
|
|
list. The new element is initialized with a copy of #elt#. */
|
|
|
|
void insert_after(GPosition pos, const TYPE &elt)
|
|
|
|
void insert_after(GPosition pos, const TYPE &elt)
|
|
|
|
{ GListImpl<TI>::insert_after(pos, newnode((const TI&)elt)); }
|
|
|
|
{ GListImpl<TI>::insert_after(pos, this->newnode((const TI&)elt)); }
|
|
|
|
/** Inserts a new element before the list element at position #pos#. When
|
|
|
|
/** Inserts a new element before the list element at position #pos#. When
|
|
|
|
position #pos# is null the element is inserted at the end of the
|
|
|
|
position #pos# is null the element is inserted at the end of the
|
|
|
|
list. The new element is initialized with a copy of #elt#. */
|
|
|
|
list. The new element is initialized with a copy of #elt#. */
|
|
|
|
void insert_before(GPosition pos, const TYPE &elt)
|
|
|
|
void insert_before(GPosition pos, const TYPE &elt)
|
|
|
|
{ GListImpl<TI>::insert_before(pos, newnode((const TI&)elt)); }
|
|
|
|
{ GListImpl<TI>::insert_before(pos, this->newnode((const TI&)elt)); }
|
|
|
|
/** Inserts an element of another list into this list. This function
|
|
|
|
/** Inserts an element of another list into this list. This function
|
|
|
|
removes the element at position #frompos# in list #frompos#, inserts it
|
|
|
|
removes the element at position #frompos# in list #frompos#, inserts it
|
|
|
|
in the current list before the element at position #pos#, and advances
|
|
|
|
in the current list before the element at position #pos#, and advances
|
|
|
@ -1039,7 +1126,7 @@ public:
|
|
|
|
GPosition contains(const K &key) const
|
|
|
|
GPosition contains(const K &key) const
|
|
|
|
{ return GPosition( get(key), (void*)this); }
|
|
|
|
{ return GPosition( get(key), (void*)this); }
|
|
|
|
void del(const K &key)
|
|
|
|
void del(const K &key)
|
|
|
|
{ deletenode(get(key)); }
|
|
|
|
{ this->deletenode(this->get(key)); }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template<class K>
|
|
|
|
template<class K>
|
|
|
@ -1067,7 +1154,7 @@ GSetImpl<K>::get(const K &key) const
|
|
|
|
template<class K> GCONT HNode *
|
|
|
|
template<class K> GCONT HNode *
|
|
|
|
GSetImpl<K>::get_or_throw(const K &key) const
|
|
|
|
GSetImpl<K>::get_or_throw(const K &key) const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
HNode *m = get(key);
|
|
|
|
HNode *m = this->get(key);
|
|
|
|
if (!m)
|
|
|
|
if (!m)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
G_THROW( ERR_MSG("GContainer.cannot_add") );
|
|
|
|
G_THROW( ERR_MSG("GContainer.cannot_add") );
|
|
|
@ -1078,14 +1165,14 @@ GSetImpl<K>::get_or_throw(const K &key) const
|
|
|
|
template<class K> inline GCONT HNode *
|
|
|
|
template<class K> inline GCONT HNode *
|
|
|
|
GSetImpl<K>::get_or_throw(const K &key) const
|
|
|
|
GSetImpl<K>::get_or_throw(const K &key) const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return get(key);
|
|
|
|
return this->get(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
template<class K> GCONT HNode *
|
|
|
|
template<class K> GCONT HNode *
|
|
|
|
GSetImpl<K>::get_or_create(const K &key)
|
|
|
|
GSetImpl<K>::get_or_create(const K &key)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
HNode *m = get(key);
|
|
|
|
HNode *m = this->get(key);
|
|
|
|
if (m) return m;
|
|
|
|
if (m) return m;
|
|
|
|
SNode *n = (SNode*) operator new (sizeof(SNode));
|
|
|
|
SNode *n = (SNode*) operator new (sizeof(SNode));
|
|
|
|
#if GCONTAINER_ZERO_FILL
|
|
|
|
#if GCONTAINER_ZERO_FILL
|
|
|
@ -1093,7 +1180,7 @@ GSetImpl<K>::get_or_create(const K &key)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
new ((void*)&(n->key)) K ( key );
|
|
|
|
new ((void*)&(n->key)) K ( key );
|
|
|
|
n->hashcode = hash((const K&)(n->key));
|
|
|
|
n->hashcode = hash((const K&)(n->key));
|
|
|
|
installnode(n);
|
|
|
|
this->installnode(n);
|
|
|
|
return n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1122,7 +1209,7 @@ GMapImpl<K,TI>::GMapImpl(const GCONT Traits &traits)
|
|
|
|
template<class K, class TI> GCONT HNode *
|
|
|
|
template<class K, class TI> GCONT HNode *
|
|
|
|
GMapImpl<K,TI>::get_or_create(const K &key)
|
|
|
|
GMapImpl<K,TI>::get_or_create(const K &key)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
GCONT HNode *m = get(key);
|
|
|
|
GCONT HNode *m = this->get(key);
|
|
|
|
if (m) return m;
|
|
|
|
if (m) return m;
|
|
|
|
MNode *n = (MNode*) operator new (sizeof(MNode));
|
|
|
|
MNode *n = (MNode*) operator new (sizeof(MNode));
|
|
|
|
#if GCONTAINER_ZERO_FILL
|
|
|
|
#if GCONTAINER_ZERO_FILL
|
|
|
@ -1131,7 +1218,7 @@ GMapImpl<K,TI>::get_or_create(const K &key)
|
|
|
|
new ((void*)&(n->key)) K (key);
|
|
|
|
new ((void*)&(n->key)) K (key);
|
|
|
|
new ((void*)&(n->val)) TI ();
|
|
|
|
new ((void*)&(n->val)) TI ();
|
|
|
|
n->hashcode = hash((const K&)(n->key));
|
|
|
|
n->hashcode = hash((const K&)(n->key));
|
|
|
|
installnode(n);
|
|
|
|
this->installnode(n);
|
|
|
|
return n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -1197,13 +1284,13 @@ public:
|
|
|
|
contains key #key#. This variant of #operator[]# is necessary when
|
|
|
|
contains key #key#. This variant of #operator[]# is necessary when
|
|
|
|
dealing with a #const GMAP<KTYPE,VTYPE>#. */
|
|
|
|
dealing with a #const GMAP<KTYPE,VTYPE>#. */
|
|
|
|
const VTYPE& operator[](const KTYPE &key) const
|
|
|
|
const VTYPE& operator[](const KTYPE &key) const
|
|
|
|
{ return (const VTYPE&)(((const typename GMapImpl<KTYPE,TI>::MNode*)(get_or_throw(key)))->val); }
|
|
|
|
{ return (const VTYPE&)(((const typename GMapImpl<KTYPE,TI>::MNode*)(this->get_or_throw(key)))->val); }
|
|
|
|
/** Returns a reference to the value of the map entry for key #key#. This
|
|
|
|
/** Returns a reference to the value of the map entry for key #key#. This
|
|
|
|
reference can be used for both reading (as "#a[n]#") and modifying (as
|
|
|
|
reference can be used for both reading (as "#a[n]#") and modifying (as
|
|
|
|
"#a[n]=v#"). If there is no entry for key #key#, a new entry is created
|
|
|
|
"#a[n]=v#"). If there is no entry for key #key#, a new entry is created
|
|
|
|
for that key with the null constructor #VTYPE::VTYPE()#. */
|
|
|
|
for that key with the null constructor #VTYPE::VTYPE()#. */
|
|
|
|
VTYPE& operator[](const KTYPE &key)
|
|
|
|
VTYPE& operator[](const KTYPE &key)
|
|
|
|
{ return (VTYPE&)(((typename GMapImpl<KTYPE,TI>::MNode*)(get_or_create(key)))->val); }
|
|
|
|
{ return (VTYPE&)(((typename GMapImpl<KTYPE,TI>::MNode*)(this->get_or_create(key)))->val); }
|
|
|
|
/** Destroys the map entry for position #pos#.
|
|
|
|
/** Destroys the map entry for position #pos#.
|
|
|
|
Nothing is done if position #pos# is not a valid position. */
|
|
|
|
Nothing is done if position #pos# is not a valid position. */
|
|
|
|
void del(GPosition &pos)
|
|
|
|
void del(GPosition &pos)
|
|
|
@ -1266,95 +1353,6 @@ public:
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
|
|
|
// HASH FUNCTIONS
|
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @name Hash functions
|
|
|
|
|
|
|
|
These functions let you use template class \Ref{GMap} with the
|
|
|
|
|
|
|
|
corresponding elementary types. The returned hash code may be reduced to
|
|
|
|
|
|
|
|
an arbitrary range by computing its remainder modulo the upper bound of
|
|
|
|
|
|
|
|
the range.
|
|
|
|
|
|
|
|
@memo Hash functions for elementary types. */
|
|
|
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (unsigned int). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const unsigned int & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (int). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const int & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned int)x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (long). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const long & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned int)x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (unsigned long). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const unsigned long & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned int)x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (void *). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(void * const & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned long) x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (const void *). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const void * const & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return (unsigned long) x;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (float). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const float & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// optimizer will get rid of unnecessary code
|
|
|
|
|
|
|
|
unsigned int *addr = (unsigned int*)&x;
|
|
|
|
|
|
|
|
if (sizeof(float)<2*sizeof(unsigned int))
|
|
|
|
|
|
|
|
return addr[0];
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return addr[0]^addr[1];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Hashing function (double). */
|
|
|
|
|
|
|
|
static inline unsigned int
|
|
|
|
|
|
|
|
hash(const double & x)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// optimizer will get rid of unnecessary code
|
|
|
|
|
|
|
|
unsigned int *addr = (unsigned int*)&x;
|
|
|
|
|
|
|
|
if (sizeof(double)<2*sizeof(unsigned int))
|
|
|
|
|
|
|
|
return addr[0];
|
|
|
|
|
|
|
|
else if (sizeof(double)<4*sizeof(unsigned int))
|
|
|
|
|
|
|
|
return addr[0]^addr[1];
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return addr[0]^addr[1]^addr[2]^addr[3];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ------------ THE END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_NAMESPACES
|
|
|
|
#ifdef HAVE_NAMESPACES
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# ifndef NOT_USING_DJVU_NAMESPACE
|
|
|
|
# ifndef NOT_USING_DJVU_NAMESPACE
|
|
|
|