words.h

Go to the documentation of this file.
00001 
00002 
00003 
00014 
00015 // Copyright (C) 1997-2010 by Pawel Pilarczyk.
00016 //
00017 // This file is part of the Homology Library.  This library is free software;
00018 // you can redistribute it and/or modify it under the terms of the GNU
00019 // General Public License as published by the Free Software Foundation;
00020 // either version 2 of the License, or (at your option) any later version.
00021 //
00022 // This library is distributed in the hope that it will be useful,
00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025 // GNU General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License along
00028 // with this software; see the file "license.txt".  If not, write to the
00029 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00030 // MA 02111-1307, USA.
00031 
00032 // Started on May 5, 2002. Last revision: February 21, 2007.
00033 
00034 
00035 #ifndef _CHOMP_STRUCT_WORDS_H_
00036 #define _CHOMP_STRUCT_WORDS_H_
00037 
00038 #include "chomp/system/config.h"
00039 #include "chomp/struct/integer.h"
00040 #include "chomp/system/textfile.h"
00041 #include "chomp/struct/hashsets.h"
00042 
00043 #include <cstdlib>
00044 #include <cstring>
00045 #include <iostream>
00046 #include <fstream>
00047 #include <sstream>
00048 
00049 namespace chomp {
00050 namespace homology {
00051 
00052 
00053 // the data types defined within this file
00054 class word;
00055 
00057 typedef hashedset<word> words;
00058 
00059 
00060 // --------------------------------------------------
00061 // ---------------------- word ----------------------
00062 // --------------------------------------------------
00063 
00065 class word
00066 {
00067 public:
00069         word ();
00070 
00072         word (const char *s);
00073 
00075         word (const word &w);
00076 
00078         ~word ();
00079 
00081         word &operator = (const word &w);
00082 
00084         int length () const;
00085 
00087         const char *text () const;
00088 
00090         operator const char * () const;
00091 
00093         word &operator += (const word &w);
00094 
00096         word operator + (const word &w) const;
00097 
00100         operator int () const;
00101 
00102 private:
00104         int len;
00105 
00107         char *txt;
00108 
00109 }; /* class word */
00110 
00111 // --------------------------------------------------
00112 
00113 inline word::word ()
00114 {
00115         len = 0;
00116         txt = NULL;
00117         return;
00118 } /* word::word */
00119 
00120 inline word::word (const char *s)
00121 {
00122         len = s ? strlen (s) : 0;
00123         if (!len)
00124                 txt = NULL;
00125         else
00126         {
00127                 txt = new char [len + 1];
00128                 if (!txt)
00129                         throw "Not enough memory to create a word.";
00130                 strcpy (txt, s);
00131         }
00132         return;
00133 } /* word::word */
00134 
00135 inline word::word (const word &w)
00136 {
00137         len = w. len;
00138         if (!len)
00139                 txt = NULL;
00140         else
00141         {
00142                 txt = new char [len + 1];
00143                 if (!txt)
00144                         throw "Not enough memory to copy a word.";
00145                 strcpy (txt, w. txt);
00146         }
00147         return;
00148 } /* word::word */
00149 
00150 inline word::~word ()
00151 {
00152         if (txt)
00153                 delete [] txt;
00154         return;
00155 } /* word::~word */
00156 
00157 inline word &word::operator = (const word &w)
00158 {
00159         if (txt)
00160                 delete [] txt;
00161         len = w. len;
00162         if (w. txt)
00163         {
00164                 txt = new char [len + 1];
00165                 if (!txt)
00166                         throw "Not enough memory to copy a word.";
00167                 strcpy (txt, w. txt);
00168         }
00169         else
00170                 txt = NULL;
00171         return *this;
00172 } /* operator = */
00173 
00174 inline int word::length () const
00175 {
00176         return len;
00177 } /* length */
00178 
00179 inline const char *word::text () const
00180 {
00181         return txt;
00182 } /* text */
00183 
00184 inline word::operator const char * () const
00185 {
00186         return txt;
00187 } /* operator int */
00188 
00189 inline word &word::operator += (const word &w)
00190 {
00191         if (!len)
00192         {
00193                 *this = w;
00194                 return *this;
00195         }
00196         if (!w. len)
00197                 return *this;
00198         int newlen = len + w. len;
00199         char *newtxt = new char [newlen + 1];
00200         strcpy (newtxt, txt);
00201         strcat (newtxt, w. txt);
00202         delete [] txt;
00203         txt = newtxt;
00204         len = newlen;
00205         return *this;
00206 } /* operator += */
00207 
00208 inline word word::operator + (const word &w) const
00209 {
00210         word new_w (*this);
00211         new_w += w;
00212         return new_w;
00213 } /* operator + */
00214 
00215 inline word::operator int () const
00216 {
00217         if (!len)
00218                 return 0;
00219         char *s = txt;
00220         if (*s == '+')
00221                 ++ s;
00222         int num;
00223         std::istringstream str (s);
00224         str >> num;
00225         if (!str)
00226                 return 0;
00227         else
00228                 return num;
00229 } /* operator int */
00230 
00231 // --------------------------------------------------
00232 
00233 inline int_t hashkey1 (const word &w)
00234 {
00235         int len = w. length ();
00236         if (!len)
00237                 return 13;
00238         const char *txt = w. text ();
00239         int_t code = (static_cast<int_t> (txt [0]) << 7) ^
00240                 (static_cast<int_t> (txt [len - 1]));
00241         if (len > 3)
00242                 code ^= static_cast<int_t> (txt [2]) << 15;
00243         return code;
00244 } /* word::hashkey1 */
00245 
00246 inline int_t hashkey2 (const word &w)
00247 {
00248         int len = w. length ();
00249         if (!len)
00250                 return 7;
00251         const char *txt = w. text ();
00252         int_t code = (static_cast<int_t> (txt [0])) ^
00253                 (static_cast<int_t> (txt [len - 1] << 17));
00254         if (len > 4)
00255                 code ^= static_cast<int_t> (txt [3]) << 8;
00256         return code;
00257 } /* word::hashkey2 */
00258 
00260 inline int operator == (const word &w1, const word &w2)
00261 {
00262         if (w1. length () != w2. length ())
00263                 return 0;
00264         if (!w1. length ())
00265                 return 1;
00266         return !strcmp ((const char *) w1, (const char *) w2);
00267 } /* operator == */
00268 
00270 inline int operator != (const word &w1, const word &w2)
00271 {
00272         return !(w1 == w2);
00273 } /* operator != */
00274 
00276 inline int operator == (const word &w, const char *c)
00277 {
00278         if (!w. length ())
00279                 return (!c || !*c);
00280         return !strcmp ((const char *) w, c);
00281 } /* operator == */
00282 
00284 inline int operator != (const word &w, const char *c)
00285 {
00286         return !(w == c);
00287 } /* operator != */
00288 
00290 inline int operator == (const char *c, const word &w)
00291 {
00292         return (w == c);
00293 } /* operator == */
00294 
00296 inline int operator != (const char *c, const word &w)
00297 {
00298         return (w != c);
00299 } /* operator != */
00300 
00301 // --------------------------------------------------
00302 
00305 inline int operator < (const word &w1, const word &w2)
00306 {
00307         const char *c1 = (const char *) w1;
00308         const char *c2 = (const char *) w2;
00309 
00310         while (*c1 && *c2 && ((*c1) == (*c2)))
00311         {
00312                 ++ c1;
00313                 ++ c2;
00314         }
00315         return ((*c1) < (*c2));
00316 } /* operator < */
00317 
00320 inline int operator > (const word &w1, const word &w2)
00321 {
00322         return (w2 < w1);
00323 } /* operator > */
00324 
00327 inline int operator <= (const word &w1, const word &w2)
00328 {
00329         return !(w1 > w2);
00330 } /* operator <= */
00331 
00334 inline int operator >= (const word &w1, const word &w2)
00335 {
00336         return !(w1 < w2);
00337 } /* operator >= */
00338 
00339 
00340 // --------------------------------------------------
00341 
00344 template <class type>
00345 word &operator << (word &w, const type &elem)
00346 {
00347         std::ostringstream s;
00348         s << elem;
00349         w += s. str (). c_str ();
00350         return w;
00351 } /* operator << */
00352 
00353 
00354 // --------------------------------------------------
00355 
00357 inline std::ostream &operator << (std::ostream &out, const word &w)
00358 {
00359         if (w. length ())
00360                 out << (const char *) w;
00361         return out;
00362 } /* operator << */
00363 
00365 inline std::istream &operator >> (std::istream &in, word &w)
00366 {
00367         char buf [256 + 1];
00368         int pos = 0;
00369         int ch = in. peek ();
00370         while ((ch != ' ') && (ch != '\r') && (ch != '\n') && (ch != '\t') &&
00371                 (ch != EOF))
00372         {
00373                 buf [pos ++] = in. get ();
00374                 ch = in. peek ();
00375                 if (pos >= 256)
00376                         break;
00377         }
00378         buf [pos] = '\0';
00379         w = word (buf);
00380         return in;
00381 } /* operator >> */
00382 
00383 
00384 } // namespace homology
00385 } // namespace chomp
00386 
00387 #endif // _CHOMP_STRUCT_WORDS_H_
00388 
00390