1 // Copyright (C) 2002 Graydon Hoare <graydon@pobox.com> 2 // 3 // This program is made available under the GNU GPL version 2.0 or 4 // greater. See the accompanying file COPYING for details. 5 // 6 // This program is distributed WITHOUT ANY WARRANTY; without even the 7 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 8 // PURPOSE. 9 10 //HH 11 12 #define hh_ENCODING(enc) \ 13 \ 14 template<typename INNER> \ 15 class enc; \ 16 \ 17 template <typename INNER> \ 18 std::ostream & operator<<(std::ostream &, \ 19 enc<INNER> const &); \ 20 \ 21 template <typename INNER> \ 22 void dump(enc<INNER> const &, std::string &); \ 23 \ 24 template<typename INNER> \ 25 class enc : public origin_aware { \ 26 immutable_string s; \ 27 public: \ 28 enc() {} \ 29 explicit enc(char const * const s); \ 30 enc(std::string const & s, origin::type m); \ 31 enc(enc<INNER> const & other); \ 32 enc<INNER> const & \ 33 operator=(enc<INNER> const & other); \ 34 std::string const & operator()() const \ 35 { return s.get(); } \ 36 bool operator<(enc<INNER> const & x) const \ 37 { return s.get() < x.s.get(); } \ 38 bool operator==(enc<INNER> const & x) const \ 39 { return s.get() == x.s.get(); } \ 40 bool operator!=(enc<INNER> const & x) const \ 41 { return s.get() != x.s.get(); } \ 42 friend std::ostream & operator<< <>(std::ostream &, \ 43 enc<INNER> const &); \ 44 }; 45 46 #define hh_ENCODING_NOVERIFY(enc) hh_ENCODING(enc) 47 48 49 #define hh_DECORATE(dec) \ 50 \ 51 template<typename INNER> \ 52 class dec; \ 53 \ 54 template <typename INNER> \ 55 std::ostream & operator<<(std::ostream &, \ 56 dec<INNER> const &); \ 57 \ 58 template <typename INNER> \ 59 void dump(dec<INNER> const &, std::string &); \ 60 \ 61 template<typename INNER> \ 62 class dec { \ 63 INNER i; \ 64 public: \ 65 dec() {} \ 66 explicit dec(char const * const s); \ 67 dec(std::string const & s, origin::type m); \ 68 explicit dec(INNER const & inner); \ 69 dec(dec<INNER> const & other); \ 70 bool operator<(dec<INNER> const & x) const \ 71 { return i < x.i; } \ 72 INNER const & inner() const \ 73 { return i; } \ 74 dec<INNER> const & \ 75 operator=(dec<INNER> const & other); \ 76 bool operator==(dec<INNER> const & x) const \ 77 { return i == x.i; } \ 78 bool operator!=(dec<INNER> const & x) const \ 79 { return !(i == x.i); } \ 80 friend std::ostream & operator<< <>(std::ostream &, \ 81 dec<INNER> const &); \ 82 }; 83 84 85 #define hh_ATOMIC_HOOKED(ty, hook) \ 86 class ty; \ 87 \ 88 std::ostream & operator<<(std::ostream &, ty const &); \ 89 \ 90 template <> \ 91 void dump(ty const &, std::string &); \ 92 \ 93 class ty : public origin_aware { \ 94 immutable_string s; \ 95 public: \ 96 ty() {} \ 97 explicit ty(char const * const str); \ 98 ty(std::string const & str, origin::type m); \ 99 ty(ty const & other); \ 100 ty const & operator=(ty const & other); \ 101 std::string const & operator()() const \ 102 { return s.get(); } \ 103 bool operator<(ty const & x) const \ 104 { return s.get() < x.s.get(); } \ 105 bool operator==(ty const & x) const \ 106 { return s.get() == x.s.get(); } \ 107 bool operator!=(ty const & x) const \ 108 { return s.get() != x.s.get(); } \ 109 friend std::ostream & operator<<(std::ostream &, \ 110 ty const &); \ 111 hook \ 112 struct symtab \ 113 { \ 114 symtab(); \ 115 ~symtab(); \ 116 }; \ 117 }; 118 119 #define hh_ATOMIC(ty) hh_ATOMIC_HOOKED(ty,) 120 #define hh_ATOMIC_NOVERIFY(ty) hh_ATOMIC(ty) 121 #define hh_ATOMIC_BINARY(ty) hh_ATOMIC(ty) 122 123 //CC 124 125 126 #define cc_ATOMIC(ty) \ 127 \ 128 static symtab_impl ty ## _tab; \ 129 static size_t ty ## _tab_active = 0; \ 130 \ 131 ty::ty(char const * const str) : \ 132 origin_aware(), \ 133 s((ty ## _tab_active > 0) \ 134 ? (ty ## _tab.unique(str)) \ 135 : str) \ 136 { verify(*this); } \ 137 \ 138 ty::ty(string const & str, \ 139 origin::type m) : \ 140 origin_aware(m), \ 141 s((ty ## _tab_active > 0) \ 142 ? (ty ## _tab.unique(str)) \ 143 : str) \ 144 { verify(*this); } \ 145 \ 146 ty::ty(ty const & other) : \ 147 origin_aware(other), s(other.s) {} \ 148 \ 149 ty const & ty::operator=(ty const & other) \ 150 { \ 151 s = other.s; \ 152 made_from = other.made_from; \ 153 return *this; \ 154 } \ 155 \ 156 std::ostream & operator<<(std::ostream & o, \ 157 ty const & a) \ 158 { return (o << a.s.get()); } \ 159 \ 160 template <> \ 161 void dump(ty const & obj, std::string & out) \ 162 { out = obj(); } \ 163 \ 164 ty::symtab::symtab() \ 165 { ty ## _tab_active++; } \ 166 \ 167 ty::symtab::~symtab() \ 168 { \ 169 I(ty ## _tab_active > 0); \ 170 ty ## _tab_active--; \ 171 if (ty ## _tab_active == 0) \ 172 ty ## _tab.clear(); \ 173 } 174 175 176 #define cc_ATOMIC_NOVERIFY(ty) \ 177 inline void verify(ty const &) {} \ 178 cc_ATOMIC(ty) 179 180 181 #define cc_ATOMIC_BINARY(ty) \ 182 \ 183 static symtab_impl ty ## _tab; \ 184 static size_t ty ## _tab_active = 0; \ 185 \ 186 ty::ty(char const * const str) : \ 187 origin_aware(), \ 188 s((ty ## _tab_active > 0) \ 189 ? (ty ## _tab.unique(str)) \ 190 : str) \ 191 { verify(*this); } \ 192 \ 193 ty::ty(string const & str, \ 194 origin::type m) : \ 195 origin_aware(m), \ 196 s((ty ## _tab_active > 0) \ 197 ? (ty ## _tab.unique(str)) \ 198 : str) \ 199 { verify(*this); } \ 200 \ 201 ty::ty(ty const & other) : \ 202 origin_aware(other), s(other.s) {} \ 203 \ 204 ty const & ty::operator=(ty const & other) \ 205 { \ 206 s = other.s; \ 207 made_from = other.made_from; \ 208 return *this; \ 209 } \ 210 \ 211 std::ostream & operator<<(std::ostream & o, \ 212 ty const & a) \ 213 { return (o << encode_hexenc(a(), a.made_from)); } \ 214 \ 215 ty::symtab::symtab() \ 216 { ty ## _tab_active++; } \ 217 \ 218 ty::symtab::~symtab() \ 219 { \ 220 I(ty ## _tab_active > 0); \ 221 ty ## _tab_active--; \ 222 if (ty ## _tab_active == 0) \ 223 ty ## _tab.clear(); \ 224 } 225 226 227 228 #define cc_ENCODING(enc) \ 229 \ 230 template<typename INNER> \ 231 enc<INNER>::enc(char const * const s) : \ 232 origin_aware(), s(s) \ 233 { verify(*this); } \ 234 \ 235 template<typename INNER> \ 236 enc<INNER>::enc(string const & s, origin::type m) : \ 237 origin_aware(m), s(s) \ 238 { verify(*this); } \ 239 \ 240 template<typename INNER> \ 241 enc<INNER>::enc(enc<INNER> const & other) \ 242 : origin_aware(other), s(other.s) {} \ 243 \ 244 template<typename INNER> \ 245 enc<INNER> const & \ 246 enc<INNER>::operator=(enc<INNER> const & other) \ 247 { \ 248 s = other.s; \ 249 made_from = other.made_from; \ 250 return *this; \ 251 } \ 252 \ 253 template <typename INNER> \ 254 std::ostream & operator<<(std::ostream & o, \ 255 enc<INNER> const & e) \ 256 { return (o << e.s.get()); } \ 257 \ 258 template <typename INNER> \ 259 void dump(enc<INNER> const & obj, std::string & out) \ 260 { out = obj(); } 261 262 #define cc_ENCODING_NOVERIFY(enc) \ 263 template<typename INNER> \ 264 inline void verify(enc<INNER> const &) {} \ 265 cc_ENCODING(enc) 266 267 268 269 #define cc_DECORATE(dec) \ 270 \ 271 template<typename INNER> \ 272 dec<INNER>::dec(dec<INNER> const & other) \ 273 : i(other.i) {} \ 274 \ 275 template<typename INNER> \ 276 dec<INNER>::dec(char const * const s) \ 277 : i(s) { verify(i); } \ 278 \ 279 template<typename INNER> \ 280 dec<INNER>::dec(std::string const & s, \ 281 origin::type m) \ 282 : i(s, m) { verify(i); } \ 283 \ 284 template<typename INNER> \ 285 dec<INNER>::dec(INNER const & inner) \ 286 : i(inner) {} \ 287 \ 288 template<typename INNER> \ 289 dec<INNER> const & \ 290 dec<INNER>::operator=(dec<INNER> const & other) \ 291 { i = other.i; return *this; } \ 292 \ 293 template <typename INNER> \ 294 std::ostream & operator<<(std::ostream & o, \ 295 dec<INNER> const & d) \ 296 { return (o << d.i); } \ 297 \ 298 template <typename INNER> \ 299 void dump(dec<INNER> const & obj, std::string & out) \ 300 { dump(obj.inner(), out); } 301 302 // Local Variables: 303 // mode: C++ 304 // fill-column: 76 305 // c-file-style: "gnu" 306 // indent-tabs-mode: nil 307 // End: 308 // vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: 309