This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.


  String Table
  Submitted by

The description is part of the code listing.

Download Associated File: stable.h (4,339 bytes)

#ifndef STABLE_H

#define STABLE_H

// This class implements a 'stringtable'. It is being released into // the public domain on September 27, 2000 by John W. Ratcliff // for as part of the 'code of they day' // project. // // What the heck does a 'StringTable' class do for me? What a StringTable // is used for is to manage a collection of shared strings across a package. // It is primarily used for tokens, keywords, asset names, etc. You do // *NOT* want to use the StringTable for any cases which could produce // an infinite number of strings. This is only for managing a finite list // of keywords. // // The reason you use a string table is so that you can keep track of items // by ASCII name instead of some non-intutitive and arbritrary id number. // Normally it is not practical to make a container class who's key is // an STL string. First of all there is a memory overhead, and additionally // there is a serious peformance penalty. However, with the StringTable // class, instead you can keep track of a list of items where the key is // a pointer to the string, instead of the string itself. Now you can // compare if 'two strings are equal' simply by comparing if their address // is the same. Remember that any container class which uses this pointer as // a key is *NOT* in alphabetical order!! It's ordered based on the address // in memory of the string itself. But that doesn't matter, because the // purpose of the container is not to maintain an alphabetical list of // items but rather to simply locate items *BY NAME* extremely quickly. // // Using a stringtable makes it trivial to keep ASCII names and descriptions // as member variables in all of your classes. This makes debugging and // debug output vastly simpler. // // Example: Say you contruct a new intance of a Vehicle class. In it's // constructor you might have something like: // // mObjectName = gStringTable.Get("vehicle"); // // Where mObjectName is a member variable of type 'const char *' and // gStringTable is some global instance of a shared string table across // your application. Now, you can compare whether or not an object is of // type 'vehicle' simply by comparing it's name to anybody else's name // with the two pointers allocated with the same string table. // // This is extremely convenient for debugging, logging, etc. // // To create an STL map where you access every item *by name* all you // have to do is: // // typedef std::map< const char * , Texture *> TextureMap; // // This would create an STL map that would allow you to quickly look // up any texture by name. A fairly useful data structure. // // Example of how to locate a texture by name: // // **NOTE* texname must have been created by the same StringTable // // Texture * FindTexture(const char *texname) // { // TextureMap::iterator found; // STL map iterator to find item. // found = mTextures.find( texname ); // search red/black tree // if ( found != mTextures.end() ) return (*found).second; // return 0; // no texture of this name found. // } // // The string table implementation uses STL to maintain the collection // of strings. If you change the comparator function in CharPtrLess // from strcmp to stricmp then all of your strings will be created without // case sensitivity, which is often the behavior you want for tokens and // keywords. #include <string.h> #include <string> #include <set>

typedef std::string String;

class CharPtrLess { public: bool operator()(const char *v1,const char *v2) const { int v = strcmp(v1,v2); if ( v < 0 ) return true; return false; }; };

typedef std::set< const char *, CharPtrLess > CharPtrSet;

class StringTable { public: StringTable(void) { };

~StringTable(void) { CharPtrSet::iterator i; for (i=mStrings.begin(); i!=mStrings.end(); i++) { char *str = (char *)(*i); delete str; } }

const char * Get(const char *str) { CharPtrSet::iterator found; found = mStrings.find( str ); if ( found != mStrings.end() ) return (*found); int l = strlen(str); char *mem = new char[l+1]; strcpy(mem,str); mStrings.insert( mem ); return mem; };

const char * Get(const String &str) { return Get( str.c_str() ); };

private: CharPtrSet mStrings; };


The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.


Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.