Update copyright.
[shibboleth/cpp-xmltooling.git] / xmltooling / base.h
1 /*
2  *  Copyright 2001-2007 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 #define UNICODE_LITERAL_33(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,gg) \
188     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
189         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
190         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
191         chLatin_##aa, chLatin_##bb, chLatin_##cc, chLatin_##dd, chLatin_##ee, chLatin_##ff, chLatin_##gg, chNull}
192 #define UNICODE_LITERAL_34(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,gg,hh) \
193     {chLatin_##a, chLatin_##b, chLatin_##c, chLatin_##d, chLatin_##e, chLatin_##f, chLatin_##g, chLatin_##h, chLatin_##i, \
194         chLatin_##j, chLatin_##k, chLatin_##l, chLatin_##m, chLatin_##n, chLatin_##o, chLatin_##p, chLatin_##q, chLatin_##r, \
195         chLatin_##s, chLatin_##t, chLatin_##u, chLatin_##v, chLatin_##w, chLatin_##x, chLatin_##y, chLatin_##z, \
196         chLatin_##aa, chLatin_##bb, chLatin_##cc, chLatin_##dd, chLatin_##ee, chLatin_##ff, chLatin_##gg, chLatin_##hh, chNull}
197 #endif /* DOXYGEN_SKIP */
198
199 /**
200  * Begins the declaration of an XMLObject specialization for an abstract element/type.
201  * Basic boilerplate includes a protected constructor, empty virtual destructor,
202  * and Unicode constants for the default associated element's name and prefix.
203  * 
204  * @param linkage   linkage specifier for the class
205  * @param cname     the name of the class to declare
206  * @param base      the base class to derive from using public virtual inheritance
207  * @param desc      documentation comment for class
208  */
209 #define DECL_XMLOBJECT_ABSTRACT(linkage,cname,base,desc) \
210     XMLTOOLING_DOXYGEN(desc) \
211     class linkage cname : public virtual base { \
212     protected: \
213         cname() {} \
214     public: \
215         virtual ~cname() {} \
216         XMLTOOLING_DOXYGEN(Element local name) \
217         static const XMLCh LOCAL_NAME[]; \
218     }
219
220 /**
221  * Begins the declaration of an XMLObject specialization.
222  * Basic boilerplate includes a protected constructor, empty virtual destructor,
223  * and Unicode constants for the default associated element's name and prefix.
224  * 
225  * @param linkage   linkage specifier for the class
226  * @param cname     the name of the class to declare
227  * @param base      the base class to derive from using public virtual inheritance
228  * @param desc      documentation comment for class
229  */
230 #define BEGIN_XMLOBJECT(linkage,cname,base,desc) \
231     XMLTOOLING_DOXYGEN(desc) \
232     class linkage cname : public virtual base { \
233     protected: \
234         cname() {} \
235     public: \
236         virtual ~cname() {} \
237         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
238         virtual cname* clone##cname() const=0; \
239         XMLTOOLING_DOXYGEN(Element local name) \
240         static const XMLCh LOCAL_NAME[]
241
242 /**
243  * Begins the declaration of an XMLObject specialization with two base classes.
244  * Basic boilerplate includes a protected constructor, empty virtual destructor,
245  * and Unicode constants for the default associated element's name and prefix.
246  * 
247  * @param linkage   linkage specifier for the class
248  * @param cname     the name of the class to declare
249  * @param base      the first base class to derive from using public virtual inheritance
250  * @param base2     the second base class to derive from using public virtual inheritance
251  * @param desc      documentation comment for class
252  */
253 #define BEGIN_XMLOBJECT2(linkage,cname,base,base2,desc) \
254     XMLTOOLING_DOXYGEN(desc) \
255     class linkage cname : public virtual base, public virtual base2 { \
256     protected: \
257         cname() {} \
258     public: \
259         virtual ~cname() {} \
260         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
261         virtual cname* clone##cname() const=0; \
262         XMLTOOLING_DOXYGEN(Element local name) \
263         static const XMLCh LOCAL_NAME[]
264
265 /**
266  * Begins the declaration of an XMLObject specialization with three base classes.
267  * Basic boilerplate includes a protected constructor, empty virtual destructor,
268  * and Unicode constants for the default associated element's name and prefix.
269  * 
270  * @param linkage   linkage specifier for the class
271  * @param cname     the name of the class to declare
272  * @param base      the first base class to derive from using public virtual inheritance
273  * @param base2     the second base class to derive from using public virtual inheritance
274  * @param base3     the third base class to derive from using public virtual inheritance
275  * @param desc      documentation comment for class
276  */
277 #define BEGIN_XMLOBJECT3(linkage,cname,base,base2,base3,desc) \
278     XMLTOOLING_DOXYGEN(desc) \
279     class linkage cname : public virtual base, public virtual base2, public virtual base3 { \
280     protected: \
281         cname() {} \
282     public: \
283         virtual ~cname() {} \
284         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
285         virtual cname* clone##cname() const=0; \
286         XMLTOOLING_DOXYGEN(Element local name) \
287         static const XMLCh LOCAL_NAME[]
288
289 /**
290  * Begins the declaration of an XMLObject specialization with four base classes.
291  * Basic boilerplate includes a protected constructor, empty virtual destructor,
292  * and Unicode constants for the default associated element's name and prefix.
293  * 
294  * @param linkage   linkage specifier for the class
295  * @param cname     the name of the class to declare
296  * @param base      the first base class to derive from using public virtual inheritance
297  * @param base2     the second base class to derive from using public virtual inheritance
298  * @param base3     the third base class to derive from using public virtual inheritance
299  * @param base4     the fourth base class to derive from using public virtual inheritance
300  * @param desc      documentation comment for class
301  */
302 #define BEGIN_XMLOBJECT4(linkage,cname,base,base2,base3,base4,desc) \
303     XMLTOOLING_DOXYGEN(desc) \
304     class linkage cname : public virtual base, public virtual base2, public virtual base3, public virtual base4 { \
305     protected: \
306         cname() {} \
307     public: \
308         virtual ~cname() {} \
309         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
310         virtual cname* clone##cname() const=0; \
311         XMLTOOLING_DOXYGEN(Element local name) \
312         static const XMLCh LOCAL_NAME[]
313
314 /**
315  * Begins the declaration of an XMLObject specialization with five base classes.
316  * Basic boilerplate includes a protected constructor, empty virtual destructor,
317  * and Unicode constants for the default associated element's name and prefix.
318  * 
319  * @param linkage   linkage specifier for the class
320  * @param cname     the name of the class to declare
321  * @param base      the first base class to derive from using public virtual inheritance
322  * @param base2     the second base class to derive from using public virtual inheritance
323  * @param base3     the third base class to derive from using public virtual inheritance
324  * @param base4     the fourth base class to derive from using public virtual inheritance
325  * @param base5     the fifth base class to derive from using public virtual inheritance
326  * @param desc      documentation comment for class
327  */
328 #define BEGIN_XMLOBJECT5(linkage,cname,base,base2,base3,base4,base5,desc) \
329     XMLTOOLING_DOXYGEN(desc) \
330     class linkage cname : public virtual base, public virtual base2, public virtual base3, public virtual base4, public virtual base5 { \
331     protected: \
332         cname() {} \
333     public: \
334         virtual ~cname() {} \
335         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
336         virtual cname* clone##cname() const=0; \
337         XMLTOOLING_DOXYGEN(Element local name) \
338         static const XMLCh LOCAL_NAME[]
339
340 /**
341  * Ends the declaration of an XMLObject specialization.
342  */
343 #define END_XMLOBJECT }
344
345 /**
346  * Declares abstract set method for a typed XML attribute.
347  * The get method is omitted.
348  * 
349  * @param proper    the proper name of the attribute
350  * @param upcased   the upcased name of the attribute
351  * @param type      the attribute's data type
352  */
353 #define DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,type) \
354     public: \
355         XMLTOOLING_DOXYGEN(proper attribute name) \
356         static const XMLCh upcased##_ATTRIB_NAME[]; \
357         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
358         virtual void set##proper(const type* proper)=0
359
360 /**
361  * Declares abstract get/set methods for a typed XML attribute.
362  * 
363  * @param proper    the proper name of the attribute
364  * @param upcased   the upcased name of the attribute
365  * @param type      the attribute's data type
366  */
367 #define DECL_XMLOBJECT_ATTRIB(proper,upcased,type) \
368     public: \
369         XMLTOOLING_DOXYGEN(proper attribute name) \
370         static const XMLCh upcased##_ATTRIB_NAME[]; \
371         XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
372         virtual const type* get##proper() const=0; \
373         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
374         virtual void set##proper(const type* proper)=0
375
376 /**
377  * Declares abstract set method for a string XML attribute.
378  * The get method is omitted.
379  * 
380  * @param proper    the proper name of the attribute
381  * @param upcased   the upcased name of the attribute
382  */
383 #define DECL_INHERITED_STRING_ATTRIB(proper,upcased) \
384     DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
385
386 /**
387  * Declares abstract get/set methods for a string XML attribute.
388  * 
389  * @param proper    the proper name of the attribute
390  * @param upcased   the upcased name of the attribute
391  */
392 #define DECL_STRING_ATTRIB(proper,upcased) \
393     DECL_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
394
395 /**
396  * Declares abstract set method for a DateTime XML attribute.
397  * The get method is omitted.
398  * 
399  * @param proper    the proper name of the attribute
400  * @param upcased   the upcased name of the attribute
401  */
402 #define DECL_INHERITED_DATETIME_ATTRIB(proper,upcased) \
403     DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
404     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
405     virtual void set##proper(time_t proper)=0; \
406     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
407     virtual void set##proper(const XMLCh* proper)=0
408
409 /**
410  * Declares abstract get/set methods for a DateTime XML attribute.
411  * 
412  * @param proper    the proper name of the attribute
413  * @param upcased   the upcased name of the attribute
414  */
415 #define DECL_DATETIME_ATTRIB(proper,upcased) \
416     DECL_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
417     XMLTOOLING_DOXYGEN(Returns the proper attribute in epoch form.) \
418     virtual time_t get##proper##Epoch() const=0; \
419     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
420     virtual void set##proper(time_t proper)=0; \
421     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
422     virtual void set##proper(const XMLCh* proper)=0
423
424 /**
425  * Declares abstract set method for an integer XML attribute.
426  * The get method is omitted.
427  * 
428  * @param proper    the proper name of the attribute
429  * @param upcased   the upcased name of the attribute
430  */
431 #define DECL_INHERITED_INTEGER_ATTRIB(proper,upcased) \
432     public: \
433         XMLTOOLING_DOXYGEN(proper attribute name) \
434         static const XMLCh upcased##_ATTRIB_NAME[]; \
435         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
436         virtual void set##proper(const XMLCh* proper)=0; \
437         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
438         virtual void set##proper(int proper)=0
439
440 /**
441  * Declares abstract get/set methods for an integer XML attribute.
442  * 
443  * @param proper    the proper name of the attribute
444  * @param upcased   the upcased name of the attribute
445  */
446 #define DECL_INTEGER_ATTRIB(proper,upcased) \
447     public: \
448         XMLTOOLING_DOXYGEN(proper attribute name) \
449         static const XMLCh upcased##_ATTRIB_NAME[]; \
450         XMLTOOLING_DOXYGEN(Returns the proper attribute after a NULL indicator.) \
451         virtual std::pair<bool,int> get##proper() const=0; \
452         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
453         virtual void set##proper(const XMLCh* proper)=0; \
454         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
455         virtual void set##proper(int proper)=0
456
457 /**
458  * Declares abstract get/set methods for a boolean XML attribute.
459  * 
460  * @param proper    the proper name of the attribute
461  * @param upcased   the upcased name of the attribute
462  * @param def       the default/presumed value, if no explicit value has been set
463  */
464 #define DECL_BOOLEAN_ATTRIB(proper,upcased,def) \
465     public: \
466         XMLTOOLING_DOXYGEN(proper attribute name) \
467         static const XMLCh upcased##_ATTRIB_NAME[]; \
468         XMLTOOLING_DOXYGEN(Returns the proper attribute or def if not set.) \
469         bool proper() const { \
470             switch (get##proper()) { \
471                 case xmlconstants::XML_BOOL_TRUE: \
472                 case xmlconstants::XML_BOOL_ONE: \
473                     return true; \
474                 case xmlconstants::XML_BOOL_FALSE: \
475                 case xmlconstants::XML_BOOL_ZERO: \
476                     return false; \
477                 default: \
478                     return def; \
479             } \
480         } \
481         XMLTOOLING_DOXYGEN(Returns the proper attribute as an explicit enumerated value.) \
482         virtual xmlconstants::xmltooling_bool_t get##proper() const=0; \
483         XMLTOOLING_DOXYGEN(Sets the proper attribute using an enumerated value.) \
484         virtual void proper(xmlconstants::xmltooling_bool_t value)=0; \
485         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
486         void proper(bool value) { \
487             proper(value ? xmlconstants::XML_BOOL_ONE : xmlconstants::XML_BOOL_ZERO); \
488         } \
489         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string constant.) \
490         void set##proper(const XMLCh* value) { \
491             if (value) { \
492                 switch (*value) { \
493                     case chLatin_t: \
494                         proper(xmlconstants::XML_BOOL_TRUE); \
495                         break; \
496                     case chLatin_f: \
497                         proper(xmlconstants::XML_BOOL_FALSE); \
498                         break; \
499                     case chDigit_1: \
500                         proper(xmlconstants::XML_BOOL_ONE); \
501                         break; \
502                     case chDigit_0: \
503                         proper(xmlconstants::XML_BOOL_ZERO); \
504                         break; \
505                     default: \
506                         proper(xmlconstants::XML_BOOL_NULL); \
507                 } \
508             } \
509             else \
510                 proper(xmlconstants::XML_BOOL_NULL); \
511         }
512
513 /**
514  * Implements get/set methods and a private member for a typed XML attribute.
515  * 
516  * @param proper    the proper name of the attribute
517  * @param type      the attribute's data type
518  */
519 #define IMPL_XMLOBJECT_ATTRIB(proper,type) \
520     protected: \
521         type* m_##proper; \
522     public: \
523         const type* get##proper() const { \
524             return m_##proper; \
525         } \
526         void set##proper(const type* proper) { \
527             m_##proper = prepareForAssignment(m_##proper,proper); \
528         }
529
530 /**
531  * Implements get/set methods and a private member for a string XML attribute.
532  * 
533  * @param proper    the proper name of the attribute
534  */
535 #define IMPL_STRING_ATTRIB(proper) \
536     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
537
538 /**
539  * Implements get/set methods and a private member for a string XML attribute,
540  * plus a getXMLID override.
541  * 
542  * @param proper    the proper name of the attribute
543  */
544 #define IMPL_ID_ATTRIB(proper) \
545     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
546     const XMLCh* getXMLID() const { \
547         return m_##proper; \
548     }
549
550 /**
551  * Implements get/set methods and a private member for a DateTime XML attribute.
552  * 
553  * @param proper    the proper name of the attribute
554  * @param fallback  epoch to return when attribute is NULL
555  */
556 #define IMPL_DATETIME_ATTRIB(proper,fallback) \
557     protected: \
558         DateTime* m_##proper; \
559         time_t m_##proper##Epoch; \
560     public: \
561         const DateTime* get##proper() const { \
562             return m_##proper; \
563         } \
564         time_t get##proper##Epoch() const { \
565             return m_##proper ? m_##proper##Epoch : fallback; \
566         } \
567         void set##proper(const DateTime* proper) { \
568             m_##proper = prepareForAssignment(m_##proper,proper); \
569             if (m_##proper) \
570                 m_##proper##Epoch=m_##proper->getEpoch(); \
571         } \
572         void set##proper(time_t proper) { \
573             m_##proper = prepareForAssignment(m_##proper,proper); \
574             m_##proper##Epoch = proper; \
575         } \
576         void set##proper(const XMLCh* proper) { \
577             m_##proper = prepareForAssignment(m_##proper,proper); \
578             if (m_##proper) \
579                 m_##proper##Epoch=m_##proper->getEpoch(); \
580         }
581
582 /**
583  * Implements get/set methods and a private member for an integer XML attribute.
584  * 
585  * @param proper    the proper name of the attribute
586  */
587 #define IMPL_INTEGER_ATTRIB(proper) \
588     protected: \
589         XMLCh* m_##proper; \
590     public: \
591         pair<bool,int> get##proper() const { \
592             return make_pair((m_##proper!=NULL),(m_##proper!=NULL ? XMLString::parseInt(m_##proper): 0)); \
593         } \
594         void set##proper(const XMLCh* proper) { \
595             m_##proper = prepareForAssignment(m_##proper,proper); \
596         } \
597         void set##proper(int proper) { \
598             char buf##proper[64]; \
599             sprintf(buf##proper,"%d",proper); \
600             auto_ptr_XMLCh wide##proper(buf##proper); \
601             set##proper(wide##proper.get()); \
602         }
603
604 /**
605  * Implements get/set methods and a private member for a boolean XML attribute.
606  * 
607  * @param proper    the proper name of the attribute
608  */
609 #define IMPL_BOOLEAN_ATTRIB(proper) \
610     protected: \
611         xmlconstants::xmltooling_bool_t m_##proper; \
612     public: \
613         xmlconstants::xmltooling_bool_t get##proper() const { \
614             return m_##proper; \
615         } \
616         void proper(xmlconstants::xmltooling_bool_t value) { \
617             if (m_##proper != value) { \
618                 releaseThisandParentDOM(); \
619                 m_##proper = value; \
620             } \
621         }
622
623 /**
624  * Declares abstract set method for a typed XML child object in a foreign namespace.
625  * The get method is omitted.
626  * 
627  * @param proper    the proper name of the child type
628  * @param ns        the C++ namespace for the type
629  */
630 #define DECL_INHERITED_TYPED_FOREIGN_CHILD(proper,ns) \
631     public: \
632         XMLTOOLING_DOXYGEN(Sets the proper child.) \
633         virtual void set##proper(ns::proper* child)=0
634
635 /**
636  * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
637  * 
638  * @param proper    the proper name of the child type
639  * @param ns        the C++ namespace for the type
640  */
641 #define DECL_TYPED_FOREIGN_CHILD(proper,ns) \
642     public: \
643         XMLTOOLING_DOXYGEN(Returns the proper child.) \
644         virtual ns::proper* get##proper() const=0; \
645         XMLTOOLING_DOXYGEN(Sets the proper child.) \
646         virtual void set##proper(ns::proper* child)=0
647
648 /**
649  * Declares abstract set method for a typed XML child object.
650  * The get method is omitted.
651  * 
652  * @param proper    the proper name of the child type
653  */
654 #define DECL_INHERITED_TYPED_CHILD(proper) \
655     public: \
656         XMLTOOLING_DOXYGEN(Sets the proper child.) \
657         virtual void set##proper(proper* child)=0
658
659 /**
660  * Declares abstract get/set methods for a typed XML child object.
661  * 
662  * @param proper    the proper name of the child type
663  */
664 #define DECL_TYPED_CHILD(proper) \
665     public: \
666         XMLTOOLING_DOXYGEN(Returns the proper child.) \
667         virtual proper* get##proper() const=0; \
668         XMLTOOLING_DOXYGEN(Sets the proper child.) \
669         virtual void set##proper(proper* child)=0
670
671 /**
672  * Declares abstract get/set methods for a generic XML child object.
673  * 
674  * @param proper    the proper name of the child
675  */
676 #define DECL_XMLOBJECT_CHILD(proper) \
677     public: \
678         XMLTOOLING_DOXYGEN(Returns the proper child.) \
679         virtual xmltooling::XMLObject* get##proper() const=0; \
680         XMLTOOLING_DOXYGEN(Sets the proper child.) \
681         virtual void set##proper(xmltooling::XMLObject* child)=0
682
683
684 /**
685  * Implements get/set methods and a private list iterator member for a typed XML child object.
686  * 
687  * @param proper    the proper name of the child type
688  */
689 #define IMPL_TYPED_CHILD(proper) \
690     protected: \
691         proper* m_##proper; \
692         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
693     public: \
694         proper* get##proper() const { \
695             return m_##proper; \
696         } \
697         void set##proper(proper* child) { \
698             prepareForAssignment(m_##proper,child); \
699             *m_pos_##proper = m_##proper = child; \
700         }
701
702 /**
703  * Implements get/set methods and a private list iterator member for
704  * a typed XML child object in a foreign namespace
705  * 
706  * @param proper    the proper name of the child type
707  * @param ns        the C++ namespace for the type
708  */
709 #define IMPL_TYPED_FOREIGN_CHILD(proper,ns) \
710     protected: \
711         ns::proper* m_##proper; \
712         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
713     public: \
714         ns::proper* get##proper() const { \
715             return m_##proper; \
716         } \
717         void set##proper(ns::proper* child) { \
718             prepareForAssignment(m_##proper,child); \
719             *m_pos_##proper = m_##proper = child; \
720         }
721
722 /**
723  * Implements get/set methods and a private list iterator member for a generic XML child object.
724  * 
725  * @param proper    the proper name of the child
726  */
727 #define IMPL_XMLOBJECT_CHILD(proper) \
728     protected: \
729         xmltooling::XMLObject* m_##proper; \
730         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
731     public: \
732         xmltooling::XMLObject* get##proper() const { \
733             return m_##proper; \
734         } \
735         void set##proper(xmltooling::XMLObject* child) { \
736             prepareForAssignment(m_##proper,child); \
737             *m_pos_##proper = m_##proper = child; \
738         }
739
740 /**
741  * Declares abstract get/set methods for a typed XML child collection.
742  * 
743  * @param proper    the proper name of the child type
744  */
745 #define DECL_TYPED_CHILDREN(proper) \
746     public: \
747         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
748         virtual VectorOf(proper) get##proper##s()=0; \
749         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
750         virtual const std::vector<proper*>& get##proper##s() const=0
751
752 /**
753  * Declares abstract get/set methods for a typed XML child collection in a foreign namespace.
754  * 
755  * @param proper    the proper name of the child type
756  * @param ns        the C++ namespace for the type
757  */
758 #define DECL_TYPED_FOREIGN_CHILDREN(proper,ns) \
759     public: \
760         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
761         virtual VectorOf(ns::proper) get##proper##s()=0; \
762         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
763         virtual const std::vector<ns::proper*>& get##proper##s() const=0
764
765 /**
766  * Declares abstract get/set methods for a generic XML child collection.
767  * 
768  * @param proper    the proper name of the child
769  */
770 #define DECL_XMLOBJECT_CHILDREN(proper) \
771     public: \
772         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
773         virtual VectorOf(xmltooling::XMLObject) get##proper##s()=0; \
774         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
775         virtual const std::vector<xmltooling::XMLObject*>& get##proper##s() const=0
776
777 /**
778  * Implements get method and a private vector member for a typed XML child collection.
779  * 
780  * @param proper    the proper name of the child type
781  * @param fence     insertion fence for new objects of the child collection in backing list
782  */
783 #define IMPL_TYPED_CHILDREN(proper,fence) \
784     protected: \
785         std::vector<proper*> m_##proper##s; \
786     public: \
787         VectorOf(proper) get##proper##s() { \
788             return VectorOf(proper)(this, m_##proper##s, &m_children, fence); \
789         } \
790         const std::vector<proper*>& get##proper##s() const { \
791             return m_##proper##s; \
792         } 
793
794 /**
795  * Implements get method and a private vector member for a typed XML child collection
796  * in a foreign namespace.
797  * 
798  * @param proper    the proper name of the child type
799  * @param ns        the C++ namespace for the type
800  * @param fence     insertion fence for new objects of the child collection in backing list
801  */
802 #define IMPL_TYPED_FOREIGN_CHILDREN(proper,ns,fence) \
803     protected: \
804         std::vector<ns::proper*> m_##proper##s; \
805     public: \
806         VectorOf(ns::proper) get##proper##s() { \
807             return VectorOf(ns::proper)(this, m_##proper##s, &m_children, fence); \
808         } \
809         const std::vector<ns::proper*>& get##proper##s() const { \
810             return m_##proper##s; \
811         } 
812
813 /**
814  * Implements get method and a private vector member for a generic XML child collection.
815  * 
816  * @param proper    the proper name of the child
817  * @param fence     insertion fence for new objects of the child collection in backing list
818  */
819 #define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
820     protected: \
821         std::vector<xmltooling::XMLObject*> m_##proper##s; \
822     public: \
823         VectorOf(xmltooling::XMLObject) get##proper##s() { \
824             return VectorOf(xmltooling::XMLObject)(this, m_##proper##s, &m_children, fence); \
825         } \
826         const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
827             return m_##proper##s; \
828         } 
829
830 /**
831  * Implements marshalling for a string attribute
832  * 
833  * @param proper        the proper name of the attribute
834  * @param ucase         the upcased name of the attribute
835  * @param namespaceURI  the XML namespace of the attribute
836  */
837 #define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
838     if (m_##proper) { \
839         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
840     }
841
842 /**
843  * Implements marshalling for a DateTime attribute
844  * 
845  * @param proper        the proper name of the attribute
846  * @param ucase         the upcased name of the attribute
847  * @param namespaceURI  the XML namespace of the attribute
848  */
849 #define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
850     if (m_##proper) { \
851         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper->getRawData()); \
852     }
853
854 /**
855  * Implements marshalling for an integer attribute
856  * 
857  * @param proper        the proper name of the attribute
858  * @param ucase         the upcased name of the attribute
859  * @param namespaceURI  the XML namespace of the attribute
860  */
861 #define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
862     if (m_##proper) { \
863         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
864     }
865
866 /**
867  * Implements marshalling for a boolean attribute
868  * 
869  * @param proper        the proper name of the attribute
870  * @param ucase         the upcased name of the attribute
871  * @param namespaceURI  the XML namespace of the attribute
872  */
873 #define MARSHALL_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
874     switch (m_##proper) { \
875         case xmlconstants::XML_BOOL_TRUE: \
876             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_TRUE); \
877             break; \
878         case xmlconstants::XML_BOOL_ONE: \
879             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ONE); \
880             break; \
881         case xmlconstants::XML_BOOL_FALSE: \
882             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_FALSE); \
883             break; \
884         case xmlconstants::XML_BOOL_ZERO: \
885             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ZERO); \
886             break; \
887         case xmlconstants::XML_BOOL_NULL: \
888             break; \
889     }
890
891 /**
892  * Implements marshalling for a QName attribute
893  * 
894  * @param proper        the proper name of the attribute
895  * @param ucase         the upcased name of the attribute
896  * @param namespaceURI  the XML namespace of the attribute
897  */
898 #define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
899     if (m_##proper) { \
900         auto_ptr_XMLCh qstr(m_##proper->toString().c_str()); \
901         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
902     }
903
904 /**
905  * Implements marshalling for an ID attribute
906  * 
907  * @param proper        the proper name of the attribute
908  * @param ucase         the upcased name of the attribute
909  * @param namespaceURI  the XML namespace of the attribute
910  */
911 #define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
912     if (m_##proper) { \
913         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
914         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
915     }
916
917 /**
918  * Implements unmarshalling process branch for a string attribute
919  * 
920  * @param proper        the proper name of the attribute
921  * @param ucase         the upcased name of the attribute
922  * @param namespaceURI  the XML namespace of the attribute
923  */
924 #define PROC_STRING_ATTRIB(proper,ucase,namespaceURI) \
925     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
926         set##proper(attribute->getValue()); \
927         return; \
928     }
929
930 /**
931  * Implements unmarshalling process branch for an ID attribute
932  * 
933  * @param proper        the proper name of the attribute
934  * @param ucase         the upcased name of the attribute
935  * @param namespaceURI  the XML namespace of the attribute
936  */
937 #define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
938     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
939         set##proper(attribute->getValue()); \
940         attribute->getOwnerElement()->setIdAttributeNode(attribute); \
941         return; \
942     }
943
944 /**
945  * Implements unmarshalling process branch for a DateTime attribute
946  * 
947  * @param proper        the proper name of the attribute
948  * @param ucase         the upcased name of the attribute
949  * @param namespaceURI  the XML namespace of the attribute
950  */
951 #define PROC_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
952     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
953
954 /**
955  * Implements unmarshalling process branch for a DateTime attribute
956  * 
957  * @param proper        the proper name of the attribute
958  * @param ucase         the upcased name of the attribute
959  * @param namespaceURI  the XML namespace of the attribute
960  */
961 #define PROC_QNAME_ATTRIB(proper,ucase,namespaceURI) \
962     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
963         set##proper(XMLHelper::getAttributeValueAsQName(attribute)); \
964         return; \
965     }
966
967 /**
968  * Implements unmarshalling process branch for an integer attribute
969  * 
970  * @param proper        the proper name of the attribute
971  * @param ucase         the upcased name of the attribute
972  * @param namespaceURI  the XML namespace of the attribute
973  */
974 #define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
975     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
976
977 /**
978  * Implements unmarshalling process branch for a boolean attribute
979  * 
980  * @param proper        the proper name of the attribute
981  * @param ucase         the upcased name of the attribute
982  * @param namespaceURI  the XML namespace of the attribute
983  */
984 #define PROC_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
985     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
986
987 /**
988  * Implements unmarshalling process branch for typed child collection element
989  * 
990  * @param proper        the proper name of the child type
991  * @param namespaceURI  the XML namespace of the child element
992  * @param force         bypass use of hint and just cast down to check child
993  */
994 #define PROC_TYPED_CHILDREN(proper,namespaceURI,force) \
995     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
996         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
997         if (typesafe) { \
998             get##proper##s().push_back(typesafe); \
999             return; \
1000         } \
1001     }
1002
1003 /**
1004  * Implements unmarshalling process branch for typed child collection element
1005  * in a foreign namespace.
1006  * 
1007  * @param proper        the proper name of the child type
1008  * @param ns            the C++ namespace for the type
1009  * @param namespaceURI  the XML namespace of the child element
1010  * @param force         bypass use of hint and just cast down to check child
1011  */
1012 #define PROC_TYPED_FOREIGN_CHILDREN(proper,ns,namespaceURI,force) \
1013     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1014         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1015         if (typesafe) { \
1016             get##proper##s().push_back(typesafe); \
1017             return; \
1018         } \
1019     }
1020
1021 /**
1022  * Implements unmarshalling process branch for typed child singleton element
1023  * 
1024  * @param proper        the proper name of the child type
1025  * @param namespaceURI  the XML namespace of the child element
1026  * @param force         bypass use of hint and just cast down to check child
1027  */
1028 #define PROC_TYPED_CHILD(proper,namespaceURI,force) \
1029     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1030         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
1031         if (typesafe) { \
1032             set##proper(typesafe); \
1033             return; \
1034         } \
1035     }
1036
1037 /**
1038  * Implements unmarshalling process branch for typed child singleton element
1039  * in a foreign namespace.
1040  * 
1041  * @param proper        the proper name of the child type
1042  * @param ns            the C++ namespace for the type
1043  * @param namespaceURI  the XML namespace of the child element
1044  * @param force         bypass use of hint and just cast down to check child
1045  */
1046 #define PROC_TYPED_FOREIGN_CHILD(proper,ns,namespaceURI,force) \
1047     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1048         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1049         if (typesafe) { \
1050             set##proper(typesafe); \
1051             return; \
1052         } \
1053     }
1054
1055 /**
1056  * Implements unmarshalling process branch for a generic child singleton element
1057  * 
1058  * @param proper        the proper name of the child type
1059  * @param namespaceURI  the XML namespace of the child element
1060  */
1061 #define PROC_XMLOBJECT_CHILD(proper,namespaceURI) \
1062     if (xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1063         set##proper(childXMLObject); \
1064         return; \
1065     }
1066
1067 /**
1068  * Declares aliased get/set methods for named XML element simple content.
1069  * 
1070  * @param proper    the proper name to label the element's content
1071  */
1072 #define DECL_SIMPLE_CONTENT(proper) \
1073     XMLTOOLING_DOXYGEN(Returns proper.) \
1074     const XMLCh* get##proper() const { \
1075         return getTextContent(); \
1076     } \
1077     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1078     void set##proper(const XMLCh* proper) { \
1079         setTextContent(proper); \
1080     }
1081
1082 /**
1083  * Declares aliased get/set methods for named integer XML element content.
1084  * 
1085  * @param proper    the proper name to label the element's content
1086  */
1087 #define DECL_INTEGER_CONTENT(proper) \
1088     XMLTOOLING_DOXYGEN(Returns proper in integer form after a NULL indicator.) \
1089     std::pair<bool,int> get##proper() const { \
1090         return std::make_pair((getTextContent()!=NULL), (getTextContent()!=NULL ? XMLString::parseInt(getTextContent()) : NULL)); \
1091     } \
1092     XMLTOOLING_DOXYGEN(Sets proper.) \
1093     void set##proper(int proper) { \
1094         char buf[64]; \
1095         sprintf(buf,"%d",proper); \
1096         xmltooling::auto_ptr_XMLCh widebuf(buf); \
1097         setTextContent(widebuf.get()); \
1098     } \
1099     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1100     void set##proper(const XMLCh* proper) { \
1101         setTextContent(proper); \
1102     }
1103
1104 /**
1105  * Implements cloning methods for an XMLObject specialization implementation class.
1106  * 
1107  * @param cname    the name of the XMLObject specialization
1108  */
1109 #define IMPL_XMLOBJECT_CLONE(cname) \
1110     cname* clone##cname() const { \
1111         return dynamic_cast<cname*>(clone()); \
1112     } \
1113     xmltooling::XMLObject* clone() const { \
1114         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1115         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1116         if (ret) { \
1117             domClone.release(); \
1118             return ret; \
1119         } \
1120         return new cname##Impl(*this); \
1121     }
1122
1123 /**
1124  * Declares an XMLObject specialization with a simple content model and type,
1125  * handling it as string data.
1126  * 
1127  * @param linkage   linkage specifier for the class
1128  * @param cname     the name of the XMLObject specialization
1129  * @param proper    the proper name to label the element's content
1130  * @param desc      documentation for class
1131  */
1132 #define DECL_XMLOBJECT_SIMPLE(linkage,cname,proper,desc) \
1133     BEGIN_XMLOBJECT(linkage,cname,xmltooling::XMLObject,desc); \
1134         DECL_SIMPLE_CONTENT(proper); \
1135     END_XMLOBJECT
1136
1137 /**
1138  * Declares and defines an implementation class for an XMLObject with
1139  * a simple content model and type, handling it as string data.
1140  * 
1141  * @param linkage   linkage specifier for the class
1142  * @param cname     the name of the XMLObject specialization
1143  */
1144 #define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
1145     class linkage cname##Impl \
1146         : public virtual cname, \
1147             public xmltooling::AbstractSimpleElement, \
1148             public xmltooling::AbstractDOMCachingXMLObject, \
1149             public xmltooling::AbstractXMLObjectMarshaller, \
1150             public xmltooling::AbstractXMLObjectUnmarshaller \
1151     { \
1152     public: \
1153         virtual ~cname##Impl() {} \
1154         cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) \
1155             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
1156         } \
1157         cname##Impl(const cname##Impl& src) \
1158             : xmltooling::AbstractXMLObject(src), \
1159                 xmltooling::AbstractSimpleElement(src), \
1160                 xmltooling::AbstractDOMCachingXMLObject(src) {} \
1161         IMPL_XMLOBJECT_CLONE(cname) \
1162     }
1163
1164 #ifdef HAVE_COVARIANT_RETURNS
1165
1166 /**
1167  * Begins the declaration of an XMLObjectBuilder specialization.
1168  * Basic boilerplate includes an empty virtual destructor, and
1169  * a default builder that defaults the element name.
1170  * 
1171  * @param linkage           linkage specifier for the class
1172  * @param cname             the name of the XMLObject specialization
1173  * @param namespaceURI      the XML namespace of the default associated element
1174  * @param namespacePrefix   the XML namespace prefix of the default associated element
1175  */
1176 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1177     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1178     class linkage cname##Builder : public xmltooling::XMLObjectBuilder { \
1179     public: \
1180         virtual ~cname##Builder() {} \
1181         XMLTOOLING_DOXYGEN(Default builder.) \
1182         virtual cname* buildObject() const { \
1183             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1184         } \
1185         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1186         virtual cname* buildObject( \
1187             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL \
1188             ) const
1189
1190 /**
1191  * Ends the declaration of an XMLObjectBuilder specialization.
1192  */
1193 #define END_XMLOBJECTBUILDER }
1194
1195 /**
1196  * Declares a generic XMLObjectBuilder specialization.
1197  * 
1198  * @param linkage           linkage specifier for the class
1199  * @param cname             the name of the XMLObject specialization
1200  * @param namespaceURI      the XML namespace of the default associated element
1201  * @param namespacePrefix   the XML namespace prefix of the default associated element
1202  */
1203  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1204     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1205     XMLTOOLING_DOXYGEN(Singleton builder.) \
1206     static cname* build##cname() { \
1207         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1208             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1209             ); \
1210         if (b) \
1211             return b->buildObject(); \
1212         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1213     } \
1214     END_XMLOBJECTBUILDER
1215
1216 /**
1217  * Implements the standard XMLObjectBuilder specialization function. 
1218  * 
1219  * @param cname the name of the XMLObject specialization
1220  */
1221 #define IMPL_XMLOBJECTBUILDER(cname) \
1222     cname* cname##Builder::buildObject( \
1223         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \
1224         ) const \
1225     { \
1226         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1227     }
1228
1229 #else   /* !HAVE_COVARIANT_RETURNS */\r
1230
1231 /**
1232  * Begins the declaration of an XMLObjectBuilder specialization.
1233  * Basic boilerplate includes an empty virtual destructor, and
1234  * a default builder that defaults the element name.
1235  * 
1236  * @param linkage           linkage specifier for the class
1237  * @param cname             the name of the XMLObject specialization
1238  * @param namespaceURI      the XML namespace of the default associated element
1239  * @param namespacePrefix   the XML namespace prefix of the default associated element
1240  */
1241 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1242     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1243     class linkage cname##Builder : public xmltooling::XMLObjectBuilder { \
1244     public: \
1245         virtual ~cname##Builder() {} \
1246         XMLTOOLING_DOXYGEN(Default builder.) \
1247         virtual xmltooling::XMLObject* buildObject() const { \
1248             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1249         } \
1250         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1251         virtual xmltooling::XMLObject* buildObject( \
1252             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL \
1253             ) const
1254
1255 /**
1256  * Ends the declaration of an XMLObjectBuilder specialization.
1257  */
1258 #define END_XMLOBJECTBUILDER }
1259
1260 /**
1261  * Declares a generic XMLObjectBuilder specialization.
1262  * 
1263  * @param linkage           linkage specifier for the class
1264  * @param cname             the name of the XMLObject specialization
1265  * @param namespaceURI      the XML namespace of the default associated element
1266  * @param namespacePrefix   the XML namespace prefix of the default associated element
1267  */
1268  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1269     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1270     XMLTOOLING_DOXYGEN(Singleton builder.) \
1271     static cname* build##cname() { \
1272         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1273             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1274             ); \
1275         if (b) \
1276             return dynamic_cast<cname*>(b->buildObject()); \
1277         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1278     } \
1279     END_XMLOBJECTBUILDER
1280
1281 /**
1282  * Implements the standard XMLObjectBuilder specialization function. 
1283  * 
1284  * @param cname the name of the XMLObject specialization
1285  */
1286 #define IMPL_XMLOBJECTBUILDER(cname) \
1287     xmltooling::XMLObject* cname##Builder::buildObject( \
1288         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \
1289         ) const \
1290     { \
1291         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1292     }
1293
1294 #endif  /* HAVE_COVARIANT_RETURNS */
1295
1296 /**
1297  * Begins the declaration of a Schema Validator specialization.
1298  * 
1299  * @param linkage           linkage specifier for the class
1300  * @param cname the base name of the Validator specialization
1301  */
1302  #define BEGIN_XMLOBJECTVALIDATOR(linkage,cname) \
1303     class linkage cname##SchemaValidator : public xmltooling::Validator \
1304     { \
1305     public: \
1306         virtual ~cname##SchemaValidator() {} \
1307         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1308             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1309             if (!ptr) \
1310                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1311
1312 /**
1313  * Begins the declaration of a Schema Validator specialization subclass.
1314  * 
1315  * @param linkage   linkage specifier for the class
1316  * @param cname     the base name of the Validator specialization
1317  * @param base      base class for the validator
1318  */
1319  #define BEGIN_XMLOBJECTVALIDATOR_SUB(linkage,cname,base) \
1320     class linkage cname##SchemaValidator : public base##SchemaValidator \
1321     { \
1322     public: \
1323         virtual ~cname##SchemaValidator() {} \
1324         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1325             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1326             if (!ptr) \
1327                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1328
1329 /**
1330  * Ends the declaration of a Validator specialization.
1331  */
1332 #define END_XMLOBJECTVALIDATOR } }
1333
1334 /**
1335  * Validator code that checks the object type.
1336  * 
1337  * @param cname     the name of the XMLObject specialization
1338  */
1339 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
1340     const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1341     if (!ptr) \
1342         throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1343
1344 /**
1345  * Validator code that checks for a required attribute, content, or singleton.
1346  * 
1347  * @param cname     the name of the XMLObject specialization
1348  * @param proper    the proper name of the attribute, content, or singleton member 
1349  */
1350 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
1351     if (!ptr->get##proper()) \
1352         throw xmltooling::ValidationException(#cname" must have "#proper".")
1353
1354 /**
1355  * Validator code that checks for a required integer attribute
1356  * 
1357  * @param cname     the name of the XMLObject specialization
1358  * @param proper    the proper name of the attribute, content, or singleton member 
1359  */
1360 #define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
1361     if (!ptr->get##proper().first) \
1362         throw xmltooling::ValidationException(#cname" must have "#proper".")
1363
1364 /**
1365  * Validator code that checks for one of a pair of
1366  * required attributes, content, or singletons.
1367  * 
1368  * @param cname     the name of the XMLObject specialization
1369  * @param proper1   the proper name of the first attribute, content, or singleton member 
1370  * @param proper2   the proper name of the second attribute, content, or singleton member 
1371  */
1372 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
1373     if (!ptr->get##proper1() && !ptr->get##proper2()) \
1374         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
1375
1376 /**
1377  * Validator code that checks for one of a pair of
1378  * required attributes, content, or singletons, but disallows both.
1379  * 
1380  * @param cname     the name of the XMLObject specialization
1381  * @param proper1   the proper name of the first attribute, content, or singleton member 
1382  * @param proper2   the proper name of the second attribute, content, or singleton member 
1383  */
1384 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
1385     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
1386         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
1387
1388 /**
1389  * Validator code that checks for one of a set of three
1390  * required attributes, content, or singletons.
1391  * 
1392  * @param cname     the name of the XMLObject specialization
1393  * @param proper1   the proper name of the first attribute, content, or singleton member
1394  * @param proper2   the proper name of the second attribute, content, or singleton member
1395  * @param proper3   the proper name of the third attribute, content, or singleton member
1396  */
1397 #define XMLOBJECTVALIDATOR_ONEOF3(cname,proper1,proper2,proper3) \
1398     if (!ptr->get##proper1() && !ptr->get##proper2() && !ptr->get##proper3()) \
1399         throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
1400
1401 /**
1402  * Validator code that checks for one of a set of three
1403  * required attributes, content, or singletons but disallows more than one.
1404  * 
1405  * @param cname     the name of the XMLObject specialization
1406  * @param proper1   the proper name of the first attribute, content, or singleton member
1407  * @param proper2   the proper name of the second attribute, content, or singleton member
1408  * @param proper3   the proper name of the third attribute, content, or singleton member
1409  */
1410 #define XMLOBJECTVALIDATOR_ONLYONEOF3(cname,proper1,proper2,proper3) \
1411     int c##proper1##proper2##proper3=0; \
1412     if (ptr->get##proper1()!=NULL) \
1413         c##proper1##proper2##proper3++; \
1414     if (ptr->get##proper2()!=NULL) \
1415         c##proper1##proper2##proper3++; \
1416     if (ptr->get##proper3()!=NULL) \
1417         c##proper1##proper2##proper3++; \
1418     if (c##proper1##proper2##proper3 != 1) \
1419         throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
1420
1421 /**
1422  * Validator code that checks a co-constraint (if one present, the other must be)
1423  * between a pair of attributes, content, or singletons.
1424  * 
1425  * @param cname     the name of the XMLObject specialization
1426  * @param proper1   the proper name of the first attribute, content, or singleton member 
1427  * @param proper2   the proper name of the second attribute, content, or singleton member 
1428  */
1429 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
1430     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
1431         throw xmltooling::ValidationException(#cname" cannot have "#proper1" without "#proper2".")
1432
1433 /**
1434  * Validator code that checks for a non-empty collection.
1435  * 
1436  * @param cname     the name of the XMLObject specialization
1437  * @param proper    the proper name of the collection item 
1438  */
1439 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
1440     if (ptr->get##proper##s().empty()) \
1441         throw xmltooling::ValidationException(#cname" must have at least one "#proper".")
1442
1443 /**
1444  * Declares/defines a Validator specialization that checks object type and
1445  * a non-empty simple content model.
1446  * 
1447  * @param linkage   linkage specifier for the class
1448  * @param cname     the name of the XMLObject specialization
1449  */
1450 #define XMLOBJECTVALIDATOR_SIMPLE(linkage,cname) \
1451     BEGIN_XMLOBJECTVALIDATOR(linkage,cname); \
1452         XMLOBJECTVALIDATOR_REQUIRE(cname,TextContent); \
1453     END_XMLOBJECTVALIDATOR
1454
1455 #include <utility>
1456
1457 /**
1458  * @namespace xmltooling
1459  * Public namespace of XML Tooling library
1460  */
1461 namespace xmltooling {
1462
1463     /**
1464      * Template function for cloning a sequence of XMLObjects.
1465      * Invokes the clone() member on each element of the input sequence and adds the copy to
1466      * the output sequence. Order is preserved.
1467      * 
1468      * @param in    input sequence to clone
1469      * @param out   output sequence to copy cloned pointers into
1470      */
1471     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
1472         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
1473             if (*i)
1474                 out.push_back((*i)->clone());
1475             else
1476                 out.push_back(*i);
1477         }
1478     }
1479
1480     /**
1481      * Functor for cleaning up heap objects in containers.
1482      */
1483     template<class T> struct cleanup
1484     {
1485         /**
1486          * Function operator to delete an object.
1487          * 
1488          * @param ptr   object to delete
1489          */
1490         void operator()(T* ptr) {delete ptr;}
1491         
1492         /**
1493          * Function operator to delete an object stored as const.
1494          * 
1495          * @param ptr   object to delete after casting away const
1496          */
1497         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
1498     };
1499
1500     /**
1501      * Functor for cleaning up heap objects in key/value containers.
1502      */
1503     template<class A,class B> struct cleanup_pair
1504     {
1505         /**
1506          * Function operator to delete an object.
1507          * 
1508          * @param p   a pair in which the second component is the object to delete
1509          */
1510         void operator()(const std::pair<A,B*>& p) {delete p.second;}
1511     };
1512 };
1513
1514 #endif /* __xmltooling_base_h__ */