201 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Map.h --
 | |
|  *	Keyed map.
 | |
|  *
 | |
|  * Map<KeyT,DataT> is template a container class that implement a mapping
 | |
|  * from a * set of _keys_ (type KeyT) to data items or _values_ (type DataT).
 | |
|  * This is an abstract class -- it is implemented only in terms of 
 | |
|  * more specific subclasses, such as lists, arrays, hash tables, etc.
 | |
|  * All of these present the followig interface.
 | |
|  *
 | |
|  * DataT *find(KeyT key, Boolean &foundP)
 | |
|  *	Returns a pointer to the data item found under key, or null of
 | |
|  *	the key is not in the Map.
 | |
|  *	With this and the other functions, the foundP argument is optional
 | |
|  *	and returns whether the key was found.
 | |
|  *
 | |
|  * KeyT getInternalKey(KeyT key, Boolean &foundP)
 | |
|  *	Returns the internal memory allocated for key, if it exists
 | |
|  *	(or else zero data).  This can be used to share key memory
 | |
|  *	between several data structures, but the keys (in case they are
 | |
|  *	referenced by pointers) must not be modified.  Also note that
 | |
|  *	keys returned invalid as soon as the corresponding entry in
 | |
|  *	the Map (or the entire Map) is deleted.
 | |
|  *
 | |
|  * DataT *insert(KeyT key, Boolean &foundP)
 | |
|  *	Returns a pointer to the data item for key, creating a new
 | |
|  *	entry if necessary (indicated by foundP == false).
 | |
|  *	New data items are zero-initialized.
 | |
|  *
 | |
|  * DataT *remove(KeyT key, Boolean &foundP)
 | |
|  *	Deletes the entry associated with key from the Map, returning
 | |
|  *	a pointer to the previously stored value, if any.
 | |
|  *
 | |
|  * void clear(unsigned int size)
 | |
|  *	Removes all entries from table.  The optional size argument
 | |
|  *	resets the allocated number of entries in the Map.
 | |
|  *
 | |
|  * unsigned int numEntries()
 | |
|  *	Returns the current number of keys (i.e., entries) in the Map.
 | |
|  *
 | |
|  * The DataT * pointers returned by find(), insert() and remove() are
 | |
|  * valid only until the next operation on the Map object.  It is left
 | |
|  * to the user to assign actual values by dereferencing the pointers 
 | |
|  * returned.  The main benefit is that only one key lookup is needed
 | |
|  * for a find-and-change operation.
 | |
|  *
 | |
|  * Copyright (c) 1995-2006 SRI International.  All Rights Reserved.
 | |
|  *
 | |
