00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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