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