|  * @(#)$Header: /home/srilm/CVS/srilm/dstruct/src/Map.h,v 1.27 2017/01/19 20:49:30 victor Exp $
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifndef _Map_h_
 | |
| #define _Map_h_
 | |
| 
 | |
| #include <stddef.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <math.h>
 | |
| #if !defined(_MSC_VER) && !defined(WIN32)
 | |
| #include <sys/param.h>
 | |
| #endif
 | |
| 
 | |
| #include "Boolean.h"
 | |
| #include "MemStats.h"
 | |
| 
 | |
| #ifndef NBBY
 | |
| #define NBBY	8
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * _Map is a non-template parent class to all classes Map<KeyT,DataT>.
 | |
|  * It serves only to collect certain global variables shared by all
 | |
|  * Map objects.
 | |
|  */
 | |
| class _Map
 | |
| {
 | |
| public:
 | |
|     static unsigned int initialSize;	/* default initial size */
 | |
|     static float growSize;		/* factor used in enlarging
 | |
| 					 * a Map on demand */
 | |
| };
 | |
| 
 | |
| template <class KeyT, class DataT>
 | |
| class MapEntry
 | |
| {
 | |
| public:
 | |
|     DataT value;
 | |
|     KeyT key;
 | |
| };
 | |
| 
 | |
| template <class KeyT, class DataT>
 | |
| class Map : public _Map
 | |
| {
 | |
| public:
 | |
|     virtual DataT *find(KeyT key, Boolean &foundP) const = 0;
 | |
| 					/* key lookup -- returns a
 | |
| 					 * zero object and sets foundP =
 | |
| 					 * false if key is not found */
 | |
|     virtual KeyT getInternalKey(KeyT key, Boolean &foundP) const = 0;
 | |
| 					/* return the internalized key
 | |
| 					 * for an entry -- use with caution */
 | |
|     virtual DataT *insert(KeyT key, Boolean &foundP) = 0;
 | |
| 					/* create or change a value */
 | |
|     virtual DataT *remove(KeyT key, Boolean &foundP) = 0;
 | |
| 					/* delete an entry ("delete" is
 | |
| 					 * a reserved word) */
 | |
|     virtual void clear(unsigned int size) = 0;
 | |
| 					/* remove all entries */
 | |
|     virtual unsigned int numEntries() const = 0;
 | |
| 					/* number of entries in Map */
 | |
| 
 | |
|     virtual void memStats(MemStats &stats) const = 0;
 | |
| 					/* compute memory stats */
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Functions to manage key memory
 | |
|  *
 | |
|  * When Map entries are created a private copy of the key is created
 | |
|  * to save it from user modification.  This memory is returned when
 | |
|  * the entry is removed.
 | |
|  * An implementation uses Map_copyKey() and Map_freeKey() to save and
 | |
|  * free key memory, respectively.  The general template for these
 | |
|  * assumes that the key is passed by value (i.e., a scalar or struct). 
 | |
|  * There are also specialized implementations for string (char *)
 | |
|  * keys. For other pointer types the user is supposed to define 
 | |
|  * additional specializations before instatiating the Map class.
 | |
|  */
 | |
| template <class KeyT>
 | |
|    inline KeyT Map_copyKey(KeyT key) { return key; }
 | |
| template <class KeyT>
 | |
|   inline void Map_freeKey(KeyT key) {};
 | |
| 
 | |
| /* 
 | |
|  * String keys need to be copied
 | |
|  */
 | |
| inline const char *Map_copyKey(const char *key) { return strdup(key); }
 | |
| inline void Map_freeKey(const char *key) { free((void *)key); }
 | |
| 
 | |
| /*
 | |
|  * Non-key values
 | |
|  *
 | |
|  * Map implementations may make use of a distinguished value of KeyT
 | |
|  * for their own purposes (the 'non-key').  This value cannot be used by
 | |
|  * clients of the Map class.  Implementations are supposed to catch attempts
 | |
|  * to use this value.
 | |
|  *
 | |
|  * void Map_noKey(KeyT &key) sets key to the distinguished value.
 | |
|  * Boolean Map_noKeyP(KeyT key) checks for it.
 | |
|  *
 | |
|  * The template and specializations below cover the most common cases.
 | |
|  * Others need to be defined by the user.
 | |
|  */
 | |
| template <class KeyT>
 | |
|   inline void Map_noKey(const KeyT *&key) { key = 0; }
 | |
| template <class KeyT>
 | |
|   inline Boolean Map_noKeyP(const KeyT *key) { return key == 0; }
 | |
| 
 | |
| /*
 | |
|  * Signed integers use the smallest negative value as the non-key
 | |
|  */
 | |
| const short ShortNokeyValue = (short)(1u<<(sizeof(short)*NBBY-1));
 | |
| const int IntNokeyValue = (int)(1u<<(sizeof(int)*NBBY-1));
 | |
| const long LongNokeyValue = (long)(1uL<<(sizeof(long)*NBBY-1));
 | |
| 
 | |
| inline void Map_noKey(int &key) { key = IntNokeyValue; }
 | |
| inline Boolean Map_noKeyP(int key) { return key == IntNokeyValue; }
 | |
| inline void Map_noKey(short int &key) { key = ShortNokeyValue; }
 | |
| inline Boolean Map_noKeyP(short int key) { return key == ShortNokeyValue; }
 | |
| inline void Map_noKey(long int &key) { key = LongNokeyValue; }
 | |
| inline Boolean Map_noKeyP(long int key) { return key == LongNokeyValue; }
 | |
| 
 | |
| /*
 | |
|  * Unsigned integers use the largest value as the non-key
 | |
|  */
 | |
| const short unsigned UShortNokeyValue = ~(short unsigned)0;
 | |
| const unsigned UIntNokeyValue = ~(unsigned)0;
 | |
| const long unsigned ULongNokeyValue = ~(long unsigned)0;
 | |
| const long long unsigned ULongLongNokeyValue = ~(long long unsigned)0;
 | |
| 
 | |
| inline void Map_noKey(unsigned &key) { key = UIntNokeyValue; }
 | |
| inline Boolean Map_noKeyP(unsigned key) { return key == UIntNokeyValue; }
 | |
| inline void Map_noKey(short unsigned &key) { key = UShortNokeyValue; }
 | |
| inline Boolean Map_noKeyP(short unsigned key) { return key == UShortNokeyValue; }
 | |
| inline void Map_noKey(long unsigned &key) { key = ULongNokeyValue; }
 | |
| inline Boolean Map_noKeyP(long unsigned key) { return key == ULongNokeyValue; }
 | |
| inline void Map_noKey(long long unsigned &key) { key = ULongLongNokeyValue; }
 | |
| inline Boolean Map_noKeyP(long long unsigned key) { return key == ULongLongNokeyValue; }
 | |
| 
 | |
| /*
 | |
|  * Floats use HUGE_VAL as the non-key
 | |
|  */
 | |
| inline void Map_noKey(float &key) { key = HUGE_VAL; }
 | |
| inline Boolean Map_noKeyP(float key) { return key == HUGE_VAL; }
 | |
| inline void Map_noKey(double &key) { key = HUGE_VAL; }
 | |
| inline Boolean Map_noKeyP(double key) { return key == HUGE_VAL; }
 | |
| 
 | |
| #endif /* _Map_h_ */
 | |
| 
 | 
