Add cache file type to path resolver
[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                 std::string buf(boost::lexical_cast<std::string>(proper)); \
702                 xmltooling::auto_ptr_XMLCh widen(buf.c_str()); \
703                 set##proper(widen.get()); \
704             } \
705             catch (boost::bad_lexical_cast&) { \
706             } \
707         }
708
709 /**
710  * Implements get/set methods and a private member for a boolean XML attribute.
711  *
712  * @param proper    the proper name of the attribute
713  */
714 #define IMPL_BOOLEAN_ATTRIB(proper) \
715     protected: \
716         xmlconstants::xmltooling_bool_t m_##proper; \
717     public: \
718         xmlconstants::xmltooling_bool_t get##proper() const { \
719             return m_##proper; \
720         } \
721         void proper(xmlconstants::xmltooling_bool_t value) { \
722             if (m_##proper != value) { \
723                 releaseThisandParentDOM(); \
724                 m_##proper = value; \
725             } \
726         }
727
728 /**
729  * Implements get/set methods and a private member for a typed, qualified XML attribute.
730  *
731  * @param proper    the proper name of the attribute
732  * @param type      the attribute's data type
733  */
734 #define IMPL_XMLOBJECT_FOREIGN_ATTRIB(proper,type) \
735     protected: \
736     XMLCh* m_##proper##Prefix; \
737         type* m_##proper; \
738     public: \
739         const type* get##proper() const { \
740             return m_##proper; \
741         } \
742         void set##proper(const type* proper) { \
743             m_##proper = prepareForAssignment(m_##proper,proper); \
744             xercesc::XMLString::release(&m_##proper##Prefix); \
745             m_##proper##Prefix = nullptr; \
746         }
747
748 /**
749  * Declares abstract set method for a typed XML child object in a foreign namespace.
750  * The get method is omitted.
751  *
752  * @param proper    the proper name of the child type
753  * @param ns        the C++ namespace for the type
754  */
755 #define DECL_INHERITED_TYPED_FOREIGN_CHILD(proper,ns) \
756     public: \
757         XMLTOOLING_DOXYGEN(Sets the proper child.) \
758         virtual void set##proper(ns::proper* child)=0
759
760 /**
761  * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
762  *
763  * @param proper    the proper name of the child type
764  * @param ns        the C++ namespace for the type
765  */
766 #define DECL_TYPED_FOREIGN_CHILD(proper,ns) \
767     public: \
768         XMLTOOLING_DOXYGEN(Returns the proper child.) \
769         virtual ns::proper* get##proper() const=0; \
770         XMLTOOLING_DOXYGEN(Sets the proper child.) \
771         virtual void set##proper(ns::proper* child)=0
772
773 /**
774  * Declares abstract set method for a typed XML child object.
775  * The get method is omitted.
776  *
777  * @param proper    the proper name of the child type
778  */
779 #define DECL_INHERITED_TYPED_CHILD(proper) \
780     public: \
781         XMLTOOLING_DOXYGEN(Sets the proper child.) \
782         virtual void set##proper(proper* child)=0
783
784 /**
785  * Declares abstract get/set methods for a typed XML child object.
786  *
787  * @param proper    the proper name of the child type
788  */
789 #define DECL_TYPED_CHILD(proper) \
790     public: \
791         XMLTOOLING_DOXYGEN(Returns the proper child.) \
792         virtual proper* get##proper() const=0; \
793         XMLTOOLING_DOXYGEN(Sets the proper child.) \
794         virtual void set##proper(proper* child)=0
795
796 /**
797  * Declares abstract get/set methods for a generic XML child object.
798  *
799  * @param proper    the proper name of the child
800  */
801 #define DECL_XMLOBJECT_CHILD(proper) \
802     public: \
803         XMLTOOLING_DOXYGEN(Returns the proper child.) \
804         virtual xmltooling::XMLObject* get##proper() const=0; \
805         XMLTOOLING_DOXYGEN(Sets the proper child.) \
806         virtual void set##proper(xmltooling::XMLObject* child)=0
807
808
809 /**
810  * Implements get/set methods and a private list iterator member for a typed XML child object.
811  *
812  * @param proper    the proper name of the child type
813  */
814 #define IMPL_TYPED_CHILD(proper) \
815     protected: \
816         proper* m_##proper; \
817         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
818     public: \
819         proper* get##proper() const { \
820             return m_##proper; \
821         } \
822         void set##proper(proper* child) { \
823             prepareForAssignment(m_##proper,child); \
824             *m_pos_##proper = m_##proper = child; \
825         }
826
827 /**
828  * Implements get/set methods and a private list iterator member for
829  * a typed XML child object in a foreign namespace
830  *
831  * @param proper    the proper name of the child type
832  * @param ns        the C++ namespace for the type
833  */
834 #define IMPL_TYPED_FOREIGN_CHILD(proper,ns) \
835     protected: \
836         ns::proper* m_##proper; \
837         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
838     public: \
839         ns::proper* get##proper() const { \
840             return m_##proper; \
841         } \
842         void set##proper(ns::proper* child) { \
843             prepareForAssignment(m_##proper,child); \
844             *m_pos_##proper = m_##proper = child; \
845         }
846
847 /**
848  * Implements get/set methods and a private list iterator member for a generic XML child object.
849  *
850  * @param proper    the proper name of the child
851  */
852 #define IMPL_XMLOBJECT_CHILD(proper) \
853     protected: \
854         xmltooling::XMLObject* m_##proper; \
855         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
856     public: \
857         xmltooling::XMLObject* get##proper() const { \
858             return m_##proper; \
859         } \
860         void set##proper(xmltooling::XMLObject* child) { \
861             prepareForAssignment(m_##proper,child); \
862             *m_pos_##proper = m_##proper = child; \
863         }
864
865 /**
866  * Declares abstract get/set methods for a typed XML child collection.
867  *
868  * @param proper    the proper name of the child type
869  */
870 #define DECL_TYPED_CHILDREN(proper) \
871     public: \
872         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
873         virtual VectorOf(proper) get##proper##s()=0; \
874         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
875         virtual const std::vector<proper*>& get##proper##s() const=0
876
877 /**
878  * Declares abstract get/set methods for a typed XML child collection in a foreign namespace.
879  *
880  * @param proper    the proper name of the child type
881  * @param ns        the C++ namespace for the type
882  */
883 #define DECL_TYPED_FOREIGN_CHILDREN(proper,ns) \
884     public: \
885         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
886         virtual VectorOf(ns::proper) get##proper##s()=0; \
887         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
888         virtual const std::vector<ns::proper*>& get##proper##s() const=0
889
890 /**
891  * Declares abstract get/set methods for a generic XML child collection.
892  *
893  * @param proper    the proper name of the child
894  */
895 #define DECL_XMLOBJECT_CHILDREN(proper) \
896     public: \
897         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
898         virtual VectorOf(xmltooling::XMLObject) get##proper##s()=0; \
899         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
900         virtual const std::vector<xmltooling::XMLObject*>& get##proper##s() const=0
901
902 /**
903  * Implements get method and a private vector member for a typed XML child collection.
904  *
905  * @param proper    the proper name of the child type
906  * @param fence     insertion fence for new objects of the child collection in backing list
907  */
908 #define IMPL_TYPED_CHILDREN(proper,fence) \
909     protected: \
910         std::vector<proper*> m_##proper##s; \
911     public: \
912         VectorOf(proper) get##proper##s() { \
913             return VectorOf(proper)(this, m_##proper##s, &m_children, fence); \
914         } \
915         const std::vector<proper*>& get##proper##s() const { \
916             return m_##proper##s; \
917         }
918
919 /**
920  * Implements get method and a private vector member for a typed XML child collection
921  * in a foreign namespace.
922  *
923  * @param proper    the proper name of the child type
924  * @param ns        the C++ namespace for the type
925  * @param fence     insertion fence for new objects of the child collection in backing list
926  */
927 #define IMPL_TYPED_FOREIGN_CHILDREN(proper,ns,fence) \
928     protected: \
929         std::vector<ns::proper*> m_##proper##s; \
930     public: \
931         VectorOf(ns::proper) get##proper##s() { \
932             return VectorOf(ns::proper)(this, m_##proper##s, &m_children, fence); \
933         } \
934         const std::vector<ns::proper*>& get##proper##s() const { \
935             return m_##proper##s; \
936         }
937
938 /**
939  * Implements get method and a private vector member for a generic XML child collection.
940  *
941  * @param proper    the proper name of the child
942  * @param fence     insertion fence for new objects of the child collection in backing list
943  */
944 #define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
945     protected: \
946         std::vector<xmltooling::XMLObject*> m_##proper##s; \
947     public: \
948         VectorOf(xmltooling::XMLObject) get##proper##s() { \
949             return VectorOf(xmltooling::XMLObject)(this, m_##proper##s, &m_children, fence); \
950         } \
951         const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
952             return m_##proper##s; \
953         }
954
955 /**
956  * Implements marshalling for a string attribute
957  *
958  * @param proper        the proper name of the attribute
959  * @param ucase         the upcased name of the attribute
960  * @param namespaceURI  the XML namespace of the attribute
961  */
962 #define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
963     if (m_##proper && *m_##proper) { \
964         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
965     }
966
967 /**
968  * Implements marshalling for a DateTime attribute
969  *
970  * @param proper        the proper name of the attribute
971  * @param ucase         the upcased name of the attribute
972  * @param namespaceURI  the XML namespace of the attribute
973  */
974 #define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
975     if (m_##proper) { \
976         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper->getRawData()); \
977     }
978
979 /**
980  * Implements marshalling for an integer attribute
981  *
982  * @param proper        the proper name of the attribute
983  * @param ucase         the upcased name of the attribute
984  * @param namespaceURI  the XML namespace of the attribute
985  */
986 #define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
987     if (m_##proper && *m_##proper) { \
988         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
989     }
990
991 /**
992  * Implements marshalling for a boolean attribute
993  *
994  * @param proper        the proper name of the attribute
995  * @param ucase         the upcased name of the attribute
996  * @param namespaceURI  the XML namespace of the attribute
997  */
998 #define MARSHALL_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
999     switch (m_##proper) { \
1000         case xmlconstants::XML_BOOL_TRUE: \
1001             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_TRUE); \
1002             break; \
1003         case xmlconstants::XML_BOOL_ONE: \
1004             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ONE); \
1005             break; \
1006         case xmlconstants::XML_BOOL_FALSE: \
1007             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_FALSE); \
1008             break; \
1009         case xmlconstants::XML_BOOL_ZERO: \
1010             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ZERO); \
1011             break; \
1012         case xmlconstants::XML_BOOL_NULL: \
1013             break; \
1014     }
1015
1016 /**
1017  * Implements marshalling for a QName attribute
1018  *
1019  * @param proper        the proper name of the attribute
1020  * @param ucase         the upcased name of the attribute
1021  * @param namespaceURI  the XML namespace of the attribute
1022  */
1023 #define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
1024     if (m_##proper) { \
1025         xmltooling::auto_ptr_XMLCh qstr(m_##proper->toString().c_str()); \
1026         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
1027     }
1028
1029 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
1030 /**
1031  * Implements marshalling for an ID attribute
1032  *
1033  * @param proper        the proper name of the attribute
1034  * @param ucase         the upcased name of the attribute
1035  * @param namespaceURI  the XML namespace of the attribute
1036  */
1037 # define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
1038     if (m_##proper && *m_##proper) { \
1039         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
1040         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, true); \
1041     }
1042 #else
1043 /**
1044  * Implements marshalling for an ID attribute
1045  *
1046  * @param proper        the proper name of the attribute
1047  * @param ucase         the upcased name of the attribute
1048  * @param namespaceURI  the XML namespace of the attribute
1049  */
1050 # define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
1051     if (m_##proper && *m_##proper) { \
1052         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
1053         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
1054     }
1055 #endif
1056
1057 /**
1058  * Implements unmarshalling process branch for a string attribute
1059  *
1060  * @param proper        the proper name of the attribute
1061  * @param ucase         the upcased name of the attribute
1062  * @param namespaceURI  the XML namespace of the attribute
1063  */
1064 #define PROC_STRING_ATTRIB(proper,ucase,namespaceURI) \
1065     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1066         set##proper(attribute->getValue()); \
1067         return; \
1068     }
1069
1070 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
1071 /**
1072  * Implements unmarshalling process branch for an ID attribute
1073  *
1074  * @param proper        the proper name of the attribute
1075  * @param ucase         the upcased name of the attribute
1076  * @param namespaceURI  the XML namespace of the attribute
1077  */
1078 # define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
1079     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1080         set##proper(attribute->getValue()); \
1081         attribute->getOwnerElement()->setIdAttributeNode(attribute, true); \
1082         return; \
1083     }
1084 #else
1085 /**
1086  * Implements unmarshalling process branch for an ID attribute
1087  *
1088  * @param proper        the proper name of the attribute
1089  * @param ucase         the upcased name of the attribute
1090  * @param namespaceURI  the XML namespace of the attribute
1091  */
1092 # define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
1093     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1094         set##proper(attribute->getValue()); \
1095         attribute->getOwnerElement()->setIdAttributeNode(attribute); \
1096         return; \
1097     }
1098 #endif
1099
1100 /**
1101  * Implements unmarshalling process branch for a DateTime attribute
1102  *
1103  * @param proper        the proper name of the attribute
1104  * @param ucase         the upcased name of the attribute
1105  * @param namespaceURI  the XML namespace of the attribute
1106  */
1107 #define PROC_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
1108     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1109
1110 /**
1111  * Implements unmarshalling process branch for a DateTime attribute
1112  *
1113  * @param proper        the proper name of the attribute
1114  * @param ucase         the upcased name of the attribute
1115  * @param namespaceURI  the XML namespace of the attribute
1116  */
1117 #define PROC_QNAME_ATTRIB(proper,ucase,namespaceURI) \
1118     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1119         std::auto_ptr<xmltooling::QName> q(xmltooling::XMLHelper::getAttributeValueAsQName(attribute)); \
1120         set##proper(q.get()); \
1121         return; \
1122     }
1123
1124 /**
1125  * Implements unmarshalling process branch for an integer attribute
1126  *
1127  * @param proper        the proper name of the attribute
1128  * @param ucase         the upcased name of the attribute
1129  * @param namespaceURI  the XML namespace of the attribute
1130  */
1131 #define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
1132     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1133
1134 /**
1135  * Implements unmarshalling process branch for a boolean attribute
1136  *
1137  * @param proper        the proper name of the attribute
1138  * @param ucase         the upcased name of the attribute
1139  * @param namespaceURI  the XML namespace of the attribute
1140  */
1141 #define PROC_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
1142     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1143
1144 /**
1145  * Implements unmarshalling process branch for typed child collection element
1146  *
1147  * @param proper        the proper name of the child type
1148  * @param namespaceURI  the XML namespace of the child element
1149  * @param force         bypass use of hint and just cast down to check child
1150  */
1151 #define PROC_TYPED_CHILDREN(proper,namespaceURI,force) \
1152     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1153         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
1154         if (typesafe) { \
1155             get##proper##s().push_back(typesafe); \
1156             return; \
1157         } \
1158     }
1159
1160 /**
1161  * Implements unmarshalling process branch for typed child collection element
1162  * in a foreign namespace.
1163  *
1164  * @param proper        the proper name of the child type
1165  * @param ns            the C++ namespace for the type
1166  * @param namespaceURI  the XML namespace of the child element
1167  * @param force         bypass use of hint and just cast down to check child
1168  */
1169 #define PROC_TYPED_FOREIGN_CHILDREN(proper,ns,namespaceURI,force) \
1170     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1171         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1172         if (typesafe) { \
1173             get##proper##s().push_back(typesafe); \
1174             return; \
1175         } \
1176     }
1177
1178 /**
1179  * Implements unmarshalling process branch for typed child singleton element
1180  *
1181  * @param proper        the proper name of the child type
1182  * @param namespaceURI  the XML namespace of the child element
1183  * @param force         bypass use of hint and just cast down to check child
1184  */
1185 #define PROC_TYPED_CHILD(proper,namespaceURI,force) \
1186     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1187         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
1188         if (typesafe && !m_##proper) { \
1189             typesafe->setParent(this); \
1190             *m_pos_##proper = m_##proper = typesafe; \
1191             return; \
1192         } \
1193     }
1194
1195 /**
1196  * Implements unmarshalling process branch for typed child singleton element
1197  * in a foreign namespace.
1198  *
1199  * @param proper        the proper name of the child type
1200  * @param ns            the C++ namespace for the type
1201  * @param namespaceURI  the XML namespace of the child element
1202  * @param force         bypass use of hint and just cast down to check child
1203  */
1204 #define PROC_TYPED_FOREIGN_CHILD(proper,ns,namespaceURI,force) \
1205     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1206         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1207         if (typesafe && !m_##proper) { \
1208             typesafe->setParent(this); \
1209             *m_pos_##proper = m_##proper = typesafe; \
1210             return; \
1211         } \
1212     }
1213
1214 /**
1215  * Implements unmarshalling process branch for a generic child singleton element
1216  *
1217  * @param proper        the proper name of the child type
1218  * @param namespaceURI  the XML namespace of the child element
1219  */
1220 #define PROC_XMLOBJECT_CHILD(proper,namespaceURI) \
1221     if (xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1222         if (!m_##proper) { \
1223             childXMLObject->setParent(this); \
1224             *m_pos_##proper = m_##proper = childXMLObject; \
1225             return; \
1226         } \
1227     }
1228
1229 /**
1230  * Declares aliased get/set methods for named XML element simple content.
1231  *
1232  * @param proper    the proper name to label the element's content
1233  */
1234 #define DECL_SIMPLE_CONTENT(proper) \
1235     XMLTOOLING_DOXYGEN(Returns proper.) \
1236     const XMLCh* get##proper() const { \
1237         return getTextContent(); \
1238     } \
1239     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1240     void set##proper(const XMLCh* proper) { \
1241         setTextContent(proper); \
1242     }
1243
1244 /**
1245  * Declares aliased get/set methods for named integer XML element content.
1246  *
1247  * @param proper    the proper name to label the element's content
1248  */
1249 #define DECL_INTEGER_CONTENT(proper) \
1250     XMLTOOLING_DOXYGEN(Returns proper in integer form after a NULL indicator.) \
1251     std::pair<bool,int> get##proper() const { \
1252         return std::make_pair((getTextContent()!=nullptr), (getTextContent()!=nullptr ? xercesc::XMLString::parseInt(getTextContent()) : 0)); \
1253     } \
1254     XMLTOOLING_DOXYGEN(Sets proper.) \
1255     void set##proper(int proper) { \
1256         try { \
1257             std::string buf(boost::lexical_cast<std::string>(proper)); \
1258             xmltooling::auto_ptr_XMLCh widen(buf.c_str()); \
1259             setTextContent(widen.get()); \
1260         } \
1261         catch (boost::bad_lexical_cast&) { \
1262         } \
1263     } \
1264     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1265     void set##proper(const XMLCh* proper) { \
1266         setTextContent(proper); \
1267     }
1268
1269 /**
1270  * Implements cloning methods for an XMLObject specialization implementation class.
1271  *
1272  * @param cname the name of the XMLObject specialization
1273  */
1274 #define IMPL_XMLOBJECT_CLONE(cname) \
1275     cname* clone##cname() const { \
1276         return dynamic_cast<cname*>(clone()); \
1277     } \
1278     xmltooling::XMLObject* clone() const { \
1279         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1280         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1281         if (ret) { \
1282             domClone.release(); \
1283             return ret; \
1284         } \
1285         return new cname##Impl(*this); \
1286     }
1287
1288 /**
1289  * Implements cloning methods for an XMLObject specialization implementation class
1290  * that must override a base class clone method.
1291  *
1292  * @param cname the name of the XMLObject specialization
1293  * @param base  name of base type.
1294  */
1295 #define IMPL_XMLOBJECT_CLONE2(cname,base) \
1296     cname* clone##cname() const { \
1297         return dynamic_cast<cname*>(clone()); \
1298     } \
1299     base* clone##base() const { \
1300         return dynamic_cast<base*>(clone()); \
1301     } \
1302     xmltooling::XMLObject* clone() const { \
1303         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1304         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1305         if (ret) { \
1306             domClone.release(); \
1307             return ret; \
1308         } \
1309         return new cname##Impl(*this); \
1310     }
1311
1312 /**
1313  * Implements cloning methods for an XMLObject specialization implementation class that
1314  * needs two stage duplication to avoid invoking virtual methods during construction.
1315  *
1316  * @param cname the name of the XMLObject specialization
1317  */
1318 #define IMPL_XMLOBJECT_CLONE_EX(cname) \
1319     cname* clone##cname() const { \
1320         return dynamic_cast<cname*>(clone()); \
1321     } \
1322     xmltooling::XMLObject* clone() const { \
1323         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1324         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1325         if (ret) { \
1326             domClone.release(); \
1327             return ret; \
1328         } \
1329         std::auto_ptr<cname##Impl> ret2(new cname##Impl(*this)); \
1330         ret2->_clone(*this); \
1331         return ret2.release(); \
1332     }
1333
1334 /**
1335  * Implements cloning methods for an XMLObject specialization implementation class that
1336  * needs two stage duplication to avoid invoking virtual methods during construction,
1337  * and must override a base class clone method.
1338  *
1339  * @param cname the name of the XMLObject specialization
1340  * @param base  name of base type
1341  */
1342 #define IMPL_XMLOBJECT_CLONE_EX2(cname,base) \
1343     cname* clone##cname() const { \
1344         return dynamic_cast<cname*>(clone()); \
1345     } \
1346     base* clone##base() const { \
1347         return dynamic_cast<base*>(clone()); \
1348     } \
1349     xmltooling::XMLObject* clone() const { \
1350         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1351         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1352         if (ret) { \
1353             domClone.release(); \
1354             return ret; \
1355         } \
1356         std::auto_ptr<cname##Impl> ret2(new cname##Impl(*this)); \
1357         ret2->_clone(*this); \
1358         return ret2.release(); \
1359     }
1360
1361 /**
1362  * Implements cloning of a child attribute, for use in copy constructor or
1363  * deferred clone methods.
1364  *
1365  * proper   the proper name of the attribute to clone
1366  */
1367 #define IMPL_CLONE_ATTRIB(proper) \
1368     set##proper(src.get##proper())
1369
1370 /**
1371  * Implements cloning of a child attribute in a foreign namespace, for use in copy constructor or
1372  * deferred clone methods.
1373  *
1374  * proper   the proper name of the attribute to clone
1375  */
1376 #define IMPL_CLONE_FOREIGN_ATTRIB(proper) \
1377     set##proper(src.get##proper()); \
1378     if (src.m_##proper##Prefix) \
1379         m_##proper##Prefix = xercesc::XMLString::replicate(src.m_##proper##Prefix)
1380
1381 /**
1382  * Implements cloning of an integer child attribute, for use in copy constructor or
1383  * deferred clone methods.
1384  *
1385  * proper   the proper name of the attribute to clone
1386  */
1387 #define IMPL_CLONE_INTEGER_ATTRIB(proper) \
1388     set##proper(src.m_##proper)
1389
1390 /**
1391  * Implements cloning of a boolean child attribute, for use in copy constructor or
1392  * deferred clone methods.
1393  *
1394  * proper   the proper name of the attribute to clone
1395  */
1396 #define IMPL_CLONE_BOOLEAN_ATTRIB(proper) \
1397     proper(src.m_##proper)
1398
1399 /**
1400  * Implements cloning of a child object, for use in copy constructor or
1401  * deferred clone methods.
1402  *
1403  * proper   the proper name of the child object to clone
1404  */
1405 #define IMPL_CLONE_XMLOBJECT_CHILD(proper) \
1406     if (src.get##proper()) \
1407         set##proper(src.get##proper()->clone())
1408
1409 /**
1410  * Implements cloning of a typed child object, for use in copy constructor or
1411  * deferred clone methods.
1412  *
1413  * proper   the proper name of the child type to clone
1414  */
1415 #define IMPL_CLONE_TYPED_CHILD(proper) \
1416     if (src.get##proper()) \
1417         set##proper(src.get##proper()->clone##proper())
1418
1419 /**
1420  * Implements cloning of an untyped child collection, for use in copy constructor or
1421  * deferred clone methods.
1422  *
1423  * proper   the proper name of the child type to clone
1424  */
1425 #define IMPL_CLONE_XMLOBJECT_CHILDREN(proper) \
1426     static void (VectorOf(XMLObject)::* XMLObject_push_back)(XMLObject* const&) = &VectorOf(XMLObject)::push_back; \
1427     VectorOf(XMLObject) c##proper = get##proper##s(); \
1428     std::for_each( \
1429         src.m_##proper##s.begin(), src.m_##proper##s.end(), \
1430         boost::lambda::if_(boost::lambda::_1 != ((XMLObject*)nullptr)) \
1431             [boost::lambda::bind(XMLObject_push_back, boost::ref(c##proper), boost::lambda::bind(&XMLObject::clone, boost::lambda::_1))] \
1432         )
1433
1434 /**
1435  * Implements cloning of a child collection, for use in copy constructor or
1436  * deferred clone methods.
1437  *
1438  * proper   the proper name of the child type to clone
1439  */
1440 #define IMPL_CLONE_TYPED_CHILDREN(proper) \
1441     static void (VectorOf(proper)::* proper##_push_back)(proper* const&) = &VectorOf(proper)::push_back; \
1442     VectorOf(proper) c##proper = get##proper##s(); \
1443     std::for_each( \
1444         src.m_##proper##s.begin(), src.m_##proper##s.end(), \
1445         boost::lambda::if_(boost::lambda::_1 != ((proper*)nullptr)) \
1446             [boost::lambda::bind(proper##_push_back, boost::ref(c##proper), boost::lambda::bind(&proper::clone##proper, boost::lambda::_1))] \
1447         )
1448
1449 /**
1450  * Implements cloning of a child collection in a foreign namespace, for use in copy constructor or
1451  * deferred clone methods.
1452  *
1453  * proper   the proper name of the child type to clone
1454  * ns       the namespace of the child type
1455  */
1456 #define IMPL_CLONE_TYPED_FOREIGN_CHILDREN(proper,ns) \
1457     static void (VectorOf(ns::proper)::* proper##_push_back)(ns::proper* const&) = &VectorOf(ns::proper)::push_back; \
1458     VectorOf(ns::proper) c##proper = get##proper##s(); \
1459     std::for_each( \
1460         src.m_##proper##s.begin(), src.m_##proper##s.end(), \
1461         boost::lambda::if_(boost::lambda::_1 != ((ns::proper*)nullptr)) \
1462             [boost::lambda::bind(proper##_push_back, boost::ref(c##proper), boost::lambda::bind(&ns::proper::clone##proper, boost::lambda::_1))] \
1463         )
1464
1465 /**
1466  * Opens an iteration loop over all of the children of an object.
1467  */
1468 #define IMPL_CLONE_CHILDBAG_BEGIN \
1469     for (list<xmltooling::XMLObject*>::const_iterator _bagit = src.m_children.begin(); _bagit != src.m_children.end(); ++_bagit) {
1470
1471 /**
1472  * Closes an iteration loop over all of the children of an object.
1473  */
1474 #define IMPL_CLONE_CHILDBAG_END }
1475
1476 /**
1477  * Implements cloning of a typed child in a bag iteration loop based on a cast check.
1478  *
1479  * @param proper    the proper name of the child type to clone
1480  */
1481 #define IMPL_CLONE_TYPED_CHILD_IN_BAG(proper) \
1482     proper* _##proper##cast = dynamic_cast<proper*>(*_bagit); \
1483     if (_##proper##cast) { \
1484         get##proper##s().push_back(_##proper##cast->clone##proper()); \
1485         continue; \
1486     }
1487
1488 /**
1489  * Implements cloning of a typed child in a forign namespace in a bag iteration loop based on a cast check.
1490  *
1491  * @param proper    the proper name of the child type to clone
1492  * @param ns        the namespace of the child type
1493  */
1494 #define IMPL_CLONE_TYPED_FOREIGN_CHILD_IN_BAG(proper,ns) \
1495     ns::proper* _##proper##cast = dynamic_cast<ns::proper*>(*_bagit); \
1496     if (_##proper##cast) { \
1497         get##proper##s().push_back(_##proper##cast->clone##proper()); \
1498         continue; \
1499     }
1500
1501 /**
1502  * Implements cloning of an XMLObject child in a bag iteration loop.
1503  *
1504  * @param proper    the proper name of the child to clone
1505  */
1506 #define IMPL_CLONE_XMLOBJECT_CHILD_IN_BAG(proper) \
1507     if (*_bagit) { \
1508         get##proper##s().push_back((*_bagit)->clone()); \
1509     }
1510
1511 /**
1512  * Declares an XMLObject specialization with a simple content model and type,
1513  * handling it as string data.
1514  *
1515  * @param linkage   linkage specifier for the class
1516  * @param cname     the name of the XMLObject specialization
1517  * @param proper    the proper name to label the element's content
1518  * @param desc      documentation for class
1519  */
1520 #define DECL_XMLOBJECT_SIMPLE(linkage,cname,proper,desc) \
1521     BEGIN_XMLOBJECT(linkage,cname,xmltooling::XMLObject,desc); \
1522         DECL_SIMPLE_CONTENT(proper); \
1523     END_XMLOBJECT
1524
1525 /**
1526  * Declares and defines an implementation class for an XMLObject with
1527  * a simple content model and type, handling it as string data.
1528  *
1529  * @param linkage   linkage specifier for the class
1530  * @param cname     the name of the XMLObject specialization
1531  */
1532 #define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
1533     class linkage cname##Impl \
1534         : public virtual cname, \
1535             public xmltooling::AbstractSimpleElement, \
1536             public xmltooling::AbstractDOMCachingXMLObject, \
1537             public xmltooling::AbstractXMLObjectMarshaller, \
1538             public xmltooling::AbstractXMLObjectUnmarshaller \
1539     { \
1540     public: \
1541         virtual ~cname##Impl() {} \
1542         cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType) \
1543             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
1544         } \
1545         cname##Impl(const cname##Impl& src) \
1546             : xmltooling::AbstractXMLObject(src), \
1547                 xmltooling::AbstractSimpleElement(src), \
1548                 xmltooling::AbstractDOMCachingXMLObject(src) {} \
1549         IMPL_XMLOBJECT_CLONE(cname) \
1550     }
1551
1552 #ifdef HAVE_COVARIANT_RETURNS
1553
1554 /**
1555  * Begins the declaration of an XMLObjectBuilder specialization.
1556  * Basic boilerplate includes an empty virtual destructor, and
1557  * a default builder that defaults the element name.
1558  *
1559  * @param linkage           linkage specifier for the class
1560  * @param cname             the name of the XMLObject specialization
1561  * @param namespaceURI      the XML namespace of the default associated element
1562  * @param namespacePrefix   the XML namespace prefix of the default associated element
1563  */
1564 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1565     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1566     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1567     public: \
1568         virtual ~cname##Builder() {} \
1569         XMLTOOLING_DOXYGEN(Default builder.) \
1570         virtual cname* buildObject() const { \
1571             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1572         } \
1573         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1574         virtual cname* buildObject( \
1575             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1576             ) const
1577
1578 /**
1579  * Ends the declaration of an XMLObjectBuilder specialization.
1580  */
1581 #define END_XMLOBJECTBUILDER }
1582
1583 /**
1584  * Declares a generic XMLObjectBuilder specialization.
1585  *
1586  * @param linkage           linkage specifier for the class
1587  * @param cname             the name of the XMLObject specialization
1588  * @param namespaceURI      the XML namespace of the default associated element
1589  * @param namespacePrefix   the XML namespace prefix of the default associated element
1590  */
1591  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1592     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1593     XMLTOOLING_DOXYGEN(Singleton builder.) \
1594     static cname* build##cname() { \
1595         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1596             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1597             ); \
1598         if (b) \
1599             return b->buildObject(); \
1600         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1601     } \
1602     END_XMLOBJECTBUILDER
1603
1604 /**
1605  * Implements the standard XMLObjectBuilder specialization function.
1606  *
1607  * @param cname the name of the XMLObject specialization
1608  */
1609 #define IMPL_XMLOBJECTBUILDER(cname) \
1610     cname* cname##Builder::buildObject( \
1611         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1612         ) const \
1613     { \
1614         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1615     }
1616
1617 #else   /* !HAVE_COVARIANT_RETURNS */
1618
1619 /**
1620  * Begins the declaration of an XMLObjectBuilder specialization.
1621  * Basic boilerplate includes an empty virtual destructor, and
1622  * a default builder that defaults the element name.
1623  *
1624  * @param linkage           linkage specifier for the class
1625  * @param cname             the name of the XMLObject specialization
1626  * @param namespaceURI      the XML namespace of the default associated element
1627  * @param namespacePrefix   the XML namespace prefix of the default associated element
1628  */
1629 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1630     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1631     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1632     public: \
1633         virtual ~cname##Builder() {} \
1634         XMLTOOLING_DOXYGEN(Default builder.) \
1635         virtual xmltooling::XMLObject* buildObject() const { \
1636             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1637         } \
1638         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1639         virtual xmltooling::XMLObject* buildObject( \
1640             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1641             ) const
1642
1643 /**
1644  * Ends the declaration of an XMLObjectBuilder specialization.
1645  */
1646 #define END_XMLOBJECTBUILDER }
1647
1648 /**
1649  * Declares a generic XMLObjectBuilder specialization.
1650  *
1651  * @param linkage           linkage specifier for the class
1652  * @param cname             the name of the XMLObject specialization
1653  * @param namespaceURI      the XML namespace of the default associated element
1654  * @param namespacePrefix   the XML namespace prefix of the default associated element
1655  */
1656  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1657     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1658     XMLTOOLING_DOXYGEN(Singleton builder.) \
1659     static cname* build##cname() { \
1660         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1661             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1662             ); \
1663         if (b) \
1664             return dynamic_cast<cname*>(b->buildObject()); \
1665         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1666     } \
1667     END_XMLOBJECTBUILDER
1668
1669 /**
1670  * Implements the standard XMLObjectBuilder specialization function.
1671  *
1672  * @param cname the name of the XMLObject specialization
1673  */
1674 #define IMPL_XMLOBJECTBUILDER(cname) \
1675     xmltooling::XMLObject* cname##Builder::buildObject( \
1676         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1677         ) const \
1678     { \
1679         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1680     }
1681
1682 #endif  /* HAVE_COVARIANT_RETURNS */
1683
1684 /**
1685  * Begins the declaration of a Schema Validator specialization.
1686  *
1687  * @param linkage           linkage specifier for the class
1688  * @param cname the base name of the Validator specialization
1689  */
1690  #define BEGIN_XMLOBJECTVALIDATOR(linkage,cname) \
1691     class linkage cname##SchemaValidator : public xmltooling::Validator \
1692     { \
1693     public: \
1694         virtual ~cname##SchemaValidator() {} \
1695         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1696             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1697             if (!ptr) \
1698                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name())); \
1699             if (ptr->nil() && (ptr->hasChildren() || ptr->getTextContent())) \
1700                 throw xmltooling::ValidationException("Object has nil property but with children or content.")
1701
1702 /**
1703  * Begins the declaration of a Schema Validator specialization subclass.
1704  *
1705  * @param linkage   linkage specifier for the class
1706  * @param cname     the base name of the Validator specialization
1707  * @param base      base class for the validator
1708  */
1709  #define BEGIN_XMLOBJECTVALIDATOR_SUB(linkage,cname,base) \
1710     class linkage cname##SchemaValidator : public base##SchemaValidator \
1711     { \
1712     public: \
1713         virtual ~cname##SchemaValidator() {} \
1714         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1715             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1716             if (!ptr) \
1717                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()));
1718
1719 /**
1720  * Ends the declaration of a Validator specialization.
1721  */
1722 #define END_XMLOBJECTVALIDATOR } }
1723
1724 /**
1725  * Validator code that checks the object type.
1726  *
1727  * @param cname     the name of the XMLObject specialization
1728  */
1729 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
1730     const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1731     if (!ptr) \
1732         throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1733
1734 /**
1735  * Validator code that checks for a required attribute, content, or singleton.
1736  *
1737  * @param cname     the name of the XMLObject specialization
1738  * @param proper    the proper name of the attribute, content, or singleton member
1739  */
1740 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
1741     if (!ptr->get##proper()) \
1742         throw xmltooling::ValidationException(#cname" must have "#proper".")
1743
1744 /**
1745  * Validator code that checks for a required integer attribute
1746  *
1747  * @param cname     the name of the XMLObject specialization
1748  * @param proper    the proper name of the attribute, content, or singleton member
1749  */
1750 #define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
1751     if (!ptr->get##proper().first) \
1752         throw xmltooling::ValidationException(#cname" must have "#proper".")
1753
1754 /**
1755  * Validator code that checks for one of a pair of
1756  * required attributes, content, or singletons.
1757  *
1758  * @param cname     the name of the XMLObject specialization
1759  * @param proper1   the proper name of the first attribute, content, or singleton member
1760  * @param proper2   the proper name of the second attribute, content, or singleton member
1761  */
1762 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
1763     if (!ptr->get##proper1() && !ptr->get##proper2()) \
1764         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
1765
1766 /**
1767  * Validator code that checks for one of a pair of
1768  * required attributes, content, or singletons, but disallows both.
1769  *
1770  * @param cname     the name of the XMLObject specialization
1771  * @param proper1   the proper name of the first attribute, content, or singleton member
1772  * @param proper2   the proper name of the second attribute, content, or singleton member
1773  */
1774 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
1775     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
1776         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
1777
1778 /**
1779  * Validator code that checks for one of a set of three
1780  * required attributes, content, or singletons.
1781  *
1782  * @param cname     the name of the XMLObject specialization
1783  * @param proper1   the proper name of the first attribute, content, or singleton member
1784  * @param proper2   the proper name of the second attribute, content, or singleton member
1785  * @param proper3   the proper name of the third attribute, content, or singleton member
1786  */
1787 #define XMLOBJECTVALIDATOR_ONEOF3(cname,proper1,proper2,proper3) \
1788     if (!ptr->get##proper1() && !ptr->get##proper2() && !ptr->get##proper3()) \
1789         throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
1790
1791 /**
1792  * Validator code that checks for one of a set of three
1793  * required attributes, content, or singletons but disallows more than one.
1794  *
1795  * @param cname     the name of the XMLObject specialization
1796  * @param proper1   the proper name of the first attribute, content, or singleton member
1797  * @param proper2   the proper name of the second attribute, content, or singleton member
1798  * @param proper3   the proper name of the third attribute, content, or singleton member
1799  */
1800 #define XMLOBJECTVALIDATOR_ONLYONEOF3(cname,proper1,proper2,proper3) \
1801     int c##proper1##proper2##proper3=0; \
1802     if (ptr->get##proper1()!=nullptr) \
1803         c##proper1##proper2##proper3++; \
1804     if (ptr->get##proper2()!=nullptr) \
1805         c##proper1##proper2##proper3++; \
1806     if (ptr->get##proper3()!=nullptr) \
1807         c##proper1##proper2##proper3++; \
1808     if (c##proper1##proper2##proper3 != 1) \
1809         throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
1810
1811 /**
1812  * Validator code that checks a co-constraint (if one present, the other must be)
1813  * between a pair of attributes, content, or singletons.
1814  *
1815  * @param cname     the name of the XMLObject specialization
1816  * @param proper1   the proper name of the first attribute, content, or singleton member
1817  * @param proper2   the proper name of the second attribute, content, or singleton member
1818  */
1819 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
1820     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
1821         throw xmltooling::ValidationException(#cname" cannot have "#proper1" without "#proper2".")
1822
1823 /**
1824  * Validator code that checks for a non-empty collection.
1825  *
1826  * @param cname     the name of the XMLObject specialization
1827  * @param proper    the proper name of the collection item
1828  */
1829 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
1830     if (ptr->get##proper##s().empty()) \
1831         throw xmltooling::ValidationException(#cname" must have at least one "#proper".")
1832
1833 /**
1834  * Declares/defines a Validator specialization that checks object type and
1835  * a non-empty simple content model.
1836  *
1837  * @param linkage   linkage specifier for the class
1838  * @param cname     the name of the XMLObject specialization
1839  */
1840 #define XMLOBJECTVALIDATOR_SIMPLE(linkage,cname) \
1841     BEGIN_XMLOBJECTVALIDATOR(linkage,cname); \
1842         XMLOBJECTVALIDATOR_REQUIRE(cname,TextContent); \
1843     END_XMLOBJECTVALIDATOR
1844
1845 #include <utility>
1846
1847 /**
1848  * @namespace xmltooling
1849  * Public namespace of XML Tooling library
1850  */
1851 namespace xmltooling {
1852
1853     /**
1854      * Template function for cloning a sequence of XMLObjects.
1855      * Invokes the clone() member on each element of the input sequence and adds the copy to
1856      * the output sequence. Order is preserved.
1857      *
1858      * @param in    input sequence to clone
1859      * @param out   output sequence to copy cloned pointers into
1860      */
1861     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
1862         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
1863             if (*i)
1864                 out.push_back((*i)->clone());
1865             else
1866                 out.push_back(*i);
1867         }
1868     }
1869
1870     /**
1871      * Functor for cleaning up heap objects in containers.
1872      */
1873     template<class T> struct cleanup
1874     {
1875         /**
1876          * Function operator to delete an object.
1877          *
1878          * @param ptr   object to delete
1879          */
1880         void operator()(T* ptr) {delete ptr;}
1881
1882         /**
1883          * Function operator to delete an object stored as const.
1884          *
1885          * @param ptr   object to delete after casting away const
1886          */
1887         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
1888     };
1889
1890     /**
1891      * Functor for cleaning up heap objects in key/value containers.
1892      */
1893     template<class A,class B> struct cleanup_pair
1894     {
1895         /**
1896          * Function operator to delete an object.
1897          *
1898          * @param p   a pair in which the second component is the object to delete
1899          */
1900         void operator()(const std::pair<const A,B*>& p) {delete p.second;}
1901     };
1902
1903     /**
1904      * Functor for cleaning up const heap objects in key/value containers.
1905      */
1906     template<class A,class B> struct cleanup_const_pair
1907     {
1908         /**
1909          * Function operator to delete an object stored as const
1910          *
1911          * @param p   a pair in which the second component is the const object to delete
1912          */
1913         void operator()(const std::pair<const A,const B*>& p) {delete const_cast<B*>(p.second);}
1914     };
1915 };
1916
1917 #endif /* __xmltooling_base_h__ */