Generated on Wed Mar 19 07:30:03 2008 for Gecode by doxygen 1.5.5

symbol.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Contributing authors:
00007  *     Christian Schulte <schulte@gecode.org>
00008  *
00009  *  Copyright:
00010  *     Guido Tack, 2007
00011  *     Christian Schulte, 2007
00012  *
00013  *  Last modified:
00014  *     $Date: 2007-11-28 14:58:39 +0100 (Wed, 28 Nov 2007) $ by $Author: tack $
00015  *     $Revision: 5474 $
00016  *
00017  *  This file is part of Gecode, the generic constraint
00018  *  development environment:
00019  *     http://www.gecode.org
00020  *
00021  *  Permission is hereby granted, free of charge, to any person obtaining
00022  *  a copy of this software and associated documentation files (the
00023  *  "Software"), to deal in the Software without restriction, including
00024  *  without limitation the rights to use, copy, modify, merge, publish,
00025  *  distribute, sublicense, and/or sell copies of the Software, and to
00026  *  permit persons to whom the Software is furnished to do so, subject to
00027  *  the following conditions:
00028  *
00029  *  The above copyright notice and this permission notice shall be
00030  *  included in all copies or substantial portions of the Software.
00031  *
00032  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00033  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00034  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00035  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00036  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00037  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00038  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00039  *
00040  */
00041 
00042 #include "gecode/support.hh"
00043 
00044 namespace Gecode { namespace Support {
00045 
00046   forceinline void* 
00047   Symbol::SO::operator new(size_t s) {
00048     return Memory::malloc(s);
00049   }
00050   forceinline void
00051   Symbol::SO::operator delete(void* p) {
00052     Memory::free(p);
00053   }
00054   forceinline bool
00055   Symbol::SO::cancel(void) { return --use_cnt == 0; }
00056 
00057   forceinline void
00058   Symbol::SO::subscribe(void) { ++use_cnt; }
00059 
00060   forceinline unsigned int
00061   Symbol::SO::size(void) const {
00062     return strlen(s);
00063   }
00064 
00065   forceinline char*
00066   Symbol::SO::strdup(const char* s) {
00067     unsigned int n = strlen(s)+1;
00068     char* d = static_cast<char*>(Memory::malloc(sizeof(char)*n));
00069     for (unsigned int i=n; i--; )
00070       d[i]=s[i];
00071     return d;
00072   }
00073 
00074   forceinline 
00075   Symbol::SO::SO(const char* s0, bool copy)
00076     : use_cnt(0),
00077       s(copy ? strdup(s0) : const_cast<char*>(s0)), own(copy) {}
00078 
00079   forceinline int
00080   Symbol::SO::hash(int m) const {
00081     int h = 0;
00082     int pos = 0;
00083     while (s[pos] != 0) {
00084       h = (127 * h + s[pos++]) % m;
00085     }
00086     return h;
00087   }
00088 
00089   forceinline void
00090   Symbol::SO::append(SO* so0) {
00091     if (so0 == NULL)
00092       return;
00093     unsigned int n1 = strlen(s);
00094     unsigned int n2 = strlen(so0->s);
00095     char* d = static_cast<char*>(Memory::malloc(sizeof(char)*(n1+n2+1)));
00096     for (unsigned int i=n1; i--; )
00097       d[i] = s[i];
00098     for (unsigned int i=n2+1; i--; )
00099       d[n1+i] = so0->s[i];
00100     if (own)
00101       Memory::free(s);
00102     s = d;
00103     own = true;
00104   }
00105 
00106   forceinline bool
00107   Symbol::SO::eq(const SO* other) const {
00108     if (this == other)
00109       return true;
00110     if (other == NULL)
00111       return false;
00112     return (!strcmp(s, other->s));
00113   }
00114 
00115   forceinline bool
00116   Symbol::SO::eq(const char* other) const {
00117     return (!strcmp(s, other));
00118   }
00119   
00120   std::ostream&
00121   Symbol::SO::print(std::ostream& os) const {
00122     return os << s;
00123   }
00124 
00125 
00126   Symbol::Symbol(void) : so(NULL) {}
00127 
00128   Symbol::Symbol(const char* s0, bool copy)
00129     : so(new SO(s0, copy)) {
00130     so->subscribe();
00131   }
00132 
00133   Symbol::Symbol(const Symbol& s0) {
00134     so = s0.so;
00135     if (so)
00136       so->subscribe();
00137   }
00138 
00139   const Symbol&
00140   Symbol::operator=(const Symbol& s0) {
00141     if (this != &s0) {
00142       if (so && so->cancel()) {
00143         if (so->own)
00144           Memory::free(so->s);
00145         delete so;
00146       }
00147       so = s0.so;
00148       if (so)
00149         so->subscribe();
00150     }
00151     return *this;
00152   }
00153   
00154   bool
00155   Symbol::empty(void) const {
00156     return so==NULL;
00157   }
00158   
00159   Symbol
00160   Symbol::copy(void) const {
00161     Symbol ret;
00162     if (so == NULL) {
00163       ret.so = NULL;
00164     } else {
00165       ret.so = new SO(so->s, true);
00166       ret.so->subscribe();
00167     }
00168     return ret;
00169   }
00170 
00171   Symbol&
00172   Symbol::operator+=(const Symbol& s0) {
00173     if (so == NULL) {
00174       so = s0.so;
00175       if (so)
00176         so->subscribe();
00177     } else if (s0.so != NULL) {
00178       so->append(s0.so);
00179     }
00180     return *this;
00181   }
00182   
00183   int
00184   Symbol::hash(int m) const {
00185     if (so == NULL)
00186       return 0;
00187     return so->hash(m);
00188   }
00189 
00190   bool
00191   Symbol::operator==(const Symbol& s0) const {
00192     if (so == NULL)
00193       return (s0.so == NULL);
00194     return so->eq(s0.so);
00195   }
00196 
00197   bool
00198   Symbol::operator==(const char* s0) const {
00199     if (so==NULL)
00200       return s0[0] == 0;
00201     return so->eq(s0);
00202   }
00203   
00204   std::ostream&
00205   Symbol::print(std::ostream& os) const {
00206     if (so) return so->print(os);
00207     return os;
00208   }
00209 
00210   std::string
00211   Symbol::toString(void) const {
00212     if (so) return so->s;
00213     return "";
00214   }
00215   
00216   Symbol::~Symbol(void) {
00217     if ((so != NULL) && so->cancel()) {
00218       if (so->own)
00219         Memory::free(so->s);
00220       delete so;
00221     }
00222   }
00223 
00224 }}
00225 
00226 // STATISTICS: support-any