00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 00003 // This file is part of Vesta. 00004 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 00020 // Atom.H -- a package for unique text strings 00021 00022 /* An "Atom" is a unique text string. Two Atom's refs are equal iff their 00023 contents are equal. Hence, they can be compared for equality more 00024 efficiently than regular Text's. 00025 00026 NOTE: Atoms should only be used when linking with the garbage collector! 00027 This is because Atoms are a subtype of Text, and so the Text destructor 00028 will always be called when an Atom is destroyed. This is disasterous when 00029 the garbage collector is not being used, since the Text destructor in that 00030 case deallocates the string. */ 00031 00032 #ifndef _ATOM_H 00033 #define _ATOM_H 00034 00035 #include <Basics.H> 00036 00037 class Atom: public Text { 00038 public: 00039 Atom() throw () : Text() { /*SKIP*/ } 00040 Atom(const Atom& atm) throw () { this->s = atm.s; } 00041 Atom(const Text& t) throw () 00042 { Init(t.cchars(), Text::GCImpl() ? (void *)1 : (void *)NULL); } 00043 Atom(const char c) throw () { Init(&c, 1); } 00044 Atom(const char *str, const void *cpy = NULL) throw () { Init(str, cpy); } 00045 Atom(const char *bytes, int len) throw () { Init(bytes, len); } 00046 /* These initialize an Atom to the empty string, a copy of the atom "atm", 00047 a copy of the text "t", a string containing the single character "c", a 00048 copy of the null-terminated string "str", and the "len" chars pointed 00049 to by "bytes", respectively. In the latter case, it is an unchecked 00050 run-time error for any of the "len" bytes pointed to by "bytes" to be 00051 '\0'. In the case of initializing an Atom from a null-terminated string 00052 "str", if the bytes pointed to by "str" are immutable and long-lived, 00053 an extra copy can be avoided by passing a non-NULL value for "cpy". */ 00054 00055 // destructor 00056 ~Atom() throw () { /* SKIP -- Atoms are never de-allocated. */ } 00057 00058 // assignment 00059 Atom& operator = (const char* str) throw (); 00060 Atom& operator = (const Text& t) throw (); 00061 Atom& operator = (const Atom& a) throw (); 00062 00063 // relational operators 00064 inline bool operator == (const Atom& a2) throw () 00065 { return (this->s == a2.s); } 00066 inline bool operator == (const Text& t2) throw () 00067 { return (*((Text* ) this) == t2); } 00068 inline bool operator == (const char *c2) throw () 00069 { return (*((Text* ) this) == c2); } 00070 inline bool operator != (const Atom& a2) throw () 00071 { return (this->s != a2.s); } 00072 inline bool operator != (const Text& t2) throw () 00073 { return (*((Text* ) this) != t2); } 00074 inline bool operator != (const char *c2) throw () 00075 { return (*((Text* ) this) != c2); } 00076 00077 // destructive concatenation 00078 Atom& operator += (const char* str) throw (); 00079 Atom& operator += (const Text& t) throw (); 00080 Atom& operator += (const Atom& ) throw (); 00081 00082 private: 00083 void Init(const char* str, const void* copy) throw (); 00084 void Init(const char* bytes, int len) throw (); 00085 }; 00086 00087 #endif // _ATOM_H