1 /************************************************************************
2 ************************************************************************
4 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
23 * A library to create and manipulate symbols with a unique name.
24 * A library of functions to create and manipulate symbols with a unique name.
28 * - Sym q = symbol("abcd"); <i>returns the symbol of name "abcd"</i>
29 * - const char* s = name(q); <i>returns the name of symbol q</i>
30 * - Sym q = unique("TOTO"); <i>returns a new unique symbol of name "TOTOnnn"</i>
34 * If p and q are two symbols then :
35 * p != q <=> name(p) != name(q)
48 //--------------------------------SYMBOL-------------------------------------
51 * Symbols are unique objects with a name stored in a hash table.
58 static const int kHashTableSize = 511; ///< Size of the hash table (a prime number is recommended)
59 static Symbol* gSymbolTable[kHashTableSize]; ///< Hash table used to store the symbols
63 char* fName; ///< Name of the symbol
64 unsigned int fHash; ///< Hash key computed from the name and used to determine the hash table entry
65 Symbol* fNext; ///< Next symbol in the hash table entry
66 void* fData; ///< Field to user disposal to store additional data
68 // Constructors & destructors
69 Symbol (const char* str, unsigned int hsh, Symbol* nxt); ///< Constructs a new symbol ready to be placed in the hash table
70 ~Symbol (); ///< The Destructor is never used
73 bool equiv (unsigned int hash, const char* str) const ; ///< Check if the name of the symbol is equal to string \p str
74 static unsigned int calcHashKey (const char* str); ///< Compute the 32-bits hash key of string \p str
77 static Symbol* get (const string& str); ///< Get the symbol of name \p str
78 static Symbol* get (const char* str); ///< Get the symbol of name \p str
79 static Symbol* prefix (const char* str); ///< Creates a new symbol of name prefixed by \p str
80 static bool isnew (const char* str); ///< Returns \b true if no symbol of name \p str exists
83 ostream& print (ostream& fout) const; ///< print a symbol on a stream
85 friend Symbol* symbol (const char* str);
86 friend Symbol* symbol (const string& str);
87 friend Symbol* unique (const char* str);
88 friend const char* name (Symbol* sym);
90 friend void* getUserData (Symbol* sym);
91 friend void setUserData (Symbol* sym, void* d);
95 inline Symbol* symbol (const char* str) { return Symbol::get(str); } ///< Returns (and creates if new) the symbol of name \p str
96 inline Symbol* symbol (const string& str) { return Symbol::get(str); } ///< Returns (and creates if new) the symbol of name \p str
97 inline Symbol* unique (const char* str) { return Symbol::prefix(str);} ///< Returns a new unique symbol of name strxxx
98 inline const char* name (Symbol* sym) { return sym->fName; } ///< Returns the name of a symbol
100 inline void* getUserData (Symbol* sym) { return sym->fData; } ///< Returns user data
101 inline void setUserData (Symbol* sym, void* d) { sym->fData=d; } ///< Set user data
103 inline ostream& operator << (ostream& s, const Symbol& n) { return n.print(s); }