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