Macro adjustments, date/time class, typed XML attributes.
[shibboleth/cpp-xmltooling.git] / xmltooling / base.h
1 /*
2  *  Copyright 2001-2006 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file base.h
19  * 
20  * Base header file definitions
21  * Must be included prior to including any other header
22  */
23
24 #ifndef __xmltooling_base_h__
25 #define __xmltooling_base_h__
26
27 #if defined (_MSC_VER) || defined(__BORLANDC__)
28   #include <xmltooling/config_pub_win32.h>
29 #else
30   #include <xmltooling/config_pub.h>
31 #endif
32
33 // Windows and GCC4 Symbol Visibility Macros
34 #ifdef WIN32
35   #define XMLTOOL_IMPORT __declspec(dllimport)
36   #define XMLTOOL_EXPORT __declspec(dllexport)
37   #define XMLTOOL_DLLLOCAL
38   #define XMLTOOL_DLLPUBLIC
39 #else
40   #define XMLTOOL_IMPORT
41   #ifdef GCC_HASCLASSVISIBILITY
42     #define XMLTOOL_EXPORT __attribute__ ((visibility("default")))
43     #define XMLTOOL_DLLLOCAL __attribute__ ((visibility("hidden")))
44     #define XMLTOOL_DLLPUBLIC __attribute__ ((visibility("default")))
45   #else
46     #define XMLTOOL_EXPORT
47     #define XMLTOOL_DLLLOCAL
48     #define XMLTOOL_DLLPUBLIC
49   #endif
50 #endif
51
52 // Define XMLTOOL_API for DLL builds
53 #ifdef XMLTOOLING_EXPORTS
54   #define XMLTOOL_API XMLTOOL_EXPORT
55 #else
56   #define XMLTOOL_API XMLTOOL_IMPORT
57 #endif
58
59 // Throwable classes must always be visible on GCC in all binaries
60 #ifdef WIN32
61   #define XMLTOOL_EXCEPTIONAPI(api) api
62 #elif defined(GCC_HASCLASSVISIBILITY)
63   #define XMLTOOL_EXCEPTIONAPI(api) XMLTOOL_EXPORT
64 #else
65   #define XMLTOOL_EXCEPTIONAPI(api)
66 #endif
67
68 #ifdef _MSC_VER
69     #define XMLTOOLING_DOXYGEN(desc) /##** desc */
70 #else
71     #define XMLTOOLING_DOXYGEN(desc)
72 #endif
73
74 /**
75  * Blocks copy c'tor and assignment operator for a class.
76  */
77 #define MAKE_NONCOPYABLE(type) \
78     private: \
79         type(const type&); \
80         type& operator=(const type&);
81
82 #ifndef DOXYGEN_SKIP
83 #ifndef NULL
84 #define NULL    0
85 #endif
86 #define UNICODE_LITERAL_1(a) {chLatin_##a, chNull}
87 #define UNICODE_LITERAL_2(a,b) {chLatin_##a, chLatin_##b, chNull}
88 #define UNICODE_LITERAL_3(a,b,c) {chLatin_##a, chLatin_##b, chLatin_##c, chNull}
89 #define UNICODE_LITERAL_4(a,b,c,d) {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chNull}
90 #define UNICODE_LITERAL_5(a,b,c,d,e) {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chNull}
91 #define UNICODE_LITERAL_6(a,b,c,d,e,f) {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chNull}
92 #define UNICODE_LITERAL_7(a,b,c,d,e,f,g) \
93     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chNull}
94 #define UNICODE_LITERAL_8(a,b,c,d,e,f,g,h) \
95     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chNull}
96 #define UNICODE_LITERAL_9(a,b,c,d,e,f,g,h,i) \
97     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, chNull}
98 #define UNICODE_LITERAL_10(a,b,c,d,e,f,g,h,i,j) \
99     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
100         chLatin_##j, chNull}
101 #define UNICODE_LITERAL_11(a,b,c,d,e,f,g,h,i,j,k) \
102     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
103         chLatin_##j, chLatin_##k, chNull}
104 #define UNICODE_LITERAL_12(a,b,c,d,e,f,g,h,i,j,k,l) \
105     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
106         chLatin_##j, chLatin_##k, chLatin_##l, chNull}
107 #define UNICODE_LITERAL_13(a,b,c,d,e,f,g,h,i,j,k,l,m) \
108     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
109         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chNull}
110 #define UNICODE_LITERAL_14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) \
111     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
112         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chNull}
113 #define UNICODE_LITERAL_15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \
114     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
115         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chNull}
116 #define UNICODE_LITERAL_16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
117     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
118         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chNull}
119 #define UNICODE_LITERAL_17(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) \
120     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
121         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chNull}
122 #define UNICODE_LITERAL_18(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) \
123     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
124         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, chNull}
125 #define UNICODE_LITERAL_19(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) \
126     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
127         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
128         chLatin_##s, chNull}
129 #define UNICODE_LITERAL_20(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) \
130     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
131         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
132         chLatin_##s, chLatin_##t, chNull}
133 #define UNICODE_LITERAL_21(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) \
134     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
135         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
136         chLatin_##s, chLatin_##t, chLatin_##u, chNull}
137 #define UNICODE_LITERAL_22(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) \
138     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
139         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
140         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chNull}
141 #define UNICODE_LITERAL_23(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) \
142     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
143         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
144         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chNull}
145 #define UNICODE_LITERAL_24(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x) \
146     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
147         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
148         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chNull}
149 #define UNICODE_LITERAL_25(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y) \
150     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
151         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
152         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chNull}
153 #define UNICODE_LITERAL_26(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) \
154     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
155         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
156         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, chNull}
157 #define UNICODE_LITERAL_27(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa) \
158     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
159         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
160         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
161         chLatin_##aa, chNull}
162 #define UNICODE_LITERAL_28(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb) \
163     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
164         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
165         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
166         chLatin_##aa, chLatin_##bb, chNull}
167 #define UNICODE_LITERAL_29(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc) \
168     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
169         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
170         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
171         chLatin_##aa, chLatin_##bb, chLatin_##cc, chNull}
172 #define UNICODE_LITERAL_30(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd) \
173     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
174         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
175         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
176         chLatin_##aa, chLatin_##bb, chLatin_##cc, chLatin_##dd, chNull}
177 #define UNICODE_LITERAL_31(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd,ee) \
178     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
179         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
180         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
181         chLatin_##aa, chLatin_##bb, chLatin_##cc, chLatin_##dd, chLatin_##ee, chNull}
182 #define UNICODE_LITERAL_32(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd,ee,ff) \
183     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
184         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
185         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
186         chLatin_##aa, chLatin_##bb, chLatin_##cc, chLatin_##dd, chLatin_##ee, chLatin_##ff, chNull}
187 #endif /* DOXYGEN_SKIP */
188
189 /**
190  * Begins the declaration of an XMLObject specialization for an abstract element/type.
191  * Basic boilerplate includes a protected constructor, empty virtual destructor,
192  * and Unicode constants for the default associated element's name and prefix.
193  * 
194  * @param linkage   linkage specifier for the class
195  * @param cname     the name of the class to declare
196  * @param base      the base class to derive from using public virtual inheritance
197  * @param desc      documentation comment for class
198  */
199 #define DECL_XMLOBJECT_ABSTRACT(linkage,cname,base,desc) \
200     XMLTOOLING_DOXYGEN(desc) \
201     class linkage cname : public virtual base { \
202     protected: \
203         cname() {} \
204     public: \
205         virtual ~cname() {} \
206         XMLTOOLING_DOXYGEN(Element local name) \
207         static const XMLCh LOCAL_NAME[]; \
208     }
209
210 /**
211  * Begins the declaration of an XMLObject specialization.
212  * Basic boilerplate includes a protected constructor, empty virtual destructor,
213  * and Unicode constants for the default associated element's name and prefix.
214  * 
215  * @param linkage   linkage specifier for the class
216  * @param cname     the name of the class to declare
217  * @param base      the base class to derive from using public virtual inheritance
218  * @param desc      documentation comment for class
219  */
220 #define BEGIN_XMLOBJECT(linkage,cname,base,desc) \
221     XMLTOOLING_DOXYGEN(desc) \
222     class linkage cname : public virtual base, public virtual xmltooling::ValidatingXMLObject { \
223     protected: \
224         cname() {} \
225     public: \
226         virtual ~cname() {} \
227         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
228         virtual cname* clone##cname() const=0; \
229         XMLTOOLING_DOXYGEN(Element local name) \
230         static const XMLCh LOCAL_NAME[]
231
232 /**
233  * Ends the declaration of an XMLObject specialization.
234  */
235 #define END_XMLOBJECT }
236
237 /**
238  * Declares abstract get/set methods for a typed XML attribute.
239  * 
240  * @param proper    the proper name of the attribute
241  * @param upcased   the upcased name of the attribute
242  * @param type      the attribute's data type
243  */
244 #define DECL_XMLOBJECT_ATTRIB(proper,upcased,type) \
245     public: \
246         XMLTOOLING_DOXYGEN(proper attribute name) \
247         static const XMLCh upcased##_ATTRIB_NAME[]; \
248         XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
249         virtual const type* get##proper() const=0; \
250         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
251         virtual void set##proper(const type* proper)=0
252
253 /**
254  * Declares abstract get/set methods for a string XML attribute.
255  * 
256  * @param proper    the proper name of the attribute
257  * @param upcased   the upcased name of the attribute
258  */
259 #define DECL_STRING_ATTRIB(proper,upcased) \
260     DECL_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
261
262 /**
263  * Declares abstract get/set methods for a string XML attribute.
264  * 
265  * @param proper    the proper name of the attribute
266  * @param upcased   the upcased name of the attribute
267  */
268 #define DECL_DATETIME_ATTRIB(proper,upcased) \
269     DECL_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
270     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
271     virtual void set##proper(time_t proper)=0; \
272     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
273     virtual void set##proper(const XMLCh* proper)=0
274
275 /**
276  * Declares abstract get/set methods for an integer XML attribute.
277  * 
278  * @param proper    the proper name of the attribute
279  * @param upcased   the upcased name of the attribute
280  */
281 #define DECL_INTEGER_ATTRIB(proper,upcased) \
282     public: \
283         XMLTOOLING_DOXYGEN(proper attribute name) \
284         static const XMLCh upcased##_ATTRIB_NAME[]; \
285         XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
286         virtual int get##proper() const=0; \
287         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
288         virtual void set##proper(int proper)=0
289
290 /**
291  * Implements get/set methods and a private member for a typed XML attribute.
292  * 
293  * @param proper    the proper name of the attribute
294  * @param type      the attribute's data type
295  */
296 #define IMPL_XMLOBJECT_ATTRIB(proper,type) \
297     protected: \
298         type* m_##proper; \
299     public: \
300         const type* get##proper() const { \
301             return m_##proper; \
302         } \
303         void set##proper(const type* proper) { \
304             m_##proper = prepareForAssignment(m_##proper,proper); \
305         }
306
307 /**
308  * Implements get/set methods and a private member for a string XML attribute.
309  * 
310  * @param proper    the proper name of the attribute
311  */
312 #define IMPL_STRING_ATTRIB(proper) \
313     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
314
315 /**
316  * Implements get/set methods and a private member for a DateTime XML attribute.
317  * 
318  * @param proper    the proper name of the attribute
319  */
320 #define IMPL_DATETIME_ATTRIB(proper) \
321     IMPL_XMLOBJECT_ATTRIB(proper,xmltooling::DateTime); \
322     void set##proper(time_t proper) { \
323         m_##proper = prepareForAssignment(m_##proper,proper); \
324     } \
325     void set##proper(const XMLCh* proper) { \
326         m_##proper = prepareForAssignment(m_##proper,proper); \
327     }
328
329 /**
330  * Implements get/set methods and a private member for an integer XML attribute.
331  * 
332  * @param proper    the proper name of the attribute
333  */
334 #define IMPL_INTEGER_ATTRIB(proper) \
335     protected: \
336         int m_##proper; \
337     public: \
338         int get##proper() const { \
339             return m_##proper; \
340         } \
341         void set##proper(int proper) { \
342             if (m_##proper != proper) { \
343                 releaseThisandParentDOM(); \
344                 m_##proper = proper; \
345             } \
346         }
347
348 /**
349  * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
350  * 
351  * @param proper    the proper name of the child type
352  * @param ns        the C++ namespace for the type
353  */
354 #define DECL_TYPED_FOREIGN_CHILD(proper,ns) \
355     public: \
356         XMLTOOLING_DOXYGEN(Returns the proper child.) \
357         virtual ns::proper* get##proper() const=0; \
358         XMLTOOLING_DOXYGEN(Sets the proper child.) \
359         virtual void set##proper(ns::proper* child)=0
360
361 /**
362  * Declares abstract get/set methods for a typed XML child object.
363  * 
364  * @param proper    the proper name of the child type
365  */
366 #define DECL_TYPED_CHILD(proper) \
367     public: \
368         XMLTOOLING_DOXYGEN(Returns the proper child.) \
369         virtual proper* get##proper() const=0; \
370         XMLTOOLING_DOXYGEN(Sets the proper child.) \
371         virtual void set##proper(proper* child)=0
372
373 /**
374  * Declares abstract get/set methods for a generic XML child object.
375  * 
376  * @param proper    the proper name of the child
377  */
378 #define DECL_XMLOBJECT_CHILD(proper) \
379     public: \
380         XMLTOOLING_DOXYGEN(Returns the proper child.) \
381         virtual xmltooling::XMLObject* get##proper() const=0; \
382         XMLTOOLING_DOXYGEN(Sets the proper child.) \
383         virtual void set##proper(xmltooling::XMLObject* child)=0
384
385
386 /**
387  * Implements get/set methods and a private list iterator member for a typed XML child object.
388  * 
389  * @param proper    the proper name of the child type
390  */
391 #define IMPL_TYPED_CHILD(proper) \
392     protected: \
393         proper* m_##proper; \
394         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
395     public: \
396         proper* get##proper() const { \
397             return m_##proper; \
398         } \
399         void set##proper(proper* child) { \
400             prepareForAssignment(m_##proper,child); \
401             *m_pos_##proper = m_##proper = child; \
402         }
403
404 /**
405  * Implements get/set methods and a private list iterator member for a generic XML child object.
406  * 
407  * @param proper    the proper name of the child
408  */
409 #define IMPL_XMLOBJECT_CHILD(proper) \
410     protected: \
411         xmltooling::XMLObject* m_##proper; \
412         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
413     public: \
414         xmltooling::XMLObject* get##proper() const { \
415             return m_##proper; \
416         } \
417         void set##proper(xmltooling::XMLObject* child) { \
418             prepareForAssignment(m_##proper,child); \
419             *m_pos_##proper = m_##proper = child; \
420         }
421
422 /**
423  * Declares abstract get/set methods for a typed XML child collection.
424  * 
425  * @param proper    the proper name of the child type
426  */
427 #define DECL_TYPED_CHILDREN(proper) \
428     public: \
429         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
430         virtual VectorOf(proper) get##proper##s()=0; \
431         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
432         virtual const std::vector<proper*>& get##proper##s() const=0
433
434 /**
435  * Declares abstract get/set methods for a generic XML child collection.
436  * 
437  * @param proper    the proper name of the child
438  */
439 #define DECL_XMLOBJECT_CHILDREN(proper) \
440     public: \
441         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
442         virtual VectorOf(xmltooling::XMLObject) get##proper##s()=0; \
443         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
444         virtual const std::vector<xmltooling::XMLObject*>& get##proper##s() const=0
445
446 /**
447  * Implements get method and a private vector member for a typed XML child collection.
448  * 
449  * @param proper    the proper name of the child type
450  * @param fence     insertion fence for new objects of the child collection in backing list
451  */
452 #define IMPL_TYPED_CHILDREN(proper,fence) \
453     protected: \
454         std::vector<proper*> m_##proper##s; \
455     public: \
456         VectorOf(proper) get##proper##s() { \
457             return VectorOf(proper)(this, m_##proper##s, &m_children, fence); \
458         } \
459         const std::vector<proper*>& get##proper##s() const { \
460             return m_##proper##s; \
461         } 
462
463 /**
464  * Implements get method and a private vector member for a generic XML child collection.
465  * 
466  * @param proper    the proper name of the child
467  * @param fence     insertion fence for new objects of the child collection in backing list
468  */
469 #define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
470     protected: \
471         std::vector<xmltooling::XMLObject*> m_##proper##s; \
472     public: \
473         VectorOf(xmltooling::XMLObject) get##proper##s() { \
474             return VectorOf(xmltooling::XMLObject)(this, m_##proper##s, &m_children, fence); \
475         } \
476         const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
477             return m_##proper##s; \
478         } 
479
480 /**
481  * Implements marshalling for a string attribute
482  * 
483  * @param proper        the proper name of the attribute
484  * @param ucase         the upcased name of the attribute
485  * @param namespaceURI  the XML namespace of the attribute
486  */
487 #define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
488     if(get##proper()) { \
489         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()); \
490     }
491
492 /**
493  * Implements marshalling for a DateTime attribute
494  * 
495  * @param proper        the proper name of the attribute
496  * @param ucase         the upcased name of the attribute
497  * @param namespaceURI  the XML namespace of the attribute
498  */
499 #define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
500     if(get##proper()) { \
501         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()->getRawData()); \
502     }
503
504 /**
505  * Implements marshalling for an integer attribute
506  * 
507  * @param proper        the proper name of the attribute
508  * @param ucase         the upcased name of the attribute
509  * @param namespaceURI  the XML namespace of the attribute
510  */
511 #define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
512     char buf##proper[64]; \
513     sprintf(buf##proper,"%d",get##proper()); \
514     auto_ptr_XMLCh wide##proper(buf##proper); \
515     domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, wide##proper.get())
516
517 /**
518  * Implements marshalling for a QName attribute
519  * 
520  * @param proper        the proper name of the attribute
521  * @param ucase         the upcased name of the attribute
522  * @param namespaceURI  the XML namespace of the attribute
523  */
524 #define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
525     if(get##proper()) { \
526         auto_ptr_XMLCh qstr(get##proper()->toString().c_str()); \
527         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
528     }
529
530 /**
531  * Implements marshalling for an ID attribute
532  * 
533  * @param proper        the proper name of the attribute
534  * @param ucase         the upcased name of the attribute
535  * @param namespaceURI  the XML namespace of the attribute
536  */
537 #define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
538     if(get##proper()) { \
539         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, get##proper()); \
540         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
541     }
542
543 /**
544  * Implements unmarshalling process branch for a string attribute
545  * 
546  * @param proper        the proper name of the attribute
547  * @param ucase         the upcased name of the attribute
548  * @param namespaceURI  the XML namespace of the attribute
549  */
550 #define PROC_STRING_ATTRIB(proper,ucase,namespaceURI) \
551     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
552         set##proper(attribute->getValue()); \
553         return; \
554     }
555
556 /**
557  * Implements unmarshalling process branch for an ID attribute
558  * 
559  * @param proper        the proper name of the attribute
560  * @param ucase         the upcased name of the attribute
561  * @param namespaceURI  the XML namespace of the attribute
562  */
563 #define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
564     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
565         set##proper(attribute->getValue()); \
566         static_cast<DOMElement*>(attribute->getParentNode())->setIdAttributeNode(attribute); \
567         return; \
568     }
569
570 /**
571  * Implements unmarshalling process branch for a DateTime attribute
572  * 
573  * @param proper        the proper name of the attribute
574  * @param ucase         the upcased name of the attribute
575  * @param namespaceURI  the XML namespace of the attribute
576  */
577 #define PROC_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
578     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
579
580 /**
581  * Implements unmarshalling process branch for a DateTime attribute
582  * 
583  * @param proper        the proper name of the attribute
584  * @param ucase         the upcased name of the attribute
585  * @param namespaceURI  the XML namespace of the attribute
586  */
587 #define PROC_QNAME_ATTRIB(proper,ucase,namespaceURI) \
588     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
589         set##proper(XMLHelper::getAttributeValueAsQName(attribute)); \
590         return; \
591     }
592
593 /**
594  * Implements unmarshalling process branch for an integer attribute
595  * 
596  * @param proper        the proper name of the attribute
597  * @param ucase         the upcased name of the attribute
598  * @param namespaceURI  the XML namespace of the attribute
599  */
600 #define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
601     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
602         set##proper(XMLString::parseInt(attribute->getValue())); \
603         return; \
604     }
605
606
607 /**
608  * Implements unmarshalling process branch for typed child collection element
609  * 
610  * @param proper        the proper name of the child type
611  * @param namespaceURI  the XML namespace of the child element
612  * @param force         bypass use of hint and just cast down to check child
613  */
614 #define PROC_TYPED_CHILDREN(proper,namespaceURI,force) \
615     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
616         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
617         if (typesafe) { \
618             get##proper##s().push_back(typesafe); \
619             return; \
620         } \
621     }
622
623 /**
624  * Implements unmarshalling process branch for typed child singleton element
625  * 
626  * @param proper        the proper name of the child type
627  * @param namespaceURI  the XML namespace of the child element
628  * @param force         bypass use of hint and just cast down to check child
629  */
630 #define PROC_TYPED_CHILD(proper,namespaceURI,force) \
631     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
632         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
633         if (typesafe) { \
634             set##proper(typesafe); \
635             return; \
636         } \
637     }
638
639 /**
640  * Declares aliased get/set methods for named XML element content.
641  * 
642  * @param proper    the proper name to label the element's content
643  */
644 #define DECL_XMLOBJECT_CONTENT(proper) \
645     XMLTOOLING_DOXYGEN(Returns proper.) \
646     const XMLCh* get##proper() const { \
647         return getTextContent(); \
648     } \
649     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
650     void set##proper(const XMLCh* proper) { \
651         setTextContent(proper); \
652     }
653
654 /**
655  * Implements marshalling/unmarshalling for element content.
656  */
657 #define IMPL_XMLOBJECT_CONTENT \
658     protected: \
659         void marshallElementContent(DOMElement* domElement) const { \
660             if(getTextContent()) { \
661                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent())); \
662             } \
663         } \
664         void processElementContent(const XMLCh* elementContent) { \
665             setTextContent(elementContent); \
666         }
667
668
669 /**
670  * Implements cloning methods for an XMLObject specialization implementation class.
671  * 
672  * @param cname    the name of the XMLObject specialization
673  */
674 #define IMPL_XMLOBJECT_CLONE(cname) \
675     cname* clone##cname() const { \
676         return clone(); \
677     } \
678     cname* clone() const { \
679         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
680         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
681         if (ret) { \
682             domClone.release(); \
683             return ret; \
684         } \
685         return new cname##Impl(*this); \
686     }
687
688 /**
689  * Declares an XMLObject specialization with a simple content model and type,
690  * handling it as string data.
691  * 
692  * @param linkage   linkage specifier for the class
693  * @param cname     the name of the XMLObject specialization
694  * @param proper    the proper name to label the element's content
695  * @param desc      documentation for class
696  */
697 #define DECL_XMLOBJECT_SIMPLE(linkage,cname,proper,desc) \
698     BEGIN_XMLOBJECT(linkage,cname,xmltooling::SimpleElement,desc); \
699         DECL_XMLOBJECT_CONTENT(proper); \
700     END_XMLOBJECT
701
702 /**
703  * Declares and defines an implementation class for an XMLObject with
704  * a simple content model and type, handling it as string data.
705  * 
706  * @param linkage   linkage specifier for the class
707  * @param cname     the name of the XMLObject specialization
708  */
709 #define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
710     class linkage cname##Impl \
711         : public virtual cname, \
712             public xmltooling::AbstractSimpleElement, \
713             public xmltooling::AbstractChildlessElement, \
714             public xmltooling::AbstractDOMCachingXMLObject, \
715             public xmltooling::AbstractValidatingXMLObject, \
716             public xmltooling::AbstractXMLObjectMarshaller, \
717             public xmltooling::AbstractXMLObjectUnmarshaller \
718     { \
719     public: \
720         virtual ~cname##Impl() {} \
721         cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) \
722             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
723         } \
724         cname##Impl(const cname##Impl& src) \
725             : xmltooling::AbstractXMLObject(src), \
726                 xmltooling::AbstractSimpleElement(src), \
727                 xmltooling::AbstractDOMCachingXMLObject(src), \
728                 xmltooling::AbstractValidatingXMLObject(src) {} \
729         IMPL_XMLOBJECT_CLONE(cname) \
730         IMPL_XMLOBJECT_CONTENT \
731     }
732     
733 /**
734  * Begins the declaration of an XMLObjectBuilder specialization.
735  * Basic boilerplate includes an empty virtual destructor, and
736  * a default builder that defaults the element name.
737  * 
738  * @param linkage           linkage specifier for the class
739  * @param cname             the name of the XMLObject specialization
740  * @param namespaceURI      the XML namespace of the default associated element
741  * @param namespacePrefix   the XML namespace prefix of the default associated element
742  */
743 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
744     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
745     class linkage cname##Builder : public xmltooling::XMLObjectBuilder { \
746     public: \
747         virtual ~cname##Builder() {} \
748         XMLTOOLING_DOXYGEN(Default builder.) \
749         virtual cname* buildObject() const { \
750             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
751         } \
752         virtual cname* buildObject( \
753             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL \
754             ) const
755
756 /**
757  * Ends the declaration of an XMLObjectBuilder specialization.
758  */
759 #define END_XMLOBJECTBUILDER }
760
761 /**
762  * Declares a generic XMLObjectBuilder specialization.
763  * 
764  * @param linkage           linkage specifier for the class
765  * @param cname             the name of the XMLObject specialization
766  * @param namespaceURI      the XML namespace of the default associated element
767  * @param namespacePrefix   the XML namespace prefix of the default associated element
768  */
769  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
770     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
771     XMLTOOLING_DOXYGEN(Singleton builder.) \
772     static cname* new##cname() { \
773         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
774             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
775             ); \
776         if (b) \
777             return b->buildObject(); \
778         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
779     } \
780     END_XMLOBJECTBUILDER
781
782 /**
783  * Implements the standard XMLObjectBuilder specialization function. 
784  * 
785  * @param cname the name of the XMLObject specialization
786  */
787 #define IMPL_XMLOBJECTBUILDER(cname) \
788     cname* cname##Builder::buildObject( \
789         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \
790         ) const \
791     { \
792         return new cname##Impl(nsURI,localName,prefix,schemaType); \
793     }
794
795 /**
796  * Begins the declaration of a Schema Validator specialization.
797  * 
798  * @param linkage           linkage specifier for the class
799  * @param cname the base name of the Validator specialization
800  */
801  #define BEGIN_XMLOBJECTVALIDATOR(linkage,cname) \
802     class linkage cname##SchemaValidator : public xmltooling::Validator \
803     { \
804     public: \
805         virtual ~cname##SchemaValidator() {} \
806         virtual cname##SchemaValidator* clone() const { \
807             return new cname##SchemaValidator(); \
808         } \
809         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
810             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
811             if (!ptr) \
812                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
813
814 /**
815  * Ends the declaration of a Validator specialization.
816  */
817 #define END_XMLOBJECTVALIDATOR } }
818
819 /**
820  * Validator code that checks the object type.
821  * 
822  * @param cname     the name of the XMLObject specialization
823  */
824 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
825     const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
826     if (!ptr) \
827         throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
828
829 /**
830  * Validator code that checks for a required attribute, content, or singleton.
831  * 
832  * @param cname     the name of the XMLObject specialization
833  * @param proper    the proper name of the attribute, content, or singleton member 
834  */
835 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
836     if (!ptr->get##proper()) \
837         throw xmltooling::ValidationException(#cname" must have "#proper".")
838
839 /**
840  * Validator code that checks for one of a pair of
841  * required attributes, content, or singletons.
842  * 
843  * @param cname     the name of the XMLObject specialization
844  * @param proper1   the proper name of the first attribute, content, or singleton member 
845  * @param proper2   the proper name of the second attribute, content, or singleton member 
846  */
847 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
848     if (!ptr->get##proper1() && !ptr->get##proper2()) \
849         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
850
851 /**
852  * Validator code that checks for one of a pair of
853  * required attributes, content, or singletons, but disallows both.
854  * 
855  * @param cname     the name of the XMLObject specialization
856  * @param proper1   the proper name of the first attribute, content, or singleton member 
857  * @param proper2   the proper name of the second attribute, content, or singleton member 
858  */
859 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
860     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
861         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
862
863 /**
864  * Validator code that checks for one of a set of three
865  * required attributes, content, or singletons.
866  * 
867  * @param cname     the name of the XMLObject specialization
868  * @param proper1   the proper name of the first attribute, content, or singleton member
869  * @param proper2   the proper name of the second attribute, content, or singleton member
870  * @param proper3   the proper name of the third attribute, content, or singleton member
871  */
872 #define XMLOBJECTVALIDATOR_ONEOF3(cname,proper1,proper2,proper3) \
873     if (!ptr->get##proper1() && !ptr->get##proper2() && !ptr->get##proper3()) \
874         throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
875
876 /**
877  * Validator code that checks for one of a set of three
878  * required attributes, content, or singletons but disallows more than one.
879  * 
880  * @param cname     the name of the XMLObject specialization
881  * @param proper1   the proper name of the first attribute, content, or singleton member
882  * @param proper2   the proper name of the second attribute, content, or singleton member
883  * @param proper3   the proper name of the third attribute, content, or singleton member
884  */
885 #define XMLOBJECTVALIDATOR_ONLYONEOF3(cname,proper1,proper2,proper3) \
886     int c##proper1##proper2##proper3=0; \
887     if (ptr->get##proper1()!=NULL) \
888         c##proper1##proper2##proper3++; \
889     if (ptr->get##proper2()!=NULL) \
890         c##proper1##proper2##proper3++; \
891     if (ptr->get##proper3()!=NULL) \
892         c##proper1##proper2##proper3++; \
893     if (c##proper1##proper2##proper3 != 1) \
894         throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
895
896 /**
897  * Validator code that checks a co-constraint (if one present, the other must be)
898  * between a pair of attributes, content, or singletons.
899  * 
900  * @param cname     the name of the XMLObject specialization
901  * @param proper1   the proper name of the first attribute, content, or singleton member 
902  * @param proper2   the proper name of the second attribute, content, or singleton member 
903  */
904 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
905     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
906         throw xmltooling::ValidationException(#cname" cannot have "#proper1" without "#proper2".")
907
908 /**
909  * Validator code that checks for a non-empty collection.
910  * 
911  * @param cname     the name of the XMLObject specialization
912  * @param proper    the proper name of the collection item 
913  */
914 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
915     if (ptr->get##proper##s().empty()) \
916         throw xmltooling::ValidationException(#cname" must have at least one "#proper".")
917
918 /**
919  * Declares/defines a Validator specialization that checks object type and
920  * a non-empty simple content model.
921  * 
922  * @param linkage   linkage specifier for the class
923  * @param cname     the name of the XMLObject specialization
924  */
925 #define XMLOBJECTVALIDATOR_SIMPLE(linkage,cname) \
926     BEGIN_XMLOBJECTVALIDATOR(linkage,cname); \
927         XMLOBJECTVALIDATOR_REQUIRE(cname,TextContent); \
928     END_XMLOBJECTVALIDATOR
929
930 #include <utility>
931
932 /**
933  * @namespace xmltooling
934  * Public namespace of XML Tooling library
935  */
936 namespace xmltooling {
937
938     /**
939      * Template function for cloning a sequence of XMLObjects.
940      * Invokes the clone() member on each element of the input sequence and adds the copy to
941      * the output sequence. Order is preserved.
942      * 
943      * @param in    input sequence to clone
944      * @param out   output sequence to copy cloned pointers into
945      */
946     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
947         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
948             if (*i)
949                 out.push_back((*i)->clone());
950             else
951                 out.push_back(*i);
952         }
953     }
954
955     /**
956      * Functor for cleaning up heap objects in containers.
957      */
958     template<class T> struct cleanup
959     {
960         /**
961          * Function operator to delete an object.
962          * 
963          * @param ptr   object to delete
964          */
965         void operator()(T* ptr) {delete ptr;}
966         
967         /**
968          * Function operator to delete an object stored as const.
969          * 
970          * @param ptr   object to delete after casting away const
971          */
972         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
973     };
974
975     /**
976      * Functor for cleaning up heap objects in key/value containers.
977      */
978     template<class A,class B> struct cleanup_pair
979     {
980         /**
981          * Function operator to delete an object.
982          * 
983          * @param p   a pair in which the second component is the object to delete
984          */
985         void operator()(const std::pair<A,B*>& p) {delete p.second;}
986     };
987 };
988
989 #endif /* __xmltooling_base_h__ */