Add int/bool attribute clone macros
[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  * Implements cloning of a child attribute, for use in copy constructor or
1361  * deferred clone methods.
1362  *
1363  * proper   the proper name of the attribute to clone
1364  */
1365 #define IMPL_CLONE_ATTRIB(proper) \
1366     set##proper(src.get##proper())
1367
1368 /**
1369  * Implements cloning of an integer child attribute, for use in copy constructor or
1370  * deferred clone methods.
1371  *
1372  * proper   the proper name of the attribute to clone
1373  */
1374 #define IMPL_CLONE_INTEGER_ATTRIB(proper) \
1375     set##proper(src.m_##proper)
1376
1377 /**
1378  * Implements cloning of a boolean child attribute, for use in copy constructor or
1379  * deferred clone methods.
1380  *
1381  * proper   the proper name of the attribute to clone
1382  */
1383 #define IMPL_CLONE_BOOLEAN_ATTRIB(proper) \
1384     proper(src.m_##proper)
1385
1386 /**
1387  * Implements cloning of a child object, for use in copy constructor or
1388  * deferred clone methods.
1389  *
1390  * proper   the proper name of the child object to clone
1391  */
1392 #define IMPL_CLONE_XMLOBJECT_CHILD(proper) \
1393     if (src.get##proper()) \
1394         set##proper(src.get##proper()->clone())
1395
1396 /**
1397  * Implements cloning of a typed child object, for use in copy constructor or
1398  * deferred clone methods.
1399  *
1400  * proper   the proper name of the child type to clone
1401  */
1402 #define IMPL_CLONE_TYPED_CHILD(proper) \
1403     if (src.get##proper()) \
1404         set##proper(src.get##proper()->clone##proper())
1405
1406 /**
1407  * Implements cloning of an untyped child collection, for use in copy constructor or
1408  * deferred clone methods.
1409  */
1410 #define IMPL_CLONE_XMLOBJECT_CHILDREN() \
1411     static void (VectorOf(XMLObject)::* XMLObject_push_back)(XMLObject* const&) = &VectorOf(XMLObject)::push_back; \
1412     VectorOf(XMLObject) cXMLObject = getUnknownXMLObjects(); \
1413     std::for_each( \
1414         src.m_UnknownXMLObjects.begin(), src.m_UnknownXMLObjects.end(), \
1415         boost::lambda::if_(boost::lambda::_1 != ((XMLObject*)nullptr)) \
1416             [boost::lambda::bind(XMLObject_push_back, boost::ref(cXMLObject), boost::lambda::bind(&XMLObject::clone, boost::lambda::_1))] \
1417         )
1418
1419 /**
1420  * Implements cloning of a child collection, for use in copy constructor or
1421  * deferred clone methods.
1422  *
1423  * proper   the proper name of the child type to clone
1424  */
1425 #define IMPL_CLONE_TYPED_CHILDREN(proper) \
1426     static void (VectorOf(proper)::* proper##_push_back)(proper* const&) = &VectorOf(proper)::push_back; \
1427     VectorOf(proper) c##proper = get##proper##s(); \
1428     std::for_each( \
1429         src.m_##proper##s.begin(), src.m_##proper##s.end(), \
1430         boost::lambda::if_(boost::lambda::_1 != ((proper*)nullptr)) \
1431             [boost::lambda::bind(proper##_push_back, boost::ref(c##proper), boost::lambda::bind(&proper::clone##proper, boost::lambda::_1))] \
1432         )
1433
1434 /**
1435  * Implements cloning of a child collection in a foreign namespace, for use in copy constructor or
1436  * deferred clone methods.
1437  *
1438  * proper   the proper name of the child type to clone
1439  * ns       the namespace of the child type
1440  */
1441 #define IMPL_CLONE_TYPED_FOREIGN_CHILDREN(proper,ns) \
1442     static void (VectorOf(ns::proper)::* proper##_push_back)(ns::proper* const&) = &VectorOf(ns::proper)::push_back; \
1443     VectorOf(ns::proper) c##proper = get##proper##s(); \
1444     std::for_each( \
1445         src.m_##proper##s.begin(), src.m_##proper##s.end(), \
1446         boost::lambda::if_(boost::lambda::_1 != ((ns::proper*)nullptr)) \
1447             [boost::lambda::bind(proper##_push_back, boost::ref(c##proper), boost::lambda::bind(&ns::proper::clone##proper, boost::lambda::_1))] \
1448         )
1449
1450 /**
1451  * Declares an XMLObject specialization with a simple content model and type,
1452  * handling it as string data.
1453  *
1454  * @param linkage   linkage specifier for the class
1455  * @param cname     the name of the XMLObject specialization
1456  * @param proper    the proper name to label the element's content
1457  * @param desc      documentation for class
1458  */
1459 #define DECL_XMLOBJECT_SIMPLE(linkage,cname,proper,desc) \
1460     BEGIN_XMLOBJECT(linkage,cname,xmltooling::XMLObject,desc); \
1461         DECL_SIMPLE_CONTENT(proper); \
1462     END_XMLOBJECT
1463
1464 /**
1465  * Declares and defines an implementation class for an XMLObject with
1466  * a simple content model and type, handling it as string data.
1467  *
1468  * @param linkage   linkage specifier for the class
1469  * @param cname     the name of the XMLObject specialization
1470  */
1471 #define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
1472     class linkage cname##Impl \
1473         : public virtual cname, \
1474             public xmltooling::AbstractSimpleElement, \
1475             public xmltooling::AbstractDOMCachingXMLObject, \
1476             public xmltooling::AbstractXMLObjectMarshaller, \
1477             public xmltooling::AbstractXMLObjectUnmarshaller \
1478     { \
1479     public: \
1480         virtual ~cname##Impl() {} \
1481         cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType) \
1482             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
1483         } \
1484         cname##Impl(const cname##Impl& src) \
1485             : xmltooling::AbstractXMLObject(src), \
1486                 xmltooling::AbstractSimpleElement(src), \
1487                 xmltooling::AbstractDOMCachingXMLObject(src) {} \
1488         IMPL_XMLOBJECT_CLONE(cname) \
1489     }
1490
1491 #ifdef HAVE_COVARIANT_RETURNS
1492
1493 /**
1494  * Begins the declaration of an XMLObjectBuilder specialization.
1495  * Basic boilerplate includes an empty virtual destructor, and
1496  * a default builder that defaults the element name.
1497  *
1498  * @param linkage           linkage specifier for the class
1499  * @param cname             the name of the XMLObject specialization
1500  * @param namespaceURI      the XML namespace of the default associated element
1501  * @param namespacePrefix   the XML namespace prefix of the default associated element
1502  */
1503 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1504     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1505     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1506     public: \
1507         virtual ~cname##Builder() {} \
1508         XMLTOOLING_DOXYGEN(Default builder.) \
1509         virtual cname* buildObject() const { \
1510             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1511         } \
1512         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1513         virtual cname* buildObject( \
1514             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1515             ) const
1516
1517 /**
1518  * Ends the declaration of an XMLObjectBuilder specialization.
1519  */
1520 #define END_XMLOBJECTBUILDER }
1521
1522 /**
1523  * Declares a generic XMLObjectBuilder specialization.
1524  *
1525  * @param linkage           linkage specifier for the class
1526  * @param cname             the name of the XMLObject specialization
1527  * @param namespaceURI      the XML namespace of the default associated element
1528  * @param namespacePrefix   the XML namespace prefix of the default associated element
1529  */
1530  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1531     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1532     XMLTOOLING_DOXYGEN(Singleton builder.) \
1533     static cname* build##cname() { \
1534         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1535             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1536             ); \
1537         if (b) \
1538             return b->buildObject(); \
1539         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1540     } \
1541     END_XMLOBJECTBUILDER
1542
1543 /**
1544  * Implements the standard XMLObjectBuilder specialization function.
1545  *
1546  * @param cname the name of the XMLObject specialization
1547  */
1548 #define IMPL_XMLOBJECTBUILDER(cname) \
1549     cname* cname##Builder::buildObject( \
1550         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1551         ) const \
1552     { \
1553         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1554     }
1555
1556 #else   /* !HAVE_COVARIANT_RETURNS */
1557
1558 /**
1559  * Begins the declaration of an XMLObjectBuilder specialization.
1560  * Basic boilerplate includes an empty virtual destructor, and
1561  * a default builder that defaults the element name.
1562  *
1563  * @param linkage           linkage specifier for the class
1564  * @param cname             the name of the XMLObject specialization
1565  * @param namespaceURI      the XML namespace of the default associated element
1566  * @param namespacePrefix   the XML namespace prefix of the default associated element
1567  */
1568 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1569     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1570     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1571     public: \
1572         virtual ~cname##Builder() {} \
1573         XMLTOOLING_DOXYGEN(Default builder.) \
1574         virtual xmltooling::XMLObject* buildObject() const { \
1575             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1576         } \
1577         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1578         virtual xmltooling::XMLObject* buildObject( \
1579             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1580             ) const
1581
1582 /**
1583  * Ends the declaration of an XMLObjectBuilder specialization.
1584  */
1585 #define END_XMLOBJECTBUILDER }
1586
1587 /**
1588  * Declares a generic XMLObjectBuilder specialization.
1589  *
1590  * @param linkage           linkage specifier for the class
1591  * @param cname             the name of the XMLObject specialization
1592  * @param namespaceURI      the XML namespace of the default associated element
1593  * @param namespacePrefix   the XML namespace prefix of the default associated element
1594  */
1595  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1596     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1597     XMLTOOLING_DOXYGEN(Singleton builder.) \
1598     static cname* build##cname() { \
1599         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1600             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1601             ); \
1602         if (b) \
1603             return dynamic_cast<cname*>(b->buildObject()); \
1604         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1605     } \
1606     END_XMLOBJECTBUILDER
1607
1608 /**
1609  * Implements the standard XMLObjectBuilder specialization function.
1610  *
1611  * @param cname the name of the XMLObject specialization
1612  */
1613 #define IMPL_XMLOBJECTBUILDER(cname) \
1614     xmltooling::XMLObject* cname##Builder::buildObject( \
1615         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1616         ) const \
1617     { \
1618         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1619     }
1620
1621 #endif  /* HAVE_COVARIANT_RETURNS */
1622
1623 /**
1624  * Begins the declaration of a Schema Validator specialization.
1625  *
1626  * @param linkage           linkage specifier for the class
1627  * @param cname the base name of the Validator specialization
1628  */
1629  #define BEGIN_XMLOBJECTVALIDATOR(linkage,cname) \
1630     class linkage cname##SchemaValidator : public xmltooling::Validator \
1631     { \
1632     public: \
1633         virtual ~cname##SchemaValidator() {} \
1634         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1635             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1636             if (!ptr) \
1637                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name())); \
1638             if (ptr->nil() && (ptr->hasChildren() || ptr->getTextContent())) \
1639                 throw xmltooling::ValidationException("Object has nil property but with children or content.")
1640
1641 /**
1642  * Begins the declaration of a Schema Validator specialization subclass.
1643  *
1644  * @param linkage   linkage specifier for the class
1645  * @param cname     the base name of the Validator specialization
1646  * @param base      base class for the validator
1647  */
1648  #define BEGIN_XMLOBJECTVALIDATOR_SUB(linkage,cname,base) \
1649     class linkage cname##SchemaValidator : public base##SchemaValidator \
1650     { \
1651     public: \
1652         virtual ~cname##SchemaValidator() {} \
1653         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1654             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1655             if (!ptr) \
1656                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()));
1657
1658 /**
1659  * Ends the declaration of a Validator specialization.
1660  */
1661 #define END_XMLOBJECTVALIDATOR } }
1662
1663 /**
1664  * Validator code that checks the object type.
1665  *
1666  * @param cname     the name of the XMLObject specialization
1667  */
1668 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
1669     const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1670     if (!ptr) \
1671         throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1672
1673 /**
1674  * Validator code that checks for a required attribute, content, or singleton.
1675  *
1676  * @param cname     the name of the XMLObject specialization
1677  * @param proper    the proper name of the attribute, content, or singleton member
1678  */
1679 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
1680     if (!ptr->get##proper()) \
1681         throw xmltooling::ValidationException(#cname" must have "#proper".")
1682
1683 /**
1684  * Validator code that checks for a required integer attribute
1685  *
1686  * @param cname     the name of the XMLObject specialization
1687  * @param proper    the proper name of the attribute, content, or singleton member
1688  */
1689 #define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
1690     if (!ptr->get##proper().first) \
1691         throw xmltooling::ValidationException(#cname" must have "#proper".")
1692
1693 /**
1694  * Validator code that checks for one of a pair of
1695  * required attributes, content, or singletons.
1696  *
1697  * @param cname     the name of the XMLObject specialization
1698  * @param proper1   the proper name of the first attribute, content, or singleton member
1699  * @param proper2   the proper name of the second attribute, content, or singleton member
1700  */
1701 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
1702     if (!ptr->get##proper1() && !ptr->get##proper2()) \
1703         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
1704
1705 /**
1706  * Validator code that checks for one of a pair of
1707  * required attributes, content, or singletons, but disallows both.
1708  *
1709  * @param cname     the name of the XMLObject specialization
1710  * @param proper1   the proper name of the first attribute, content, or singleton member
1711  * @param proper2   the proper name of the second attribute, content, or singleton member
1712  */
1713 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
1714     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
1715         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
1716
1717 /**
1718  * Validator code that checks for one of a set of three
1719  * required attributes, content, or singletons.
1720  *
1721  * @param cname     the name of the XMLObject specialization
1722  * @param proper1   the proper name of the first attribute, content, or singleton member
1723  * @param proper2   the proper name of the second attribute, content, or singleton member
1724  * @param proper3   the proper name of the third attribute, content, or singleton member
1725  */
1726 #define XMLOBJECTVALIDATOR_ONEOF3(cname,proper1,proper2,proper3) \
1727     if (!ptr->get##proper1() && !ptr->get##proper2() && !ptr->get##proper3()) \
1728         throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
1729
1730 /**
1731  * Validator code that checks for one of a set of three
1732  * required attributes, content, or singletons but disallows more than one.
1733  *
1734  * @param cname     the name of the XMLObject specialization
1735  * @param proper1   the proper name of the first attribute, content, or singleton member
1736  * @param proper2   the proper name of the second attribute, content, or singleton member
1737  * @param proper3   the proper name of the third attribute, content, or singleton member
1738  */
1739 #define XMLOBJECTVALIDATOR_ONLYONEOF3(cname,proper1,proper2,proper3) \
1740     int c##proper1##proper2##proper3=0; \
1741     if (ptr->get##proper1()!=nullptr) \
1742         c##proper1##proper2##proper3++; \
1743     if (ptr->get##proper2()!=nullptr) \
1744         c##proper1##proper2##proper3++; \
1745     if (ptr->get##proper3()!=nullptr) \
1746         c##proper1##proper2##proper3++; \
1747     if (c##proper1##proper2##proper3 != 1) \
1748         throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
1749
1750 /**
1751  * Validator code that checks a co-constraint (if one present, the other must be)
1752  * between a pair of attributes, content, or singletons.
1753  *
1754  * @param cname     the name of the XMLObject specialization
1755  * @param proper1   the proper name of the first attribute, content, or singleton member
1756  * @param proper2   the proper name of the second attribute, content, or singleton member
1757  */
1758 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
1759     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
1760         throw xmltooling::ValidationException(#cname" cannot have "#proper1" without "#proper2".")
1761
1762 /**
1763  * Validator code that checks for a non-empty collection.
1764  *
1765  * @param cname     the name of the XMLObject specialization
1766  * @param proper    the proper name of the collection item
1767  */
1768 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
1769     if (ptr->get##proper##s().empty()) \
1770         throw xmltooling::ValidationException(#cname" must have at least one "#proper".")
1771
1772 /**
1773  * Declares/defines a Validator specialization that checks object type and
1774  * a non-empty simple content model.
1775  *
1776  * @param linkage   linkage specifier for the class
1777  * @param cname     the name of the XMLObject specialization
1778  */
1779 #define XMLOBJECTVALIDATOR_SIMPLE(linkage,cname) \
1780     BEGIN_XMLOBJECTVALIDATOR(linkage,cname); \
1781         XMLOBJECTVALIDATOR_REQUIRE(cname,TextContent); \
1782     END_XMLOBJECTVALIDATOR
1783
1784 #include <utility>
1785
1786 /**
1787  * @namespace xmltooling
1788  * Public namespace of XML Tooling library
1789  */
1790 namespace xmltooling {
1791
1792     /**
1793      * Template function for cloning a sequence of XMLObjects.
1794      * Invokes the clone() member on each element of the input sequence and adds the copy to
1795      * the output sequence. Order is preserved.
1796      *
1797      * @param in    input sequence to clone
1798      * @param out   output sequence to copy cloned pointers into
1799      */
1800     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
1801         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
1802             if (*i)
1803                 out.push_back((*i)->clone());
1804             else
1805                 out.push_back(*i);
1806         }
1807     }
1808
1809     /**
1810      * Functor for cleaning up heap objects in containers.
1811      */
1812     template<class T> struct cleanup
1813     {
1814         /**
1815          * Function operator to delete an object.
1816          *
1817          * @param ptr   object to delete
1818          */
1819         void operator()(T* ptr) {delete ptr;}
1820
1821         /**
1822          * Function operator to delete an object stored as const.
1823          *
1824          * @param ptr   object to delete after casting away const
1825          */
1826         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
1827     };
1828
1829     /**
1830      * Functor for cleaning up heap objects in key/value containers.
1831      */
1832     template<class A,class B> struct cleanup_pair
1833     {
1834         /**
1835          * Function operator to delete an object.
1836          *
1837          * @param p   a pair in which the second component is the object to delete
1838          */
1839         void operator()(const std::pair<const A,B*>& p) {delete p.second;}
1840     };
1841
1842     /**
1843      * Functor for cleaning up const heap objects in key/value containers.
1844      */
1845     template<class A,class B> struct cleanup_const_pair
1846     {
1847         /**
1848          * Function operator to delete an object stored as const
1849          *
1850          * @param p   a pair in which the second component is the const object to delete
1851          */
1852         void operator()(const std::pair<const A,const B*>& p) {delete const_cast<B*>(p.second);}
1853     };
1854 };
1855
1856 #endif /* __xmltooling_base_h__ */