comparison DEPENDENCIES/generic/include/boost/multiprecision/cpp_int/comparison.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children c530137014c0
comparison
equal deleted inserted replaced
15:663ca0da4350 16:2665513ce2d3
1 ///////////////////////////////////////////////////////////////
2 // Copyright 2012 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
5 //
6 // Comparison operators for cpp_int_backend:
7 //
8 #ifndef BOOST_MP_CPP_INT_COMPARISON_HPP
9 #define BOOST_MP_CPP_INT_COMPARISON_HPP
10
11 #include <boost/type_traits/make_unsigned.hpp>
12
13 namespace boost{ namespace multiprecision{ namespace backends{
14
15 #ifdef BOOST_MSVC
16 #pragma warning(push)
17 #pragma warning(disable:4018 4389 4996)
18 #endif
19
20 //
21 // Start with non-trivial cpp_int's:
22 //
23 template <unsigned MinBits, unsigned MaxBits, cpp_integer_type SignType, cpp_int_check_type Checked, class Allocator>
24 BOOST_MP_FORCEINLINE typename enable_if_c<
25 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value,
26 bool
27 >::type
28 eval_eq(const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& a, const cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& b) BOOST_NOEXCEPT
29 {
30 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
31 return (a.sign() == b.sign())
32 && (a.size() == b.size())
33 && std::equal(a.limbs(), a.limbs() + a.size(),
34 stdext::checked_array_iterator<cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>::const_limb_pointer>(b.limbs(), b.size()));
35 #else
36 return (a.sign() == b.sign())
37 && (a.size() == b.size())
38 && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
39 #endif
40 }
41 template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
42 BOOST_MP_FORCEINLINE typename enable_if_c<
43 !is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
44 && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value,
45 bool
46 >::type
47 eval_eq(const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& a, const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b) BOOST_NOEXCEPT
48 {
49 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
50 return (a.sign() == b.sign())
51 && (a.size() == b.size())
52 && std::equal(a.limbs(), a.limbs() + a.size(), stdext::checked_array_iterator<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>::const_limb_pointer>(b.limbs(), b.size()));
53 #else
54 return (a.sign() == b.sign())
55 && (a.size() == b.size())
56 && std::equal(a.limbs(), a.limbs() + a.size(), b.limbs());
57 #endif
58 }
59 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
60 BOOST_MP_FORCEINLINE typename enable_if_c<
61 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
62 bool
63 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
64 {
65 return (a.sign() == false)
66 && (a.size() == 1)
67 && (*a.limbs() == b);
68 }
69 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
70 BOOST_MP_FORCEINLINE typename enable_if_c<
71 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
72 bool
73 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
74 {
75 BOOST_MP_USING_ABS
76 return (a.sign() == (b < 0))
77 && (a.size() == 1)
78 && (*a.limbs() == static_cast<limb_type>(abs(b)));
79 }
80 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
81 BOOST_MP_FORCEINLINE typename enable_if_c<
82 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
83 bool
84 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
85 {
86 return (a.size() == 1)
87 && (*a.limbs() == b);
88 }
89 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
90 BOOST_MP_FORCEINLINE typename enable_if_c<
91 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
92 bool
93 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
94 {
95 return (b < 0) ? eval_eq(a, cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>(b)) : eval_eq(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
96 }
97
98 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
99 BOOST_MP_FORCEINLINE typename enable_if_c<
100 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
101 bool
102 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
103 {
104 if(a.sign())
105 return true;
106 if(a.size() > 1)
107 return false;
108 return *a.limbs() < b;
109 }
110 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
111 inline typename enable_if_c<
112 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
113 bool
114 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
115 {
116 BOOST_MP_USING_ABS
117 if((b == 0) || (a.sign() != (b < 0)))
118 return a.sign();
119 if(a.sign())
120 {
121 if(a.size() > 1)
122 return true;
123 return *a.limbs() > static_cast<limb_type>(abs(b));
124 }
125 else
126 {
127 if(a.size() > 1)
128 return false;
129 return *a.limbs() < static_cast<limb_type>(b);
130 }
131 }
132
133 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
134 BOOST_MP_FORCEINLINE typename enable_if_c<
135 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
136 bool
137 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
138 {
139 if(a.size() > 1)
140 return false;
141 return *a.limbs() < b;
142 }
143 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
144 BOOST_MP_FORCEINLINE typename enable_if_c<
145 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
146 bool
147 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
148 {
149 return (b < 0) ? a.compare(b) < 0 : eval_lt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison
150 }
151
152 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
153 BOOST_MP_FORCEINLINE typename enable_if_c<
154 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator> >::value,
155 bool
156 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
157 {
158 if(a.sign())
159 return false;
160 if(a.size() > 1)
161 return true;
162 return *a.limbs() > b;
163 }
164 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
165 inline typename enable_if_c<
166 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
167 bool
168 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
169 {
170 BOOST_MP_USING_ABS
171 if(b == 0)
172 return !a.sign() && ((a.size() > 1) || *a.limbs());
173 if(a.sign() != (b < 0))
174 return !a.sign();
175 if(a.sign())
176 {
177 if(a.size() > 1)
178 return false;
179 return *a.limbs() < static_cast<limb_type>(abs(b));
180 }
181 else
182 {
183 if(a.size() > 1)
184 return true;
185 return *a.limbs() > static_cast<limb_type>(b);
186 }
187 }
188
189 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
190 BOOST_MP_FORCEINLINE typename enable_if_c<
191 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
192 bool
193 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, limb_type b) BOOST_NOEXCEPT
194 {
195 if(a.size() > 1)
196 return true;
197 return *a.limbs() > b;
198 }
199 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class Allocator>
200 BOOST_MP_FORCEINLINE typename enable_if_c<
201 !is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator> >::value,
202 bool
203 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, Allocator>& a, signed_limb_type b) BOOST_NOEXCEPT
204 {
205 return (b < 0) ? a.compare(b) > 0 : eval_gt(a, static_cast<limb_type>(b)); // Use bit pattern of b for comparison.
206 }
207 //
208 // And again for trivial cpp_ints:
209 //
210 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
211 BOOST_MP_FORCEINLINE typename enable_if_c<
212 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
213 bool
214 >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT
215 {
216 return (a.sign() == b.sign()) && (*a.limbs() == *b.limbs());
217 }
218 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
219 BOOST_MP_FORCEINLINE typename enable_if_c<
220 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
221 bool
222 >::value eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
223 {
224 return *a.limbs() == *b.limbs();
225 }
226 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
227 BOOST_MP_FORCEINLINE typename enable_if_c<
228 is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
229 bool
230 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
231 {
232 return !a.sign() && (*a.limbs() == b);
233 }
234 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
235 BOOST_MP_FORCEINLINE typename enable_if_c<
236 is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
237 bool
238 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
239 {
240 BOOST_MP_USING_ABS
241 typedef typename make_unsigned<S>::type ui_type;
242 return (a.sign() == (b < 0)) && (*a.limbs() == static_cast<ui_type>(abs(b)));
243 }
244 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
245 BOOST_MP_FORCEINLINE typename enable_if_c<
246 is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
247 bool
248 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
249 {
250 return *a.limbs() == b;
251 }
252 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
253 BOOST_MP_FORCEINLINE typename enable_if_c<
254 is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
255 bool
256 >::type eval_eq(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
257 {
258 typedef typename make_unsigned<S>::type ui_type;
259 if(b < 0)
260 {
261 cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
262 return *a.limbs() == *t.limbs();
263 }
264 else
265 {
266 return *a.limbs() == static_cast<ui_type>(b);
267 }
268 }
269
270 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
271 BOOST_MP_FORCEINLINE typename enable_if_c<
272 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
273 bool
274 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
275 {
276 if(a.sign() != b.sign())
277 return a.sign();
278 return a.sign() ? *a.limbs() > *b.limbs() : *a.limbs() < *b.limbs();
279 }
280 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
281 BOOST_MP_FORCEINLINE typename enable_if_c<
282 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
283 bool
284 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
285 {
286 return *a.limbs() < *b.limbs();
287 }
288 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
289 BOOST_MP_FORCEINLINE typename enable_if_c<
290 is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
291 bool
292 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
293 {
294 if(a.sign())
295 return true;
296 return *a.limbs() < b;
297 }
298 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
299 BOOST_MP_FORCEINLINE typename enable_if_c<
300 is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
301 bool
302 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
303 {
304 BOOST_MP_USING_ABS
305 typedef typename make_unsigned<S>::type ui_type;
306 if(a.sign() != (b < 0))
307 return a.sign();
308 return a.sign() ? (*a.limbs() > static_cast<ui_type>(abs(b))) : (*a.limbs() < static_cast<ui_type>(abs(b)));
309 }
310 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
311 BOOST_MP_FORCEINLINE typename enable_if_c<
312 is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
313 bool
314 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
315 {
316 return *a.limbs() < b;
317 }
318 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
319 BOOST_MP_FORCEINLINE typename enable_if_c<
320 is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
321 bool
322 >::type eval_lt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
323 {
324 typedef typename make_unsigned<S>::type ui_type;
325 if(b < 0)
326 {
327 cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
328 return *a.limbs() < *t.limbs();
329 }
330 else
331 {
332 return *a.limbs() < static_cast<ui_type>(b);
333 }
334 }
335
336 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
337 BOOST_MP_FORCEINLINE typename enable_if_c<
338 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
339 bool
340 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& b) BOOST_NOEXCEPT
341 {
342 if(a.sign() != b.sign())
343 return !a.sign();
344 return a.sign() ? *a.limbs() < *b.limbs() : *a.limbs() > *b.limbs();
345 }
346 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked>
347 BOOST_MP_FORCEINLINE typename enable_if_c<
348 is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
349 bool
350 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& b) BOOST_NOEXCEPT
351 {
352 return *a.limbs() > *b.limbs();
353 }
354 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
355 BOOST_MP_FORCEINLINE typename enable_if_c<
356 is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
357 bool
358 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
359 {
360 if(a.sign())
361 return false;
362 return *a.limbs() > b;
363 }
364 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
365 BOOST_MP_FORCEINLINE typename enable_if_c<
366 is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void> >::value,
367 bool
368 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, signed_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
369 {
370 BOOST_MP_USING_ABS
371 typedef typename make_unsigned<S>::type ui_type;
372 if(a.sign() != (b < 0))
373 return !a.sign();
374 return a.sign() ? (*a.limbs() < static_cast<ui_type>(abs(b))) : (*a.limbs() > static_cast<ui_type>(abs(b)));
375 }
376 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class U>
377 BOOST_MP_FORCEINLINE typename enable_if_c<
378 is_unsigned<U>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
379 bool
380 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, U b) BOOST_NOEXCEPT
381 {
382 return *a.limbs() > b;
383 }
384 template <unsigned MinBits, unsigned MaxBits, cpp_int_check_type Checked, class S>
385 BOOST_MP_FORCEINLINE typename enable_if_c<
386 is_signed<S>::value && is_trivial_cpp_int<cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> >::value,
387 bool
388 >::type eval_gt(const cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void>& a, S b) BOOST_NOEXCEPT
389 {
390 typedef typename make_unsigned<S>::type ui_type;
391 if(b < 0)
392 {
393 cpp_int_backend<MinBits, MaxBits, unsigned_magnitude, Checked, void> t(b);
394 return *a.limbs() > *t.limbs();
395 }
396 else
397 {
398 return *a.limbs() > static_cast<ui_type>(b);
399 }
400 }
401
402 #ifdef BOOST_MSVC
403 #pragma warning(pop)
404 #endif
405
406 }}} // namespaces
407
408 #endif