0bd9062c6d09703f29468692a964dadfd368b620
[shibboleth/cpp-xmltooling.git] / xmltooling / base.h
1 /*
2  *  Copyright 2001-2010 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 xmltooling/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 #include <typeinfo>
28
29 /* Required for sprintf, used by integer XML attribute macros. */
30 #include <cstdio>
31
32 #if defined (_MSC_VER) || defined(__BORLANDC__)
33   #include <xmltooling/config_pub_win32.h>
34 #else
35   #include <xmltooling/config_pub.h>
36 #endif
37
38 #ifdef XMLTOOLING_LITE
39 # define XMLTOOLING_NO_XMLSEC 1
40 #endif
41
42 #ifndef HAVE_NULLPTR
43 # define nullptr 0
44 #endif
45
46 #if defined(XMLTOOLING_NO_XMLSEC) || !defined(HAVE_XSECSIZE_T)
47 # ifdef XMLTOOLING_XERCESC_64BITSAFE
48 #   include <xercesc/util/XercesDefs.hpp>
49     typedef XMLSize_t xsecsize_t;
50 # else
51     typedef unsigned int xsecsize_t;
52 # endif
53 #endif
54
55 // Windows and GCC4 Symbol Visibility Macros
56 #ifdef WIN32
57   #define XMLTOOL_IMPORT __declspec(dllimport)
58   #define XMLTOOL_EXPORT __declspec(dllexport)
59   #define XMLTOOL_DLLLOCAL
60   #define XMLTOOL_DLLPUBLIC
61 #else
62   #define XMLTOOL_IMPORT
63   #ifdef GCC_HASCLASSVISIBILITY
64     #define XMLTOOL_EXPORT __attribute__ ((visibility("default")))
65     #define XMLTOOL_DLLLOCAL __attribute__ ((visibility("hidden")))
66     #define XMLTOOL_DLLPUBLIC __attribute__ ((visibility("default")))
67   #else
68     #define XMLTOOL_EXPORT
69     #define XMLTOOL_DLLLOCAL
70     #define XMLTOOL_DLLPUBLIC
71   #endif
72 #endif
73
74 // Define XMLTOOL_API for DLL builds
75 #ifdef XMLTOOLING_EXPORTS
76   #define XMLTOOL_API XMLTOOL_EXPORT
77 #else
78   #define XMLTOOL_API XMLTOOL_IMPORT
79 #endif
80
81 // Throwable classes must always be visible on GCC in all binaries
82 #ifdef WIN32
83   #define XMLTOOL_EXCEPTIONAPI(api) api
84 #elif defined(GCC_HASCLASSVISIBILITY)
85   #define XMLTOOL_EXCEPTIONAPI(api) XMLTOOL_EXPORT
86 #else
87   #define XMLTOOL_EXCEPTIONAPI(api)
88 #endif
89
90 #ifdef _MSC_VER
91     #define XMLTOOLING_DOXYGEN(desc) /##** desc */
92 #else
93     #define XMLTOOLING_DOXYGEN(desc)
94 #endif
95
96 /**
97  * Blocks copy c'tor and assignment operator for a class.
98  */
99 #define MAKE_NONCOPYABLE(type) \
100     private: \
101         type(const type&); \
102         type& operator=(const type&)
103
104 #ifndef DOXYGEN_SKIP
105 #ifndef NULL
106 #define NULL    0
107 #endif
108 #define UNICODE_LITERAL_1(a) {xercesc::chLatin_##a, xercesc::chNull}
109 #define UNICODE_LITERAL_2(a,b) {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chNull}
110 #define UNICODE_LITERAL_3(a,b,c) {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chNull}
111 #define UNICODE_LITERAL_4(a,b,c,d) {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chNull}
112 #define UNICODE_LITERAL_5(a,b,c,d,e) \
113     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chNull}
114 #define UNICODE_LITERAL_6(a,b,c,d,e,f) \
115     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chNull}
116 #define UNICODE_LITERAL_7(a,b,c,d,e,f,g) \
117     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chNull}
118 #define UNICODE_LITERAL_8(a,b,c,d,e,f,g,h) \
119     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chNull}
120 #define UNICODE_LITERAL_9(a,b,c,d,e,f,g,h,i) \
121     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, xercesc::chNull}
122 #define UNICODE_LITERAL_10(a,b,c,d,e,f,g,h,i,j) \
123     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
124         xercesc::chLatin_##j, xercesc::chNull}
125 #define UNICODE_LITERAL_11(a,b,c,d,e,f,g,h,i,j,k) \
126     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
127         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chNull}
128 #define UNICODE_LITERAL_12(a,b,c,d,e,f,g,h,i,j,k,l) \
129     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
130         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chNull}
131 #define UNICODE_LITERAL_13(a,b,c,d,e,f,g,h,i,j,k,l,m) \
132     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
133         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chNull}
134 #define UNICODE_LITERAL_14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) \
135     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
136         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chNull}
137 #define UNICODE_LITERAL_15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \
138     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
139         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chNull}
140 #define UNICODE_LITERAL_16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
141     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
142         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chNull}
143 #define UNICODE_LITERAL_17(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) \
144     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
145         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chNull}
146 #define UNICODE_LITERAL_18(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) \
147     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
148         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, xercesc::chNull}
149 #define UNICODE_LITERAL_19(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) \
150     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
151         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
152         xercesc::chLatin_##s, xercesc::chNull}
153 #define UNICODE_LITERAL_20(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) \
154     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
155         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
156         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chNull}
157 #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) \
158     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
159         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
160         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chNull}
161 #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) \
162     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
163         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
164         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chNull}
165 #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) \
166     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
167         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
168         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chNull}
169 #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) \
170     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
171         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
172         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chNull}
173 #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) \
174     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
175         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
176         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chNull}
177 #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) \
178     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
179         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
180         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, xercesc::chNull}
181 #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) \
182     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
183         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
184         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
185         xercesc::chLatin_##aa, xercesc::chNull}
186 #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) \
187     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
188         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
189         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
190         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chNull}
191 #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) \
192     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
193         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
194         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
195         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chNull}
196 #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) \
197     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
198         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
199         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
200         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chNull}
201 #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) \
202     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
203         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
204         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
205         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chNull}
206 #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) \
207     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
208         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
209         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
210         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chLatin_##ff, xercesc::chNull}
211 #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) \
212     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
213         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
214         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
215         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chLatin_##ff, xercesc::chLatin_##gg, xercesc::chNull}
216 #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) \
217     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
218         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
219         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
220         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chLatin_##ff, xercesc::chLatin_##gg, xercesc::chLatin_##hh, xercesc::chNull}
221 #endif /* DOXYGEN_SKIP */
222
223 /**
224  * Begins the declaration of an XMLObject specialization for an abstract element/type.
225  * Basic boilerplate includes a protected constructor, empty virtual destructor,
226  * and Unicode constants for the default associated element's name and prefix.
227  *
228  * @param linkage   linkage specifier for the class
229  * @param cname     the name of the class to declare
230  * @param base      the base class to derive from using public virtual inheritance
231  * @param desc      documentation comment for class
232  */
233 #define DECL_XMLOBJECT_ABSTRACT(linkage,cname,base,desc) \
234     XMLTOOLING_DOXYGEN(desc) \
235     class linkage cname : public virtual base { \
236     protected: \
237         cname() {} \
238     public: \
239         virtual ~cname() {} \
240         XMLTOOLING_DOXYGEN(Element local name) \
241         static const XMLCh LOCAL_NAME[]; \
242     }
243
244 /**
245  * Begins the declaration of an XMLObject specialization.
246  * Basic boilerplate includes a protected constructor, empty virtual destructor,
247  * and Unicode constants for the default associated element's name and prefix.
248  *
249  * @param linkage   linkage specifier for the class
250  * @param cname     the name of the class to declare
251  * @param base      the base class to derive from using public virtual inheritance
252  * @param desc      documentation comment for class
253  */
254 #define BEGIN_XMLOBJECT(linkage,cname,base,desc) \
255     XMLTOOLING_DOXYGEN(desc) \
256     class linkage cname : public virtual base { \
257     protected: \
258         cname() {} \
259     public: \
260         virtual ~cname() {} \
261         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
262         virtual cname* clone##cname() const=0; \
263         XMLTOOLING_DOXYGEN(Element local name) \
264         static const XMLCh LOCAL_NAME[]
265
266 /**
267  * Begins the declaration of an XMLObject specialization with two base classes.
268  * Basic boilerplate includes a protected constructor, empty virtual destructor,
269  * and Unicode constants for the default associated element's name and prefix.
270  *
271  * @param linkage   linkage specifier for the class
272  * @param cname     the name of the class to declare
273  * @param base      the first base class to derive from using public virtual inheritance
274  * @param base2     the second base class to derive from using public virtual inheritance
275  * @param desc      documentation comment for class
276  */
277 #define BEGIN_XMLOBJECT2(linkage,cname,base,base2,desc) \
278     XMLTOOLING_DOXYGEN(desc) \
279     class linkage cname : public virtual base, public virtual base2 { \
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 three 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 desc      documentation comment for class
300  */
301 #define BEGIN_XMLOBJECT3(linkage,cname,base,base2,base3,desc) \
302     XMLTOOLING_DOXYGEN(desc) \
303     class linkage cname : public virtual base, public virtual base2, public virtual base3 { \
304     protected: \
305         cname() {} \
306     public: \
307         virtual ~cname() {} \
308         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
309         virtual cname* clone##cname() const=0; \
310         XMLTOOLING_DOXYGEN(Element local name) \
311         static const XMLCh LOCAL_NAME[]
312
313 /**
314  * Begins the declaration of an XMLObject specialization with four base classes.
315  * Basic boilerplate includes a protected constructor, empty virtual destructor,
316  * and Unicode constants for the default associated element's name and prefix.
317  *
318  * @param linkage   linkage specifier for the class
319  * @param cname     the name of the class to declare
320  * @param base      the first base class to derive from using public virtual inheritance
321  * @param base2     the second base class to derive from using public virtual inheritance
322  * @param base3     the third base class to derive from using public virtual inheritance
323  * @param base4     the fourth base class to derive from using public virtual inheritance
324  * @param desc      documentation comment for class
325  */
326 #define BEGIN_XMLOBJECT4(linkage,cname,base,base2,base3,base4,desc) \
327     XMLTOOLING_DOXYGEN(desc) \
328     class linkage cname : public virtual base, public virtual base2, public virtual base3, public virtual base4 { \
329     protected: \
330         cname() {} \
331     public: \
332         virtual ~cname() {} \
333         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
334         virtual cname* clone##cname() const=0; \
335         XMLTOOLING_DOXYGEN(Element local name) \
336         static const XMLCh LOCAL_NAME[]
337
338 /**
339  * Begins the declaration of an XMLObject specialization with five base classes.
340  * Basic boilerplate includes a protected constructor, empty virtual destructor,
341  * and Unicode constants for the default associated element's name and prefix.
342  *
343  * @param linkage   linkage specifier for the class
344  * @param cname     the name of the class to declare
345  * @param base      the first base class to derive from using public virtual inheritance
346  * @param base2     the second base class to derive from using public virtual inheritance
347  * @param base3     the third base class to derive from using public virtual inheritance
348  * @param base4     the fourth base class to derive from using public virtual inheritance
349  * @param base5     the fifth base class to derive from using public virtual inheritance
350  * @param desc      documentation comment for class
351  */
352 #define BEGIN_XMLOBJECT5(linkage,cname,base,base2,base3,base4,base5,desc) \
353     XMLTOOLING_DOXYGEN(desc) \
354     class linkage cname : public virtual base, public virtual base2, public virtual base3, public virtual base4, public virtual base5 { \
355     protected: \
356         cname() {} \
357     public: \
358         virtual ~cname() {} \
359         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
360         virtual cname* clone##cname() const=0; \
361         XMLTOOLING_DOXYGEN(Element local name) \
362         static const XMLCh LOCAL_NAME[]
363
364 /**
365  * Ends the declaration of an XMLObject specialization.
366  */
367 #define END_XMLOBJECT }
368
369 /**
370  * Declares a static variable holding the XMLObject's element QName.
371  */
372 #define DECL_ELEMENT_QNAME \
373     public: \
374         XMLTOOLING_DOXYGEN(Element QName) \
375         static xmltooling::QName ELEMENT_QNAME
376
377 /**
378  * Declares a static variable holding the XMLObject's schema type QName.
379  */
380 #define DECL_TYPE_QNAME \
381     public: \
382         XMLTOOLING_DOXYGEN(Type QName) \
383         static xmltooling::QName TYPE_QNAME
384
385 /**
386  * Implements a static variable holding an XMLObject's element QName.
387  *
388  * @param cname             the name of the XMLObject specialization
389  * @param namespaceURI      the XML namespace of the default associated element
390  * @param namespacePrefix   the XML namespace prefix of the default associated element
391  */
392 #define IMPL_ELEMENT_QNAME(cname,namespaceURI,namespacePrefix) \
393     xmltooling::QName cname::ELEMENT_QNAME(namespaceURI,cname::LOCAL_NAME,namespacePrefix)
394
395 /**
396  * Implements a static variable holding an XMLObject's schema type QName.
397  *
398  * @param cname             the name of the XMLObject specialization
399  * @param namespaceURI      the XML namespace of the default associated element
400  * @param namespacePrefix   the XML namespace prefix of the default associated element
401  */
402 #define IMPL_TYPE_QNAME(cname,namespaceURI,namespacePrefix) \
403     xmltooling::QName cname::TYPE_QNAME(namespaceURI,cname::TYPE_NAME,namespacePrefix)
404
405 /**
406  * Declares abstract set method for a typed XML attribute.
407  * The get method is omitted.
408  *
409  * @param proper    the proper name of the attribute
410  * @param upcased   the upcased name of the attribute
411  * @param type      the attribute's data type
412  */
413 #define DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,type) \
414     public: \
415         XMLTOOLING_DOXYGEN(proper attribute name) \
416         static const XMLCh upcased##_ATTRIB_NAME[]; \
417         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
418         virtual void set##proper(const type* proper)=0
419
420 /**
421  * Declares abstract get/set methods for a typed XML attribute.
422  *
423  * @param proper    the proper name of the attribute
424  * @param upcased   the upcased name of the attribute
425  * @param type      the attribute's data type
426  */
427 #define DECL_XMLOBJECT_ATTRIB(proper,upcased,type) \
428     public: \
429         XMLTOOLING_DOXYGEN(proper attribute name) \
430         static const XMLCh upcased##_ATTRIB_NAME[]; \
431         XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
432         virtual const type* get##proper() const=0; \
433         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
434         virtual void set##proper(const type* proper)=0
435
436 /**
437  * Declares abstract set method for a string XML attribute.
438  * The get method is omitted.
439  *
440  * @param proper    the proper name of the attribute
441  * @param upcased   the upcased name of the attribute
442  */
443 #define DECL_INHERITED_STRING_ATTRIB(proper,upcased) \
444     DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
445
446 /**
447  * Declares abstract get/set methods for a string XML attribute.
448  *
449  * @param proper    the proper name of the attribute
450  * @param upcased   the upcased name of the attribute
451  */
452 #define DECL_STRING_ATTRIB(proper,upcased) \
453     DECL_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
454
455 /**
456  * Declares abstract set method for a DateTime XML attribute.
457  * The get method is omitted.
458  *
459  * @param proper    the proper name of the attribute
460  * @param upcased   the upcased name of the attribute
461  */
462 #define DECL_INHERITED_DATETIME_ATTRIB(proper,upcased) \
463     DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
464     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
465     virtual void set##proper(time_t proper)=0; \
466     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
467     virtual void set##proper(const XMLCh* proper)=0
468
469 /**
470  * Declares abstract get/set methods for a DateTime XML attribute.
471  *
472  * @param proper    the proper name of the attribute
473  * @param upcased   the upcased name of the attribute
474  */
475 #define DECL_DATETIME_ATTRIB(proper,upcased) \
476     DECL_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
477     XMLTOOLING_DOXYGEN(Returns the proper attribute in epoch form.) \
478     virtual time_t get##proper##Epoch() const=0; \
479     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
480     virtual void set##proper(time_t proper)=0; \
481     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
482     virtual void set##proper(const XMLCh* proper)=0
483
484 /**
485  * Declares abstract set method for an integer XML attribute.
486  * The get method is omitted.
487  *
488  * @param proper    the proper name of the attribute
489  * @param upcased   the upcased name of the attribute
490  */
491 #define DECL_INHERITED_INTEGER_ATTRIB(proper,upcased) \
492     public: \
493         XMLTOOLING_DOXYGEN(proper attribute name) \
494         static const XMLCh upcased##_ATTRIB_NAME[]; \
495         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
496         virtual void set##proper(const XMLCh* proper)=0; \
497         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
498         virtual void set##proper(int proper)=0
499
500 /**
501  * Declares abstract get/set methods for an integer XML attribute.
502  *
503  * @param proper    the proper name of the attribute
504  * @param upcased   the upcased name of the attribute
505  */
506 #define DECL_INTEGER_ATTRIB(proper,upcased) \
507     public: \
508         XMLTOOLING_DOXYGEN(proper attribute name) \
509         static const XMLCh upcased##_ATTRIB_NAME[]; \
510         XMLTOOLING_DOXYGEN(Returns the proper attribute after a NULL indicator.) \
511         virtual std::pair<bool,int> get##proper() const=0; \
512         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
513         virtual void set##proper(const XMLCh* proper)=0; \
514         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
515         virtual void set##proper(int proper)=0
516
517 /**
518  * Declares abstract get/set methods for a boolean XML attribute.
519  *
520  * @param proper    the proper name of the attribute
521  * @param upcased   the upcased name of the attribute
522  * @param def       the default/presumed value, if no explicit value has been set
523  */
524 #define DECL_BOOLEAN_ATTRIB(proper,upcased,def) \
525     public: \
526         XMLTOOLING_DOXYGEN(proper attribute name) \
527         static const XMLCh upcased##_ATTRIB_NAME[]; \
528         XMLTOOLING_DOXYGEN(Returns the proper attribute or def if not set.) \
529         bool proper() const { \
530             switch (get##proper()) { \
531                 case xmlconstants::XML_BOOL_TRUE: \
532                 case xmlconstants::XML_BOOL_ONE: \
533                     return true; \
534                 case xmlconstants::XML_BOOL_FALSE: \
535                 case xmlconstants::XML_BOOL_ZERO: \
536                     return false; \
537                 default: \
538                     return def; \
539             } \
540         } \
541         XMLTOOLING_DOXYGEN(Returns the proper attribute as an explicit enumerated value.) \
542         virtual xmlconstants::xmltooling_bool_t get##proper() const=0; \
543         XMLTOOLING_DOXYGEN(Sets the proper attribute using an enumerated value.) \
544         virtual void proper(xmlconstants::xmltooling_bool_t value)=0; \
545         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
546         void proper(bool value) { \
547             proper(value ? xmlconstants::XML_BOOL_ONE : xmlconstants::XML_BOOL_ZERO); \
548         } \
549         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string constant.) \
550         void set##proper(const XMLCh* value) { \
551             if (value) { \
552                 switch (*value) { \
553                     case xercesc::chLatin_t: \
554                         proper(xmlconstants::XML_BOOL_TRUE); \
555                         break; \
556                     case xercesc::chLatin_f: \
557                         proper(xmlconstants::XML_BOOL_FALSE); \
558                         break; \
559                     case xercesc::chDigit_1: \
560                         proper(xmlconstants::XML_BOOL_ONE); \
561                         break; \
562                     case xercesc::chDigit_0: \
563                         proper(xmlconstants::XML_BOOL_ZERO); \
564                         break; \
565                     default: \
566                         proper(xmlconstants::XML_BOOL_NULL); \
567                 } \
568             } \
569             else \
570                 proper(xmlconstants::XML_BOOL_NULL); \
571         }
572
573 /**
574  * Implements get/set methods and a private member for a typed XML attribute.
575  *
576  * @param proper    the proper name of the attribute
577  * @param type      the attribute's data type
578  */
579 #define IMPL_XMLOBJECT_ATTRIB(proper,type) \
580     protected: \
581         type* m_##proper; \
582     public: \
583         const type* get##proper() const { \
584             return m_##proper; \
585         } \
586         void set##proper(const type* proper) { \
587             m_##proper = prepareForAssignment(m_##proper,proper); \
588         }
589
590 /**
591  * Implements get/set methods and a private member for a string XML attribute.
592  *
593  * @param proper    the proper name of the attribute
594  */
595 #define IMPL_STRING_ATTRIB(proper) \
596     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
597
598 /**
599  * Implements get/set methods and a private member for a string XML attribute,
600  * plus a getXMLID override.
601  *
602  * @param proper    the proper name of the attribute
603  */
604 #define IMPL_ID_ATTRIB(proper) \
605     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
606     const XMLCh* getXMLID() const { \
607         return m_##proper; \
608     }
609
610 /**
611  * Implements get/set methods and a private member for a string XML attribute,
612  * plus a getXMLID override and attribute node clearance when DOM is dropped.
613  *
614  * @param proper    the proper name of the attribute
615  * @param ucase         the upcased name of the attribute
616  * @param namespaceURI  the XML namespace of the attribute
617  */
618 #define IMPL_ID_ATTRIB_EX(proper, ucase, namespaceURI) \
619     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
620     const XMLCh* getXMLID() const { \
621         return m_##proper; \
622     } \
623     void releaseDOM() const { \
624         if (getDOM()) \
625             getDOM()->removeAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
626         AbstractDOMCachingXMLObject::releaseDOM(); \
627     }
628
629 /**
630  * Implements get/set methods and a private member for a DateTime XML attribute.
631  *
632  * @param proper    the proper name of the attribute
633  * @param fallback  epoch to return when attribute is NULL
634  */
635 #define IMPL_DATETIME_ATTRIB(proper,fallback) \
636     IMPL_DATETIME_ATTRIB_EX(proper,fallback,false)
637
638 /**
639  * Implements get/set methods and a private member for a duration-valued DateTime XML attribute.
640  *
641  * @param proper    the proper name of the attribute
642  * @param fallback  epoch to return when attribute is NULL
643  */
644 #define IMPL_DURATION_ATTRIB(proper,fallback) \
645     IMPL_DATETIME_ATTRIB_EX(proper,fallback,true)
646
647 /**
648  * Implements get/set methods and a private member for a DateTime XML attribute.
649  *
650  * @param proper    the proper name of the attribute
651  * @param fallback  epoch to return when attribute is NULL
652  * @param duration  true iff the attribute should be handled as a duration
653  */
654 #define IMPL_DATETIME_ATTRIB_EX(proper,fallback,duration) \
655     protected: \
656         DateTime* m_##proper; \
657         time_t m_##proper##Epoch; \
658     public: \
659         const DateTime* get##proper() const { \
660             return m_##proper; \
661         } \
662         time_t get##proper##Epoch() const { \
663             return m_##proper ? m_##proper##Epoch : fallback; \
664         } \
665         void set##proper(const DateTime* proper) { \
666             m_##proper = prepareForAssignment(m_##proper,proper); \
667             if (m_##proper) \
668                 m_##proper##Epoch=m_##proper->getEpoch(duration); \
669         } \
670         void set##proper(time_t proper) { \
671             m_##proper = prepareForAssignment(m_##proper,proper,duration); \
672             m_##proper##Epoch = proper; \
673         } \
674         void set##proper(const XMLCh* proper) { \
675             m_##proper = prepareForAssignment(m_##proper,proper,duration); \
676             if (m_##proper) \
677                 m_##proper##Epoch=m_##proper->getEpoch(duration); \
678         }
679
680 /**
681  * Implements get/set methods and a private member for an integer XML attribute.
682  *
683  * @param proper    the proper name of the attribute
684  */
685 #define IMPL_INTEGER_ATTRIB(proper) \
686     protected: \
687         XMLCh* m_##proper; \
688     public: \
689         pair<bool,int> get##proper() const { \
690             return make_pair((m_##proper!=nullptr),(m_##proper!=nullptr ? xercesc::XMLString::parseInt(m_##proper): 0)); \
691         } \
692         void set##proper(const XMLCh* proper) { \
693             m_##proper = prepareForAssignment(m_##proper,proper); \
694         } \
695         void set##proper(int proper) { \
696             char buf##proper[64]; \
697             sprintf(buf##proper,"%d",proper); \
698             auto_ptr_XMLCh wide##proper(buf##proper); \
699             set##proper(wide##proper.get()); \
700         }
701
702 /**
703  * Implements get/set methods and a private member for a boolean XML attribute.
704  *
705  * @param proper    the proper name of the attribute
706  */
707 #define IMPL_BOOLEAN_ATTRIB(proper) \
708     protected: \
709         xmlconstants::xmltooling_bool_t m_##proper; \
710     public: \
711         xmlconstants::xmltooling_bool_t get##proper() const { \
712             return m_##proper; \
713         } \
714         void proper(xmlconstants::xmltooling_bool_t value) { \
715             if (m_##proper != value) { \
716                 releaseThisandParentDOM(); \
717                 m_##proper = value; \
718             } \
719         }
720
721 /**
722  * Implements get/set methods and a private member for a typed, qualified XML attribute.
723  *
724  * @param proper    the proper name of the attribute
725  * @param type      the attribute's data type
726  */
727 #define IMPL_XMLOBJECT_FOREIGN_ATTRIB(proper,type) \
728     protected: \
729     XMLCh* m_##proper##Prefix; \
730         type* m_##proper; \
731     public: \
732         const type* get##proper() const { \
733             return m_##proper; \
734         } \
735         void set##proper(const type* proper) { \
736             m_##proper = prepareForAssignment(m_##proper,proper); \
737             XMLString::release(&m_##proper##Prefix); \
738             m_##proper##Prefix = nullptr; \
739         }
740
741 /**
742  * Declares abstract set method for a typed XML child object in a foreign namespace.
743  * The get method is omitted.
744  *
745  * @param proper    the proper name of the child type
746  * @param ns        the C++ namespace for the type
747  */
748 #define DECL_INHERITED_TYPED_FOREIGN_CHILD(proper,ns) \
749     public: \
750         XMLTOOLING_DOXYGEN(Sets the proper child.) \
751         virtual void set##proper(ns::proper* child)=0
752
753 /**
754  * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
755  *
756  * @param proper    the proper name of the child type
757  * @param ns        the C++ namespace for the type
758  */
759 #define DECL_TYPED_FOREIGN_CHILD(proper,ns) \
760     public: \
761         XMLTOOLING_DOXYGEN(Returns the proper child.) \
762         virtual ns::proper* get##proper() const=0; \
763         XMLTOOLING_DOXYGEN(Sets the proper child.) \
764         virtual void set##proper(ns::proper* child)=0
765
766 /**
767  * Declares abstract set method for a typed XML child object.
768  * The get method is omitted.
769  *
770  * @param proper    the proper name of the child type
771  */
772 #define DECL_INHERITED_TYPED_CHILD(proper) \
773     public: \
774         XMLTOOLING_DOXYGEN(Sets the proper child.) \
775         virtual void set##proper(proper* child)=0
776
777 /**
778  * Declares abstract get/set methods for a typed XML child object.
779  *
780  * @param proper    the proper name of the child type
781  */
782 #define DECL_TYPED_CHILD(proper) \
783     public: \
784         XMLTOOLING_DOXYGEN(Returns the proper child.) \
785         virtual proper* get##proper() const=0; \
786         XMLTOOLING_DOXYGEN(Sets the proper child.) \
787         virtual void set##proper(proper* child)=0
788
789 /**
790  * Declares abstract get/set methods for a generic XML child object.
791  *
792  * @param proper    the proper name of the child
793  */
794 #define DECL_XMLOBJECT_CHILD(proper) \
795     public: \
796         XMLTOOLING_DOXYGEN(Returns the proper child.) \
797         virtual xmltooling::XMLObject* get##proper() const=0; \
798         XMLTOOLING_DOXYGEN(Sets the proper child.) \
799         virtual void set##proper(xmltooling::XMLObject* child)=0
800
801
802 /**
803  * Implements get/set methods and a private list iterator member for a typed XML child object.
804  *
805  * @param proper    the proper name of the child type
806  */
807 #define IMPL_TYPED_CHILD(proper) \
808     protected: \
809         proper* m_##proper; \
810         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
811     public: \
812         proper* get##proper() const { \
813             return m_##proper; \
814         } \
815         void set##proper(proper* child) { \
816             prepareForAssignment(m_##proper,child); \
817             *m_pos_##proper = m_##proper = child; \
818         }
819
820 /**
821  * Implements get/set methods and a private list iterator member for
822  * a typed XML child object in a foreign namespace
823  *
824  * @param proper    the proper name of the child type
825  * @param ns        the C++ namespace for the type
826  */
827 #define IMPL_TYPED_FOREIGN_CHILD(proper,ns) \
828     protected: \
829         ns::proper* m_##proper; \
830         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
831     public: \
832         ns::proper* get##proper() const { \
833             return m_##proper; \
834         } \
835         void set##proper(ns::proper* child) { \
836             prepareForAssignment(m_##proper,child); \
837             *m_pos_##proper = m_##proper = child; \
838         }
839
840 /**
841  * Implements get/set methods and a private list iterator member for a generic XML child object.
842  *
843  * @param proper    the proper name of the child
844  */
845 #define IMPL_XMLOBJECT_CHILD(proper) \
846     protected: \
847         xmltooling::XMLObject* m_##proper; \
848         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
849     public: \
850         xmltooling::XMLObject* get##proper() const { \
851             return m_##proper; \
852         } \
853         void set##proper(xmltooling::XMLObject* child) { \
854             prepareForAssignment(m_##proper,child); \
855             *m_pos_##proper = m_##proper = child; \
856         }
857
858 /**
859  * Declares abstract get/set methods for a typed XML child collection.
860  *
861  * @param proper    the proper name of the child type
862  */
863 #define DECL_TYPED_CHILDREN(proper) \
864     public: \
865         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
866         virtual VectorOf(proper) get##proper##s()=0; \
867         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
868         virtual const std::vector<proper*>& get##proper##s() const=0
869
870 /**
871  * Declares abstract get/set methods for a typed XML child collection in a foreign namespace.
872  *
873  * @param proper    the proper name of the child type
874  * @param ns        the C++ namespace for the type
875  */
876 #define DECL_TYPED_FOREIGN_CHILDREN(proper,ns) \
877     public: \
878         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
879         virtual VectorOf(ns::proper) get##proper##s()=0; \
880         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
881         virtual const std::vector<ns::proper*>& get##proper##s() const=0
882
883 /**
884  * Declares abstract get/set methods for a generic XML child collection.
885  *
886  * @param proper    the proper name of the child
887  */
888 #define DECL_XMLOBJECT_CHILDREN(proper) \
889     public: \
890         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
891         virtual VectorOf(xmltooling::XMLObject) get##proper##s()=0; \
892         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
893         virtual const std::vector<xmltooling::XMLObject*>& get##proper##s() const=0
894
895 /**
896  * Implements get method and a private vector member for a typed XML child collection.
897  *
898  * @param proper    the proper name of the child type
899  * @param fence     insertion fence for new objects of the child collection in backing list
900  */
901 #define IMPL_TYPED_CHILDREN(proper,fence) \
902     protected: \
903         std::vector<proper*> m_##proper##s; \
904     public: \
905         VectorOf(proper) get##proper##s() { \
906             return VectorOf(proper)(this, m_##proper##s, &m_children, fence); \
907         } \
908         const std::vector<proper*>& get##proper##s() const { \
909             return m_##proper##s; \
910         }
911
912 /**
913  * Implements get method and a private vector member for a typed XML child collection
914  * in a foreign namespace.
915  *
916  * @param proper    the proper name of the child type
917  * @param ns        the C++ namespace for the type
918  * @param fence     insertion fence for new objects of the child collection in backing list
919  */
920 #define IMPL_TYPED_FOREIGN_CHILDREN(proper,ns,fence) \
921     protected: \
922         std::vector<ns::proper*> m_##proper##s; \
923     public: \
924         VectorOf(ns::proper) get##proper##s() { \
925             return VectorOf(ns::proper)(this, m_##proper##s, &m_children, fence); \
926         } \
927         const std::vector<ns::proper*>& get##proper##s() const { \
928             return m_##proper##s; \
929         }
930
931 /**
932  * Implements get method and a private vector member for a generic XML child collection.
933  *
934  * @param proper    the proper name of the child
935  * @param fence     insertion fence for new objects of the child collection in backing list
936  */
937 #define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
938     protected: \
939         std::vector<xmltooling::XMLObject*> m_##proper##s; \
940     public: \
941         VectorOf(xmltooling::XMLObject) get##proper##s() { \
942             return VectorOf(xmltooling::XMLObject)(this, m_##proper##s, &m_children, fence); \
943         } \
944         const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
945             return m_##proper##s; \
946         }
947
948 /**
949  * Implements marshalling for a string attribute
950  *
951  * @param proper        the proper name of the attribute
952  * @param ucase         the upcased name of the attribute
953  * @param namespaceURI  the XML namespace of the attribute
954  */
955 #define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
956     if (m_##proper && *m_##proper) { \
957         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
958     }
959
960 /**
961  * Implements marshalling for a DateTime attribute
962  *
963  * @param proper        the proper name of the attribute
964  * @param ucase         the upcased name of the attribute
965  * @param namespaceURI  the XML namespace of the attribute
966  */
967 #define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
968     if (m_##proper) { \
969         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper->getRawData()); \
970     }
971
972 /**
973  * Implements marshalling for an integer attribute
974  *
975  * @param proper        the proper name of the attribute
976  * @param ucase         the upcased name of the attribute
977  * @param namespaceURI  the XML namespace of the attribute
978  */
979 #define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
980     if (m_##proper && *m_##proper) { \
981         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
982     }
983
984 /**
985  * Implements marshalling for a boolean attribute
986  *
987  * @param proper        the proper name of the attribute
988  * @param ucase         the upcased name of the attribute
989  * @param namespaceURI  the XML namespace of the attribute
990  */
991 #define MARSHALL_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
992     switch (m_##proper) { \
993         case xmlconstants::XML_BOOL_TRUE: \
994             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_TRUE); \
995             break; \
996         case xmlconstants::XML_BOOL_ONE: \
997             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ONE); \
998             break; \
999         case xmlconstants::XML_BOOL_FALSE: \
1000             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_FALSE); \
1001             break; \
1002         case xmlconstants::XML_BOOL_ZERO: \
1003             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ZERO); \
1004             break; \
1005         case xmlconstants::XML_BOOL_NULL: \
1006             break; \
1007     }
1008
1009 /**
1010  * Implements marshalling for a QName attribute
1011  *
1012  * @param proper        the proper name of the attribute
1013  * @param ucase         the upcased name of the attribute
1014  * @param namespaceURI  the XML namespace of the attribute
1015  */
1016 #define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
1017     if (m_##proper) { \
1018         auto_ptr_XMLCh qstr(m_##proper->toString().c_str()); \
1019         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
1020     }
1021
1022 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
1023 /**
1024  * Implements marshalling for an ID attribute
1025  *
1026  * @param proper        the proper name of the attribute
1027  * @param ucase         the upcased name of the attribute
1028  * @param namespaceURI  the XML namespace of the attribute
1029  */
1030 # define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
1031     if (m_##proper && *m_##proper) { \
1032         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
1033         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, true); \
1034     }
1035 #else
1036 /**
1037  * Implements marshalling for an ID attribute
1038  *
1039  * @param proper        the proper name of the attribute
1040  * @param ucase         the upcased name of the attribute
1041  * @param namespaceURI  the XML namespace of the attribute
1042  */
1043 # define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
1044     if (m_##proper && *m_##proper) { \
1045         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
1046         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
1047     }
1048 #endif
1049
1050 /**
1051  * Implements unmarshalling process branch for a string attribute
1052  *
1053  * @param proper        the proper name of the attribute
1054  * @param ucase         the upcased name of the attribute
1055  * @param namespaceURI  the XML namespace of the attribute
1056  */
1057 #define PROC_STRING_ATTRIB(proper,ucase,namespaceURI) \
1058     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1059         set##proper(attribute->getValue()); \
1060         return; \
1061     }
1062
1063 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
1064 /**
1065  * Implements unmarshalling process branch for an ID attribute
1066  *
1067  * @param proper        the proper name of the attribute
1068  * @param ucase         the upcased name of the attribute
1069  * @param namespaceURI  the XML namespace of the attribute
1070  */
1071 # define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
1072     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1073         set##proper(attribute->getValue()); \
1074         attribute->getOwnerElement()->setIdAttributeNode(attribute, true); \
1075         return; \
1076     }
1077 #else
1078 /**
1079  * Implements unmarshalling process branch for an ID attribute
1080  *
1081  * @param proper        the proper name of the attribute
1082  * @param ucase         the upcased name of the attribute
1083  * @param namespaceURI  the XML namespace of the attribute
1084  */
1085 # define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
1086     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1087         set##proper(attribute->getValue()); \
1088         attribute->getOwnerElement()->setIdAttributeNode(attribute); \
1089         return; \
1090     }
1091 #endif
1092
1093 /**
1094  * Implements unmarshalling process branch for a DateTime attribute
1095  *
1096  * @param proper        the proper name of the attribute
1097  * @param ucase         the upcased name of the attribute
1098  * @param namespaceURI  the XML namespace of the attribute
1099  */
1100 #define PROC_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
1101     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1102
1103 /**
1104  * Implements unmarshalling process branch for a DateTime attribute
1105  *
1106  * @param proper        the proper name of the attribute
1107  * @param ucase         the upcased name of the attribute
1108  * @param namespaceURI  the XML namespace of the attribute
1109  */
1110 #define PROC_QNAME_ATTRIB(proper,ucase,namespaceURI) \
1111     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1112         set##proper(XMLHelper::getAttributeValueAsQName(attribute)); \
1113         return; \
1114     }
1115
1116 /**
1117  * Implements unmarshalling process branch for an integer attribute
1118  *
1119  * @param proper        the proper name of the attribute
1120  * @param ucase         the upcased name of the attribute
1121  * @param namespaceURI  the XML namespace of the attribute
1122  */
1123 #define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
1124     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1125
1126 /**
1127  * Implements unmarshalling process branch for a boolean attribute
1128  *
1129  * @param proper        the proper name of the attribute
1130  * @param ucase         the upcased name of the attribute
1131  * @param namespaceURI  the XML namespace of the attribute
1132  */
1133 #define PROC_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
1134     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1135
1136 /**
1137  * Implements unmarshalling process branch for typed child collection element
1138  *
1139  * @param proper        the proper name of the child type
1140  * @param namespaceURI  the XML namespace of the child element
1141  * @param force         bypass use of hint and just cast down to check child
1142  */
1143 #define PROC_TYPED_CHILDREN(proper,namespaceURI,force) \
1144     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1145         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
1146         if (typesafe) { \
1147             get##proper##s().push_back(typesafe); \
1148             return; \
1149         } \
1150     }
1151
1152 /**
1153  * Implements unmarshalling process branch for typed child collection element
1154  * in a foreign namespace.
1155  *
1156  * @param proper        the proper name of the child type
1157  * @param ns            the C++ namespace for the type
1158  * @param namespaceURI  the XML namespace of the child element
1159  * @param force         bypass use of hint and just cast down to check child
1160  */
1161 #define PROC_TYPED_FOREIGN_CHILDREN(proper,ns,namespaceURI,force) \
1162     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1163         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1164         if (typesafe) { \
1165             get##proper##s().push_back(typesafe); \
1166             return; \
1167         } \
1168     }
1169
1170 /**
1171  * Implements unmarshalling process branch for typed child singleton element
1172  *
1173  * @param proper        the proper name of the child type
1174  * @param namespaceURI  the XML namespace of the child element
1175  * @param force         bypass use of hint and just cast down to check child
1176  */
1177 #define PROC_TYPED_CHILD(proper,namespaceURI,force) \
1178     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1179         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
1180         if (typesafe && !m_##proper) { \
1181             typesafe->setParent(this); \
1182             *m_pos_##proper = m_##proper = typesafe; \
1183             return; \
1184         } \
1185     }
1186
1187 /**
1188  * Implements unmarshalling process branch for typed child singleton element
1189  * in a foreign namespace.
1190  *
1191  * @param proper        the proper name of the child type
1192  * @param ns            the C++ namespace for the type
1193  * @param namespaceURI  the XML namespace of the child element
1194  * @param force         bypass use of hint and just cast down to check child
1195  */
1196 #define PROC_TYPED_FOREIGN_CHILD(proper,ns,namespaceURI,force) \
1197     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1198         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1199         if (typesafe && !m_##proper) { \
1200             typesafe->setParent(this); \
1201             *m_pos_##proper = m_##proper = typesafe; \
1202             return; \
1203         } \
1204     }
1205
1206 /**
1207  * Implements unmarshalling process branch for a generic child singleton element
1208  *
1209  * @param proper        the proper name of the child type
1210  * @param namespaceURI  the XML namespace of the child element
1211  */
1212 #define PROC_XMLOBJECT_CHILD(proper,namespaceURI) \
1213     if (xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1214         if (!m_##proper) { \
1215             childXMLObject->setParent(this); \
1216             *m_pos_##proper = m_##proper = childXMLObject; \
1217             return; \
1218         } \
1219     }
1220
1221 /**
1222  * Declares aliased get/set methods for named XML element simple content.
1223  *
1224  * @param proper    the proper name to label the element's content
1225  */
1226 #define DECL_SIMPLE_CONTENT(proper) \
1227     XMLTOOLING_DOXYGEN(Returns proper.) \
1228     const XMLCh* get##proper() const { \
1229         return getTextContent(); \
1230     } \
1231     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1232     void set##proper(const XMLCh* proper) { \
1233         setTextContent(proper); \
1234     }
1235
1236 /**
1237  * Declares aliased get/set methods for named integer XML element content.
1238  *
1239  * @param proper    the proper name to label the element's content
1240  */
1241 #define DECL_INTEGER_CONTENT(proper) \
1242     XMLTOOLING_DOXYGEN(Returns proper in integer form after a NULL indicator.) \
1243     std::pair<bool,int> get##proper() const { \
1244         return std::make_pair((getTextContent()!=nullptr), (getTextContent()!=nullptr ? xercesc::XMLString::parseInt(getTextContent()) : 0)); \
1245     } \
1246     XMLTOOLING_DOXYGEN(Sets proper.) \
1247     void set##proper(int proper) { \
1248         char buf[64]; \
1249         sprintf(buf,"%d",proper); \
1250         xmltooling::auto_ptr_XMLCh widebuf(buf); \
1251         setTextContent(widebuf.get()); \
1252     } \
1253     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1254     void set##proper(const XMLCh* proper) { \
1255         setTextContent(proper); \
1256     }
1257
1258 /**
1259  * Implements cloning methods for an XMLObject specialization implementation class.
1260  *
1261  * @param cname    the name of the XMLObject specialization
1262  */
1263 #define IMPL_XMLOBJECT_CLONE(cname) \
1264     cname* clone##cname() const { \
1265         return dynamic_cast<cname*>(clone()); \
1266     } \
1267     xmltooling::XMLObject* clone() const { \
1268         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1269         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1270         if (ret) { \
1271             domClone.release(); \
1272             return ret; \
1273         } \
1274         return new cname##Impl(*this); \
1275     }
1276
1277 /**
1278  * Declares an XMLObject specialization with a simple content model and type,
1279  * handling it as string data.
1280  *
1281  * @param linkage   linkage specifier for the class
1282  * @param cname     the name of the XMLObject specialization
1283  * @param proper    the proper name to label the element's content
1284  * @param desc      documentation for class
1285  */
1286 #define DECL_XMLOBJECT_SIMPLE(linkage,cname,proper,desc) \
1287     BEGIN_XMLOBJECT(linkage,cname,xmltooling::XMLObject,desc); \
1288         DECL_SIMPLE_CONTENT(proper); \
1289     END_XMLOBJECT
1290
1291 /**
1292  * Declares and defines an implementation class for an XMLObject with
1293  * a simple content model and type, handling it as string data.
1294  *
1295  * @param linkage   linkage specifier for the class
1296  * @param cname     the name of the XMLObject specialization
1297  */
1298 #define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
1299     class linkage cname##Impl \
1300         : public virtual cname, \
1301             public xmltooling::AbstractSimpleElement, \
1302             public xmltooling::AbstractDOMCachingXMLObject, \
1303             public xmltooling::AbstractXMLObjectMarshaller, \
1304             public xmltooling::AbstractXMLObjectUnmarshaller \
1305     { \
1306     public: \
1307         virtual ~cname##Impl() {} \
1308         cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType) \
1309             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
1310         } \
1311         cname##Impl(const cname##Impl& src) \
1312             : xmltooling::AbstractXMLObject(src), \
1313                 xmltooling::AbstractSimpleElement(src), \
1314                 xmltooling::AbstractDOMCachingXMLObject(src) {} \
1315         IMPL_XMLOBJECT_CLONE(cname) \
1316     }
1317
1318 #ifdef HAVE_COVARIANT_RETURNS
1319
1320 /**
1321  * Begins the declaration of an XMLObjectBuilder specialization.
1322  * Basic boilerplate includes an empty virtual destructor, and
1323  * a default builder that defaults the element name.
1324  *
1325  * @param linkage           linkage specifier for the class
1326  * @param cname             the name of the XMLObject specialization
1327  * @param namespaceURI      the XML namespace of the default associated element
1328  * @param namespacePrefix   the XML namespace prefix of the default associated element
1329  */
1330 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1331     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1332     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1333     public: \
1334         virtual ~cname##Builder() {} \
1335         XMLTOOLING_DOXYGEN(Default builder.) \
1336         virtual cname* buildObject() const { \
1337             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1338         } \
1339         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1340         virtual cname* buildObject( \
1341             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1342             ) const
1343
1344 /**
1345  * Ends the declaration of an XMLObjectBuilder specialization.
1346  */
1347 #define END_XMLOBJECTBUILDER }
1348
1349 /**
1350  * Declares a generic XMLObjectBuilder specialization.
1351  *
1352  * @param linkage           linkage specifier for the class
1353  * @param cname             the name of the XMLObject specialization
1354  * @param namespaceURI      the XML namespace of the default associated element
1355  * @param namespacePrefix   the XML namespace prefix of the default associated element
1356  */
1357  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1358     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1359     XMLTOOLING_DOXYGEN(Singleton builder.) \
1360     static cname* build##cname() { \
1361         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1362             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1363             ); \
1364         if (b) \
1365             return b->buildObject(); \
1366         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1367     } \
1368     END_XMLOBJECTBUILDER
1369
1370 /**
1371  * Implements the standard XMLObjectBuilder specialization function.
1372  *
1373  * @param cname the name of the XMLObject specialization
1374  */
1375 #define IMPL_XMLOBJECTBUILDER(cname) \
1376     cname* cname##Builder::buildObject( \
1377         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1378         ) const \
1379     { \
1380         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1381     }
1382
1383 #else   /* !HAVE_COVARIANT_RETURNS */
1384
1385 /**
1386  * Begins the declaration of an XMLObjectBuilder specialization.
1387  * Basic boilerplate includes an empty virtual destructor, and
1388  * a default builder that defaults the element name.
1389  *
1390  * @param linkage           linkage specifier for the class
1391  * @param cname             the name of the XMLObject specialization
1392  * @param namespaceURI      the XML namespace of the default associated element
1393  * @param namespacePrefix   the XML namespace prefix of the default associated element
1394  */
1395 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1396     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1397     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1398     public: \
1399         virtual ~cname##Builder() {} \
1400         XMLTOOLING_DOXYGEN(Default builder.) \
1401         virtual xmltooling::XMLObject* buildObject() const { \
1402             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1403         } \
1404         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1405         virtual xmltooling::XMLObject* buildObject( \
1406             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1407             ) const
1408
1409 /**
1410  * Ends the declaration of an XMLObjectBuilder specialization.
1411  */
1412 #define END_XMLOBJECTBUILDER }
1413
1414 /**
1415  * Declares a generic XMLObjectBuilder specialization.
1416  *
1417  * @param linkage           linkage specifier for the class
1418  * @param cname             the name of the XMLObject specialization
1419  * @param namespaceURI      the XML namespace of the default associated element
1420  * @param namespacePrefix   the XML namespace prefix of the default associated element
1421  */
1422  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1423     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1424     XMLTOOLING_DOXYGEN(Singleton builder.) \
1425     static cname* build##cname() { \
1426         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1427             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1428             ); \
1429         if (b) \
1430             return dynamic_cast<cname*>(b->buildObject()); \
1431         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1432     } \
1433     END_XMLOBJECTBUILDER
1434
1435 /**
1436  * Implements the standard XMLObjectBuilder specialization function.
1437  *
1438  * @param cname the name of the XMLObject specialization
1439  */
1440 #define IMPL_XMLOBJECTBUILDER(cname) \
1441     xmltooling::XMLObject* cname##Builder::buildObject( \
1442         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1443         ) const \
1444     { \
1445         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1446     }
1447
1448 #endif  /* HAVE_COVARIANT_RETURNS */
1449
1450 /**
1451  * Begins the declaration of a Schema Validator specialization.
1452  *
1453  * @param linkage           linkage specifier for the class
1454  * @param cname the base name of the Validator specialization
1455  */
1456  #define BEGIN_XMLOBJECTVALIDATOR(linkage,cname) \
1457     class linkage cname##SchemaValidator : public xmltooling::Validator \
1458     { \
1459     public: \
1460         virtual ~cname##SchemaValidator() {} \
1461         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1462             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1463             if (!ptr) \
1464                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name())); \
1465             if (ptr->nil() && (ptr->hasChildren() || ptr->getTextContent())) \
1466                 throw xmltooling::ValidationException("Object has nil property but with children or content.")
1467
1468 /**
1469  * Begins the declaration of a Schema Validator specialization subclass.
1470  *
1471  * @param linkage   linkage specifier for the class
1472  * @param cname     the base name of the Validator specialization
1473  * @param base      base class for the validator
1474  */
1475  #define BEGIN_XMLOBJECTVALIDATOR_SUB(linkage,cname,base) \
1476     class linkage cname##SchemaValidator : public base##SchemaValidator \
1477     { \
1478     public: \
1479         virtual ~cname##SchemaValidator() {} \
1480         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1481             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1482             if (!ptr) \
1483                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()));
1484
1485 /**
1486  * Ends the declaration of a Validator specialization.
1487  */
1488 #define END_XMLOBJECTVALIDATOR } }
1489
1490 /**
1491  * Validator code that checks the object type.
1492  *
1493  * @param cname     the name of the XMLObject specialization
1494  */
1495 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
1496     const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1497     if (!ptr) \
1498         throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1499
1500 /**
1501  * Validator code that checks for a required attribute, content, or singleton.
1502  *
1503  * @param cname     the name of the XMLObject specialization
1504  * @param proper    the proper name of the attribute, content, or singleton member
1505  */
1506 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
1507     if (!ptr->get##proper()) \
1508         throw xmltooling::ValidationException(#cname" must have "#proper".")
1509
1510 /**
1511  * Validator code that checks for a required integer attribute
1512  *
1513  * @param cname     the name of the XMLObject specialization
1514  * @param proper    the proper name of the attribute, content, or singleton member
1515  */
1516 #define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
1517     if (!ptr->get##proper().first) \
1518         throw xmltooling::ValidationException(#cname" must have "#proper".")
1519
1520 /**
1521  * Validator code that checks for one of a pair of
1522  * required attributes, content, or singletons.
1523  *
1524  * @param cname     the name of the XMLObject specialization
1525  * @param proper1   the proper name of the first attribute, content, or singleton member
1526  * @param proper2   the proper name of the second attribute, content, or singleton member
1527  */
1528 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
1529     if (!ptr->get##proper1() && !ptr->get##proper2()) \
1530         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
1531
1532 /**
1533  * Validator code that checks for one of a pair of
1534  * required attributes, content, or singletons, but disallows both.
1535  *
1536  * @param cname     the name of the XMLObject specialization
1537  * @param proper1   the proper name of the first attribute, content, or singleton member
1538  * @param proper2   the proper name of the second attribute, content, or singleton member
1539  */
1540 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
1541     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
1542         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
1543
1544 /**
1545  * Validator code that checks for one of a set of three
1546  * required attributes, content, or singletons.
1547  *
1548  * @param cname     the name of the XMLObject specialization
1549  * @param proper1   the proper name of the first attribute, content, or singleton member
1550  * @param proper2   the proper name of the second attribute, content, or singleton member
1551  * @param proper3   the proper name of the third attribute, content, or singleton member
1552  */
1553 #define XMLOBJECTVALIDATOR_ONEOF3(cname,proper1,proper2,proper3) \
1554     if (!ptr->get##proper1() && !ptr->get##proper2() && !ptr->get##proper3()) \
1555         throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
1556
1557 /**
1558  * Validator code that checks for one of a set of three
1559  * required attributes, content, or singletons but disallows more than one.
1560  *
1561  * @param cname     the name of the XMLObject specialization
1562  * @param proper1   the proper name of the first attribute, content, or singleton member
1563  * @param proper2   the proper name of the second attribute, content, or singleton member
1564  * @param proper3   the proper name of the third attribute, content, or singleton member
1565  */
1566 #define XMLOBJECTVALIDATOR_ONLYONEOF3(cname,proper1,proper2,proper3) \
1567     int c##proper1##proper2##proper3=0; \
1568     if (ptr->get##proper1()!=nullptr) \
1569         c##proper1##proper2##proper3++; \
1570     if (ptr->get##proper2()!=nullptr) \
1571         c##proper1##proper2##proper3++; \
1572     if (ptr->get##proper3()!=nullptr) \
1573         c##proper1##proper2##proper3++; \
1574     if (c##proper1##proper2##proper3 != 1) \
1575         throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
1576
1577 /**
1578  * Validator code that checks a co-constraint (if one present, the other must be)
1579  * between a pair of attributes, content, or singletons.
1580  *
1581  * @param cname     the name of the XMLObject specialization
1582  * @param proper1   the proper name of the first attribute, content, or singleton member
1583  * @param proper2   the proper name of the second attribute, content, or singleton member
1584  */
1585 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
1586     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
1587         throw xmltooling::ValidationException(#cname" cannot have "#proper1" without "#proper2".")
1588
1589 /**
1590  * Validator code that checks for a non-empty collection.
1591  *
1592  * @param cname     the name of the XMLObject specialization
1593  * @param proper    the proper name of the collection item
1594  */
1595 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
1596     if (ptr->get##proper##s().empty()) \
1597         throw xmltooling::ValidationException(#cname" must have at least one "#proper".")
1598
1599 /**
1600  * Declares/defines a Validator specialization that checks object type and
1601  * a non-empty simple content model.
1602  *
1603  * @param linkage   linkage specifier for the class
1604  * @param cname     the name of the XMLObject specialization
1605  */
1606 #define XMLOBJECTVALIDATOR_SIMPLE(linkage,cname) \
1607     BEGIN_XMLOBJECTVALIDATOR(linkage,cname); \
1608         XMLOBJECTVALIDATOR_REQUIRE(cname,TextContent); \
1609     END_XMLOBJECTVALIDATOR
1610
1611 #include <utility>
1612
1613 /**
1614  * @namespace xmltooling
1615  * Public namespace of XML Tooling library
1616  */
1617 namespace xmltooling {
1618
1619     /**
1620      * Template function for cloning a sequence of XMLObjects.
1621      * Invokes the clone() member on each element of the input sequence and adds the copy to
1622      * the output sequence. Order is preserved.
1623      *
1624      * @param in    input sequence to clone
1625      * @param out   output sequence to copy cloned pointers into
1626      */
1627     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
1628         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
1629             if (*i)
1630                 out.push_back((*i)->clone());
1631             else
1632                 out.push_back(*i);
1633         }
1634     }
1635
1636     /**
1637      * Functor for cleaning up heap objects in containers.
1638      */
1639     template<class T> struct cleanup
1640     {
1641         /**
1642          * Function operator to delete an object.
1643          *
1644          * @param ptr   object to delete
1645          */
1646         void operator()(T* ptr) {delete ptr;}
1647
1648         /**
1649          * Function operator to delete an object stored as const.
1650          *
1651          * @param ptr   object to delete after casting away const
1652          */
1653         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
1654     };
1655
1656     /**
1657      * Functor for cleaning up heap objects in key/value containers.
1658      */
1659     template<class A,class B> struct cleanup_pair
1660     {
1661         /**
1662          * Function operator to delete an object.
1663          *
1664          * @param p   a pair in which the second component is the object to delete
1665          */
1666         void operator()(const std::pair<const A,B*>& p) {delete p.second;}
1667     };
1668
1669     /**
1670      * Functor for cleaning up const heap objects in key/value containers.
1671      */
1672     template<class A,class B> struct cleanup_const_pair
1673     {
1674         /**
1675          * Function operator to delete an object stored as const
1676          *
1677          * @param p   a pair in which the second component is the const object to delete
1678          */
1679         void operator()(const std::pair<const A,const B*>& p) {delete const_cast<B*>(p.second);}
1680     };
1681 };
1682
1683 #endif /* __xmltooling_base_h__ */