Generated on Mon Aug 25 11:35:44 2008 for Gecode by doxygen 1.5.6

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: 2008-07-11 09:32:27 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00015  *     $Revision: 7289 $
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 #include <sstream>
00044 
00045 namespace Gecode { namespace Support {
00046 
00047   forceinline void* 
00048   Symbol::SO::operator new(size_t s) {
00049     return Memory::malloc(s);
00050   }
00051   forceinline void
00052   Symbol::SO::operator delete(void* p) {
00053     Memory::free(p);
00054   }
00055   forceinline bool
00056   Symbol::SO::cancel(void) { return --use_cnt == 0; }
00057 
00058   forceinline void
00059   Symbol::SO::subscribe(void) { ++use_cnt; }
00060 
00061   forceinline unsigned int
00062   Symbol::SO::size(void) const {
00063     return strlen(s);
00064   }
00065 
00066   forceinline char*
00067   Symbol::SO::strdup(const char* s) {
00068     unsigned int n = strlen(s)+1;
00069     char* d = static_cast<char*>(Memory::malloc(sizeof(char)*n));
00070     for (unsigned int i=n; i--; )
00071       d[i]=s[i];
00072     return d;
00073   }
00074 
00075   forceinline 
00076   Symbol::SO::SO(const char* s0, bool copy)
00077     : use_cnt(0),
00078       s(copy ? strdup(s0) : const_cast<char*>(s0)), own(copy) {}
00079 
00080   forceinline int
00081   Symbol::SO::hash(int m) const {
00082     int h = 0;
00083     int pos = 0;
00084     while (s[pos] != 0) {
00085       h = (127 * h + s[pos++]) % m;
00086     }
00087     return h;
00088   }
00089 
00090   forceinline void
00091   Symbol::SO::append(SO* so0) {
00092     if (so0 == NULL)
00093       return;
00094     unsigned int n1 = strlen(s);
00095     unsigned int n2 = strlen(so0->s);
00096     char* d = static_cast<char*>(Memory::malloc(sizeof(char)*(n1+n2+1)));
00097     for (unsigned int i=n1; i--; )
00098       d[i] = s[i];
00099     for (unsigned int i=n2+1; i--; )
00100       d[n1+i] = so0->s[i];
00101     if (own)
00102       Memory::free(s);
00103     s = d;
00104     own = true;
00105   }
00106 
00107   forceinline bool
00108   Symbol::SO::eq(const SO* other) const {
00109     if (this == other)
00110       return true;
00111     if (other == NULL)
00112       return false;
00113     return (!strcmp(s, other->s));
00114   }
00115 
00116   forceinline bool
00117   Symbol::SO::eq(const char* other) const {
00118     return (!strcmp(s, other));
00119   }
00120   
00121   std::ostream&
00122   Symbol::SO::print(std::ostream& os) const {
00123     return os << s;
00124   }
00125 
00126 
00127   Symbol::Symbol(void) : so(NULL) {}
00128 
00129   Symbol::Symbol(const char* s0, bool copy)
00130     : so(new SO(s0, copy)) {
00131     so->subscribe();
00132   }
00133 
00134   Symbol::Symbol(int i) {
00135     std::stringstream s;
00136     s << i;
00137     so = new SO(s.str().c_str(), true);
00138     so->subscribe();
00139   }
00140 
00141   Symbol::Symbol(unsigned int i) {
00142     std::stringstream s;
00143     s << i;
00144     so = new SO(s.str().c_str(), true);
00145     so->subscribe();
00146   }
00147 
00148   Symbol::Symbol(const Symbol& s0) {
00149     so = s0.so;
00150     if (so)
00151       so->subscribe();
00152   }
00153 
00154   const Symbol&
00155   Symbol::operator=(const Symbol& s0) {
00156     if (this != &s0) {
00157       if (so && so->cancel()) {
00158         if (so->own)
00159           Memory::free(so->s);
00160         delete so;
00161       }
00162       so = s0.so;
00163       if (so)
00164         so->subscribe();
00165     }
00166     return *this;
00167   }
00168   
00169   bool
00170   Symbol::empty(void) const {
00171     return so==NULL;
00172   }
00173   
00174   Symbol
00175   Symbol::copy(void) const {
00176     Symbol ret;
00177     if (so == NULL) {
00178       ret.so = NULL;
00179     } else {
00180       ret.so = new SO(so->s, true);
00181       ret.so->subscribe();
00182     }
00183     return ret;
00184   }
00185 
00186   Symbol&
00187   Symbol::operator+=(const Symbol& s0) {
00188     if (so == NULL) {
00189       so = s0.so;
00190       if (so)
00191         so->subscribe();
00192     } else if (s0.so != NULL) {
00193       so->append(s0.so);
00194     }
00195     return *this;
00196   }
00197   
00198   int
00199   Symbol::hash(int m) const {
00200     if (so == NULL)
00201       return 0;
00202     return so->hash(m);
00203   }
00204 
00205   bool
00206   Symbol::operator==(const Symbol& s0) const {
00207     if (so == NULL)
00208       return (s0.so == NULL);
00209     return so->eq(s0.so);
00210   }
00211 
00212   bool
00213   Symbol::operator==(const char* s0) const {
00214     if (so==NULL)
00215       return s0[0] == 0;
00216     return so->eq(s0);
00217   }
00218   
00219   std::ostream&
00220   Symbol::print(std::ostream& os) const {
00221     if (so) return so->print(os);
00222     return os;
00223   }
00224 
00225   std::string
00226   Symbol::toString(void) const {
00227     if (so) return so->s;
00228     return "";
00229   }
00230   
00231   Symbol::~Symbol(void) {
00232     if ((so != NULL) && so->cancel()) {
00233       if (so->own)
00234         Memory::free(so->s);
00235       delete so;
00236     }
00237   }
00238 
00239 }}
00240 
00241 // STATISTICS: support-any