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