|
1 // Boost operators.hpp header file ----------------------------------------// |
|
2 |
|
3 // (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001. |
|
4 // Distributed under the Boost Software License, Version 1.0. (See |
|
5 // accompanying file LICENSE_1_0.txt or copy at |
|
6 // http://www.boost.org/LICENSE_1_0.txt) |
|
7 |
|
8 // See http://www.boost.org/libs/utility/operators.htm for documentation. |
|
9 |
|
10 // Revision History |
|
11 // 21 Oct 02 Modified implementation of operators to allow compilers with a |
|
12 // correct named return value optimization (NRVO) to produce optimal |
|
13 // code. (Daniel Frey) |
|
14 // 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel) |
|
15 // 28 Sep 01 Factored out iterator operator groups. (Daryle Walker) |
|
16 // 27 Aug 01 'left' form for non commutative operators added; |
|
17 // additional classes for groups of related operators added; |
|
18 // workaround for empty base class optimization |
|
19 // bug of GCC 3.0 (Helmut Zeisel) |
|
20 // 25 Jun 01 output_iterator_helper changes: removed default template |
|
21 // parameters, added support for self-proxying, additional |
|
22 // documentation and tests (Aleksey Gurtovoy) |
|
23 // 29 May 01 Added operator classes for << and >>. Added input and output |
|
24 // iterator helper classes. Added classes to connect equality and |
|
25 // relational operators. Added classes for groups of related |
|
26 // operators. Reimplemented example operator and iterator helper |
|
27 // classes in terms of the new groups. (Daryle Walker, with help |
|
28 // from Alexy Gurtovoy) |
|
29 // 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly |
|
30 // supplied arguments from actually being used (Dave Abrahams) |
|
31 // 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and |
|
32 // refactoring of compiler workarounds, additional documentation |
|
33 // (Alexy Gurtovoy and Mark Rodgers with some help and prompting from |
|
34 // Dave Abrahams) |
|
35 // 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and |
|
36 // Jeremy Siek (Dave Abrahams) |
|
37 // 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5 |
|
38 // (Mark Rodgers) |
|
39 // 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy) |
|
40 // 10 Jun 00 Support for the base class chaining technique was added |
|
41 // (Aleksey Gurtovoy). See documentation and the comments below |
|
42 // for the details. |
|
43 // 12 Dec 99 Initial version with iterator operators (Jeremy Siek) |
|
44 // 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary |
|
45 // specializations of dividable, subtractable, modable (Ed Brey) |
|
46 // 17 Nov 99 Add comments (Beman Dawes) |
|
47 // Remove unnecessary specialization of operators<> (Ed Brey) |
|
48 // 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two |
|
49 // operators.(Beman Dawes) |
|
50 // 12 Nov 99 Add operators templates (Ed Brey) |
|
51 // 11 Nov 99 Add single template parameter version for compilers without |
|
52 // partial specialization (Beman Dawes) |
|
53 // 10 Nov 99 Initial version |
|
54 |
|
55 // 10 Jun 00: |
|
56 // An additional optional template parameter was added to most of |
|
57 // operator templates to support the base class chaining technique (see |
|
58 // documentation for the details). Unfortunately, a straightforward |
|
59 // implementation of this change would have broken compatibility with the |
|
60 // previous version of the library by making it impossible to use the same |
|
61 // template name (e.g. 'addable') for both the 1- and 2-argument versions of |
|
62 // an operator template. This implementation solves the backward-compatibility |
|
63 // issue at the cost of some simplicity. |
|
64 // |
|
65 // One of the complications is an existence of special auxiliary class template |
|
66 // 'is_chained_base<>' (see 'detail' namespace below), which is used |
|
67 // to determine whether its template parameter is a library's operator template |
|
68 // or not. You have to specialize 'is_chained_base<>' for each new |
|
69 // operator template you add to the library. |
|
70 // |
|
71 // However, most of the non-trivial implementation details are hidden behind |
|
72 // several local macros defined below, and as soon as you understand them, |
|
73 // you understand the whole library implementation. |
|
74 |
|
75 #ifndef BOOST_OPERATORS_HPP |
|
76 #define BOOST_OPERATORS_HPP |
|
77 |
|
78 #include <boost/config.hpp> |
|
79 #include <boost/iterator.hpp> |
|
80 #include <boost/detail/workaround.hpp> |
|
81 |
|
82 #if defined(__sgi) && !defined(__GNUC__) |
|
83 # pragma set woff 1234 |
|
84 #endif |
|
85 |
|
86 #if defined(BOOST_MSVC) |
|
87 # pragma warning( disable : 4284 ) // complaint about return type of |
|
88 #endif // operator-> not begin a UDT |
|
89 |
|
90 namespace boost { |
|
91 namespace detail { |
|
92 |
|
93 // Helmut Zeisel, empty base class optimization bug with GCC 3.0.0 |
|
94 #if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0 |
|
95 class empty_base { |
|
96 bool dummy; |
|
97 }; |
|
98 #else |
|
99 class empty_base {}; |
|
100 #endif |
|
101 |
|
102 } // namespace detail |
|
103 } // namespace boost |
|
104 |
|
105 // In this section we supply the xxxx1 and xxxx2 forms of the operator |
|
106 // templates, which are explicitly targeted at the 1-type-argument and |
|
107 // 2-type-argument operator forms, respectively. Some compilers get confused |
|
108 // when inline friend functions are overloaded in namespaces other than the |
|
109 // global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of |
|
110 // these templates must go in the global namespace. |
|
111 |
|
112 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE |
|
113 namespace boost |
|
114 { |
|
115 #endif |
|
116 |
|
117 // Basic operator classes (contributed by Dave Abrahams) ------------------// |
|
118 |
|
119 // Note that friend functions defined in a class are implicitly inline. |
|
120 // See the C++ std, 11.4 [class.friend] paragraph 5 |
|
121 |
|
122 template <class T, class U, class B = ::boost::detail::empty_base> |
|
123 struct less_than_comparable2 : B |
|
124 { |
|
125 friend bool operator<=(const T& x, const U& y) { return !(x > y); } |
|
126 friend bool operator>=(const T& x, const U& y) { return !(x < y); } |
|
127 friend bool operator>(const U& x, const T& y) { return y < x; } |
|
128 friend bool operator<(const U& x, const T& y) { return y > x; } |
|
129 friend bool operator<=(const U& x, const T& y) { return !(y < x); } |
|
130 friend bool operator>=(const U& x, const T& y) { return !(y > x); } |
|
131 }; |
|
132 |
|
133 template <class T, class B = ::boost::detail::empty_base> |
|
134 struct less_than_comparable1 : B |
|
135 { |
|
136 friend bool operator>(const T& x, const T& y) { return y < x; } |
|
137 friend bool operator<=(const T& x, const T& y) { return !(y < x); } |
|
138 friend bool operator>=(const T& x, const T& y) { return !(x < y); } |
|
139 }; |
|
140 |
|
141 template <class T, class U, class B = ::boost::detail::empty_base> |
|
142 struct equality_comparable2 : B |
|
143 { |
|
144 friend bool operator==(const U& y, const T& x) { return x == y; } |
|
145 friend bool operator!=(const U& y, const T& x) { return !(x == y); } |
|
146 friend bool operator!=(const T& y, const U& x) { return !(y == x); } |
|
147 }; |
|
148 |
|
149 template <class T, class B = ::boost::detail::empty_base> |
|
150 struct equality_comparable1 : B |
|
151 { |
|
152 friend bool operator!=(const T& x, const T& y) { return !(x == y); } |
|
153 }; |
|
154 |
|
155 // A macro which produces "name_2left" from "name". |
|
156 #define BOOST_OPERATOR2_LEFT(name) name##2##_##left |
|
157 |
|
158 // NRVO-friendly implementation (contributed by Daniel Frey) ---------------// |
|
159 |
|
160 #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) |
|
161 |
|
162 // This is the optimal implementation for ISO/ANSI C++, |
|
163 // but it requires the compiler to implement the NRVO. |
|
164 // If the compiler has no NRVO, this is the best symmetric |
|
165 // implementation available. |
|
166 |
|
167 #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ |
|
168 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
169 struct NAME##2 : B \ |
|
170 { \ |
|
171 friend T operator OP( const T& lhs, const U& rhs ) \ |
|
172 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ |
|
173 friend T operator OP( const U& lhs, const T& rhs ) \ |
|
174 { T nrv( rhs ); nrv OP##= lhs; return nrv; } \ |
|
175 }; \ |
|
176 \ |
|
177 template <class T, class B = ::boost::detail::empty_base> \ |
|
178 struct NAME##1 : B \ |
|
179 { \ |
|
180 friend T operator OP( const T& lhs, const T& rhs ) \ |
|
181 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ |
|
182 }; |
|
183 |
|
184 #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ |
|
185 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
186 struct NAME##2 : B \ |
|
187 { \ |
|
188 friend T operator OP( const T& lhs, const U& rhs ) \ |
|
189 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ |
|
190 }; \ |
|
191 \ |
|
192 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
193 struct BOOST_OPERATOR2_LEFT(NAME) : B \ |
|
194 { \ |
|
195 friend T operator OP( const U& lhs, const T& rhs ) \ |
|
196 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ |
|
197 }; \ |
|
198 \ |
|
199 template <class T, class B = ::boost::detail::empty_base> \ |
|
200 struct NAME##1 : B \ |
|
201 { \ |
|
202 friend T operator OP( const T& lhs, const T& rhs ) \ |
|
203 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ |
|
204 }; |
|
205 |
|
206 #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) |
|
207 |
|
208 // For compilers without NRVO the following code is optimal, but not |
|
209 // symmetric! Note that the implementation of |
|
210 // BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide |
|
211 // optimization opportunities to the compiler :) |
|
212 |
|
213 #define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \ |
|
214 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
215 struct NAME##2 : B \ |
|
216 { \ |
|
217 friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ |
|
218 friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \ |
|
219 }; \ |
|
220 \ |
|
221 template <class T, class B = ::boost::detail::empty_base> \ |
|
222 struct NAME##1 : B \ |
|
223 { \ |
|
224 friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ |
|
225 }; |
|
226 |
|
227 #define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \ |
|
228 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
229 struct NAME##2 : B \ |
|
230 { \ |
|
231 friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ |
|
232 }; \ |
|
233 \ |
|
234 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
235 struct BOOST_OPERATOR2_LEFT(NAME) : B \ |
|
236 { \ |
|
237 friend T operator OP( const U& lhs, const T& rhs ) \ |
|
238 { return T( lhs ) OP##= rhs; } \ |
|
239 }; \ |
|
240 \ |
|
241 template <class T, class B = ::boost::detail::empty_base> \ |
|
242 struct NAME##1 : B \ |
|
243 { \ |
|
244 friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ |
|
245 }; |
|
246 |
|
247 #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) |
|
248 |
|
249 BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * ) |
|
250 BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + ) |
|
251 BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - ) |
|
252 BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / ) |
|
253 BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % ) |
|
254 BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ ) |
|
255 BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & ) |
|
256 BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | ) |
|
257 |
|
258 #undef BOOST_BINARY_OPERATOR_COMMUTATIVE |
|
259 #undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE |
|
260 #undef BOOST_OPERATOR2_LEFT |
|
261 |
|
262 // incrementable and decrementable contributed by Jeremy Siek |
|
263 |
|
264 template <class T, class B = ::boost::detail::empty_base> |
|
265 struct incrementable : B |
|
266 { |
|
267 friend T operator++(T& x, int) |
|
268 { |
|
269 incrementable_type nrv(x); |
|
270 ++x; |
|
271 return nrv; |
|
272 } |
|
273 private: // The use of this typedef works around a Borland bug |
|
274 typedef T incrementable_type; |
|
275 }; |
|
276 |
|
277 template <class T, class B = ::boost::detail::empty_base> |
|
278 struct decrementable : B |
|
279 { |
|
280 friend T operator--(T& x, int) |
|
281 { |
|
282 decrementable_type nrv(x); |
|
283 --x; |
|
284 return nrv; |
|
285 } |
|
286 private: // The use of this typedef works around a Borland bug |
|
287 typedef T decrementable_type; |
|
288 }; |
|
289 |
|
290 // Iterator operator classes (contributed by Jeremy Siek) ------------------// |
|
291 |
|
292 template <class T, class P, class B = ::boost::detail::empty_base> |
|
293 struct dereferenceable : B |
|
294 { |
|
295 P operator->() const |
|
296 { |
|
297 return &*static_cast<const T&>(*this); |
|
298 } |
|
299 }; |
|
300 |
|
301 template <class T, class I, class R, class B = ::boost::detail::empty_base> |
|
302 struct indexable : B |
|
303 { |
|
304 R operator[](I n) const |
|
305 { |
|
306 return *(static_cast<const T&>(*this) + n); |
|
307 } |
|
308 }; |
|
309 |
|
310 // More operator classes (contributed by Daryle Walker) --------------------// |
|
311 // (NRVO-friendly implementation contributed by Daniel Frey) ---------------// |
|
312 |
|
313 #if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) |
|
314 |
|
315 #define BOOST_BINARY_OPERATOR( NAME, OP ) \ |
|
316 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
317 struct NAME##2 : B \ |
|
318 { \ |
|
319 friend T operator OP( const T& lhs, const U& rhs ) \ |
|
320 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ |
|
321 }; \ |
|
322 \ |
|
323 template <class T, class B = ::boost::detail::empty_base> \ |
|
324 struct NAME##1 : B \ |
|
325 { \ |
|
326 friend T operator OP( const T& lhs, const T& rhs ) \ |
|
327 { T nrv( lhs ); nrv OP##= rhs; return nrv; } \ |
|
328 }; |
|
329 |
|
330 #else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) |
|
331 |
|
332 #define BOOST_BINARY_OPERATOR( NAME, OP ) \ |
|
333 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
334 struct NAME##2 : B \ |
|
335 { \ |
|
336 friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \ |
|
337 }; \ |
|
338 \ |
|
339 template <class T, class B = ::boost::detail::empty_base> \ |
|
340 struct NAME##1 : B \ |
|
341 { \ |
|
342 friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \ |
|
343 }; |
|
344 |
|
345 #endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS) |
|
346 |
|
347 BOOST_BINARY_OPERATOR( left_shiftable, << ) |
|
348 BOOST_BINARY_OPERATOR( right_shiftable, >> ) |
|
349 |
|
350 #undef BOOST_BINARY_OPERATOR |
|
351 |
|
352 template <class T, class U, class B = ::boost::detail::empty_base> |
|
353 struct equivalent2 : B |
|
354 { |
|
355 friend bool operator==(const T& x, const U& y) |
|
356 { |
|
357 return !(x < y) && !(x > y); |
|
358 } |
|
359 }; |
|
360 |
|
361 template <class T, class B = ::boost::detail::empty_base> |
|
362 struct equivalent1 : B |
|
363 { |
|
364 friend bool operator==(const T&x, const T&y) |
|
365 { |
|
366 return !(x < y) && !(y < x); |
|
367 } |
|
368 }; |
|
369 |
|
370 template <class T, class U, class B = ::boost::detail::empty_base> |
|
371 struct partially_ordered2 : B |
|
372 { |
|
373 friend bool operator<=(const T& x, const U& y) |
|
374 { return (x < y) || (x == y); } |
|
375 friend bool operator>=(const T& x, const U& y) |
|
376 { return (x > y) || (x == y); } |
|
377 friend bool operator>(const U& x, const T& y) |
|
378 { return y < x; } |
|
379 friend bool operator<(const U& x, const T& y) |
|
380 { return y > x; } |
|
381 friend bool operator<=(const U& x, const T& y) |
|
382 { return (y > x) || (y == x); } |
|
383 friend bool operator>=(const U& x, const T& y) |
|
384 { return (y < x) || (y == x); } |
|
385 }; |
|
386 |
|
387 template <class T, class B = ::boost::detail::empty_base> |
|
388 struct partially_ordered1 : B |
|
389 { |
|
390 friend bool operator>(const T& x, const T& y) |
|
391 { return y < x; } |
|
392 friend bool operator<=(const T& x, const T& y) |
|
393 { return (x < y) || (x == y); } |
|
394 friend bool operator>=(const T& x, const T& y) |
|
395 { return (y < x) || (x == y); } |
|
396 }; |
|
397 |
|
398 // Combined operator classes (contributed by Daryle Walker) ----------------// |
|
399 |
|
400 template <class T, class U, class B = ::boost::detail::empty_base> |
|
401 struct totally_ordered2 |
|
402 : less_than_comparable2<T, U |
|
403 , equality_comparable2<T, U, B |
|
404 > > {}; |
|
405 |
|
406 template <class T, class B = ::boost::detail::empty_base> |
|
407 struct totally_ordered1 |
|
408 : less_than_comparable1<T |
|
409 , equality_comparable1<T, B |
|
410 > > {}; |
|
411 |
|
412 template <class T, class U, class B = ::boost::detail::empty_base> |
|
413 struct additive2 |
|
414 : addable2<T, U |
|
415 , subtractable2<T, U, B |
|
416 > > {}; |
|
417 |
|
418 template <class T, class B = ::boost::detail::empty_base> |
|
419 struct additive1 |
|
420 : addable1<T |
|
421 , subtractable1<T, B |
|
422 > > {}; |
|
423 |
|
424 template <class T, class U, class B = ::boost::detail::empty_base> |
|
425 struct multiplicative2 |
|
426 : multipliable2<T, U |
|
427 , dividable2<T, U, B |
|
428 > > {}; |
|
429 |
|
430 template <class T, class B = ::boost::detail::empty_base> |
|
431 struct multiplicative1 |
|
432 : multipliable1<T |
|
433 , dividable1<T, B |
|
434 > > {}; |
|
435 |
|
436 template <class T, class U, class B = ::boost::detail::empty_base> |
|
437 struct integer_multiplicative2 |
|
438 : multiplicative2<T, U |
|
439 , modable2<T, U, B |
|
440 > > {}; |
|
441 |
|
442 template <class T, class B = ::boost::detail::empty_base> |
|
443 struct integer_multiplicative1 |
|
444 : multiplicative1<T |
|
445 , modable1<T, B |
|
446 > > {}; |
|
447 |
|
448 template <class T, class U, class B = ::boost::detail::empty_base> |
|
449 struct arithmetic2 |
|
450 : additive2<T, U |
|
451 , multiplicative2<T, U, B |
|
452 > > {}; |
|
453 |
|
454 template <class T, class B = ::boost::detail::empty_base> |
|
455 struct arithmetic1 |
|
456 : additive1<T |
|
457 , multiplicative1<T, B |
|
458 > > {}; |
|
459 |
|
460 template <class T, class U, class B = ::boost::detail::empty_base> |
|
461 struct integer_arithmetic2 |
|
462 : additive2<T, U |
|
463 , integer_multiplicative2<T, U, B |
|
464 > > {}; |
|
465 |
|
466 template <class T, class B = ::boost::detail::empty_base> |
|
467 struct integer_arithmetic1 |
|
468 : additive1<T |
|
469 , integer_multiplicative1<T, B |
|
470 > > {}; |
|
471 |
|
472 template <class T, class U, class B = ::boost::detail::empty_base> |
|
473 struct bitwise2 |
|
474 : xorable2<T, U |
|
475 , andable2<T, U |
|
476 , orable2<T, U, B |
|
477 > > > {}; |
|
478 |
|
479 template <class T, class B = ::boost::detail::empty_base> |
|
480 struct bitwise1 |
|
481 : xorable1<T |
|
482 , andable1<T |
|
483 , orable1<T, B |
|
484 > > > {}; |
|
485 |
|
486 template <class T, class B = ::boost::detail::empty_base> |
|
487 struct unit_steppable |
|
488 : incrementable<T |
|
489 , decrementable<T, B |
|
490 > > {}; |
|
491 |
|
492 template <class T, class U, class B = ::boost::detail::empty_base> |
|
493 struct shiftable2 |
|
494 : left_shiftable2<T, U |
|
495 , right_shiftable2<T, U, B |
|
496 > > {}; |
|
497 |
|
498 template <class T, class B = ::boost::detail::empty_base> |
|
499 struct shiftable1 |
|
500 : left_shiftable1<T |
|
501 , right_shiftable1<T, B |
|
502 > > {}; |
|
503 |
|
504 template <class T, class U, class B = ::boost::detail::empty_base> |
|
505 struct ring_operators2 |
|
506 : additive2<T, U |
|
507 , subtractable2_left<T, U |
|
508 , multipliable2<T, U, B |
|
509 > > > {}; |
|
510 |
|
511 template <class T, class B = ::boost::detail::empty_base> |
|
512 struct ring_operators1 |
|
513 : additive1<T |
|
514 , multipliable1<T, B |
|
515 > > {}; |
|
516 |
|
517 template <class T, class U, class B = ::boost::detail::empty_base> |
|
518 struct ordered_ring_operators2 |
|
519 : ring_operators2<T, U |
|
520 , totally_ordered2<T, U, B |
|
521 > > {}; |
|
522 |
|
523 template <class T, class B = ::boost::detail::empty_base> |
|
524 struct ordered_ring_operators1 |
|
525 : ring_operators1<T |
|
526 , totally_ordered1<T, B |
|
527 > > {}; |
|
528 |
|
529 template <class T, class U, class B = ::boost::detail::empty_base> |
|
530 struct field_operators2 |
|
531 : ring_operators2<T, U |
|
532 , dividable2<T, U |
|
533 , dividable2_left<T, U, B |
|
534 > > > {}; |
|
535 |
|
536 template <class T, class B = ::boost::detail::empty_base> |
|
537 struct field_operators1 |
|
538 : ring_operators1<T |
|
539 , dividable1<T, B |
|
540 > > {}; |
|
541 |
|
542 template <class T, class U, class B = ::boost::detail::empty_base> |
|
543 struct ordered_field_operators2 |
|
544 : field_operators2<T, U |
|
545 , totally_ordered2<T, U, B |
|
546 > > {}; |
|
547 |
|
548 template <class T, class B = ::boost::detail::empty_base> |
|
549 struct ordered_field_operators1 |
|
550 : field_operators1<T |
|
551 , totally_ordered1<T, B |
|
552 > > {}; |
|
553 |
|
554 template <class T, class U, class B = ::boost::detail::empty_base> |
|
555 struct euclidian_ring_operators2 |
|
556 : ring_operators2<T, U |
|
557 , dividable2<T, U |
|
558 , dividable2_left<T, U |
|
559 , modable2<T, U |
|
560 , modable2_left<T, U, B |
|
561 > > > > > {}; |
|
562 |
|
563 template <class T, class B = ::boost::detail::empty_base> |
|
564 struct euclidian_ring_operators1 |
|
565 : ring_operators1<T |
|
566 , dividable1<T |
|
567 , modable1<T, B |
|
568 > > > {}; |
|
569 |
|
570 template <class T, class U, class B = ::boost::detail::empty_base> |
|
571 struct ordered_euclidian_ring_operators2 |
|
572 : totally_ordered2<T, U |
|
573 , euclidian_ring_operators2<T, U, B |
|
574 > > {}; |
|
575 |
|
576 template <class T, class B = ::boost::detail::empty_base> |
|
577 struct ordered_euclidian_ring_operators1 |
|
578 : totally_ordered1<T |
|
579 , euclidian_ring_operators1<T, B |
|
580 > > {}; |
|
581 |
|
582 template <class T, class P, class B = ::boost::detail::empty_base> |
|
583 struct input_iteratable |
|
584 : equality_comparable1<T |
|
585 , incrementable<T |
|
586 , dereferenceable<T, P, B |
|
587 > > > {}; |
|
588 |
|
589 template <class T, class B = ::boost::detail::empty_base> |
|
590 struct output_iteratable |
|
591 : incrementable<T, B |
|
592 > {}; |
|
593 |
|
594 template <class T, class P, class B = ::boost::detail::empty_base> |
|
595 struct forward_iteratable |
|
596 : input_iteratable<T, P, B |
|
597 > {}; |
|
598 |
|
599 template <class T, class P, class B = ::boost::detail::empty_base> |
|
600 struct bidirectional_iteratable |
|
601 : forward_iteratable<T, P |
|
602 , decrementable<T, B |
|
603 > > {}; |
|
604 |
|
605 // To avoid repeated derivation from equality_comparable, |
|
606 // which is an indirect base class of bidirectional_iterable, |
|
607 // random_access_iteratable must not be derived from totally_ordered1 |
|
608 // but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001) |
|
609 template <class T, class P, class D, class R, class B = ::boost::detail::empty_base> |
|
610 struct random_access_iteratable |
|
611 : bidirectional_iteratable<T, P |
|
612 , less_than_comparable1<T |
|
613 , additive2<T, D |
|
614 , indexable<T, D, R, B |
|
615 > > > > {}; |
|
616 |
|
617 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE |
|
618 } // namespace boost |
|
619 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE |
|
620 |
|
621 |
|
622 // BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 - |
|
623 // |
|
624 // When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an |
|
625 // operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used |
|
626 // for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for |
|
627 // two-argument forms. Note that these macros expect to be invoked from within |
|
628 // boost. |
|
629 |
|
630 #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE |
|
631 |
|
632 // The template is already in boost so we have nothing to do. |
|
633 # define BOOST_IMPORT_TEMPLATE4(template_name) |
|
634 # define BOOST_IMPORT_TEMPLATE3(template_name) |
|
635 # define BOOST_IMPORT_TEMPLATE2(template_name) |
|
636 # define BOOST_IMPORT_TEMPLATE1(template_name) |
|
637 |
|
638 #else // BOOST_NO_OPERATORS_IN_NAMESPACE |
|
639 |
|
640 # ifndef BOOST_NO_USING_TEMPLATE |
|
641 |
|
642 // Bring the names in with a using-declaration |
|
643 // to avoid stressing the compiler. |
|
644 # define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name; |
|
645 # define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name; |
|
646 # define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name; |
|
647 # define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name; |
|
648 |
|
649 # else |
|
650 |
|
651 // Otherwise, because a Borland C++ 5.5 bug prevents a using declaration |
|
652 // from working, we are forced to use inheritance for that compiler. |
|
653 # define BOOST_IMPORT_TEMPLATE4(template_name) \ |
|
654 template <class T, class U, class V, class W, class B = ::boost::detail::empty_base> \ |
|
655 struct template_name : ::template_name<T, U, V, W, B> {}; |
|
656 |
|
657 # define BOOST_IMPORT_TEMPLATE3(template_name) \ |
|
658 template <class T, class U, class V, class B = ::boost::detail::empty_base> \ |
|
659 struct template_name : ::template_name<T, U, V, B> {}; |
|
660 |
|
661 # define BOOST_IMPORT_TEMPLATE2(template_name) \ |
|
662 template <class T, class U, class B = ::boost::detail::empty_base> \ |
|
663 struct template_name : ::template_name<T, U, B> {}; |
|
664 |
|
665 # define BOOST_IMPORT_TEMPLATE1(template_name) \ |
|
666 template <class T, class B = ::boost::detail::empty_base> \ |
|
667 struct template_name : ::template_name<T, B> {}; |
|
668 |
|
669 # endif // BOOST_NO_USING_TEMPLATE |
|
670 |
|
671 #endif // BOOST_NO_OPERATORS_IN_NAMESPACE |
|
672 |
|
673 // |
|
674 // Here's where we put it all together, defining the xxxx forms of the templates |
|
675 // in namespace boost. We also define specializations of is_chained_base<> for |
|
676 // the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as |
|
677 // necessary. |
|
678 // |
|
679 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
680 |
|
681 // is_chained_base<> - a traits class used to distinguish whether an operator |
|
682 // template argument is being used for base class chaining, or is specifying a |
|
683 // 2nd argument type. |
|
684 |
|
685 namespace boost { |
|
686 // A type parameter is used instead of a plain bool because Borland's compiler |
|
687 // didn't cope well with the more obvious non-type template parameter. |
|
688 namespace detail { |
|
689 struct true_t {}; |
|
690 struct false_t {}; |
|
691 } // namespace detail |
|
692 |
|
693 // Unspecialized version assumes that most types are not being used for base |
|
694 // class chaining. We specialize for the operator templates defined in this |
|
695 // library. |
|
696 template<class T> struct is_chained_base { |
|
697 typedef ::boost::detail::false_t value; |
|
698 }; |
|
699 |
|
700 } // namespace boost |
|
701 |
|
702 // Import a 4-type-argument operator template into boost (if necessary) and |
|
703 // provide a specialization of 'is_chained_base<>' for it. |
|
704 # define BOOST_OPERATOR_TEMPLATE4(template_name4) \ |
|
705 BOOST_IMPORT_TEMPLATE4(template_name4) \ |
|
706 template<class T, class U, class V, class W, class B> \ |
|
707 struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \ |
|
708 typedef ::boost::detail::true_t value; \ |
|
709 }; |
|
710 |
|
711 // Import a 3-type-argument operator template into boost (if necessary) and |
|
712 // provide a specialization of 'is_chained_base<>' for it. |
|
713 # define BOOST_OPERATOR_TEMPLATE3(template_name3) \ |
|
714 BOOST_IMPORT_TEMPLATE3(template_name3) \ |
|
715 template<class T, class U, class V, class B> \ |
|
716 struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \ |
|
717 typedef ::boost::detail::true_t value; \ |
|
718 }; |
|
719 |
|
720 // Import a 2-type-argument operator template into boost (if necessary) and |
|
721 // provide a specialization of 'is_chained_base<>' for it. |
|
722 # define BOOST_OPERATOR_TEMPLATE2(template_name2) \ |
|
723 BOOST_IMPORT_TEMPLATE2(template_name2) \ |
|
724 template<class T, class U, class B> \ |
|
725 struct is_chained_base< ::boost::template_name2<T, U, B> > { \ |
|
726 typedef ::boost::detail::true_t value; \ |
|
727 }; |
|
728 |
|
729 // Import a 1-type-argument operator template into boost (if necessary) and |
|
730 // provide a specialization of 'is_chained_base<>' for it. |
|
731 # define BOOST_OPERATOR_TEMPLATE1(template_name1) \ |
|
732 BOOST_IMPORT_TEMPLATE1(template_name1) \ |
|
733 template<class T, class B> \ |
|
734 struct is_chained_base< ::boost::template_name1<T, B> > { \ |
|
735 typedef ::boost::detail::true_t value; \ |
|
736 }; |
|
737 |
|
738 // BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it |
|
739 // can be used for specifying both 1-argument and 2-argument forms. Requires the |
|
740 // existence of two previously defined class templates named '<template_name>1' |
|
741 // and '<template_name>2' which must implement the corresponding 1- and 2- |
|
742 // argument forms. |
|
743 // |
|
744 // The template type parameter O == is_chained_base<U>::value is used to |
|
745 // distinguish whether the 2nd argument to <template_name> is being used for |
|
746 // base class chaining from another boost operator template or is describing a |
|
747 // 2nd operand type. O == true_t only when U is actually an another operator |
|
748 // template from the library. Partial specialization is used to select an |
|
749 // implementation in terms of either '<template_name>1' or '<template_name>2'. |
|
750 // |
|
751 |
|
752 # define BOOST_OPERATOR_TEMPLATE(template_name) \ |
|
753 template <class T \ |
|
754 ,class U = T \ |
|
755 ,class B = ::boost::detail::empty_base \ |
|
756 ,class O = typename is_chained_base<U>::value \ |
|
757 > \ |
|
758 struct template_name : template_name##2<T, U, B> {}; \ |
|
759 \ |
|
760 template<class T, class U, class B> \ |
|
761 struct template_name<T, U, B, ::boost::detail::true_t> \ |
|
762 : template_name##1<T, U> {}; \ |
|
763 \ |
|
764 template <class T, class B> \ |
|
765 struct template_name<T, T, B, ::boost::detail::false_t> \ |
|
766 : template_name##1<T, B> {}; \ |
|
767 \ |
|
768 template<class T, class U, class B, class O> \ |
|
769 struct is_chained_base< ::boost::template_name<T, U, B, O> > { \ |
|
770 typedef ::boost::detail::true_t value; \ |
|
771 }; \ |
|
772 \ |
|
773 BOOST_OPERATOR_TEMPLATE2(template_name##2) \ |
|
774 BOOST_OPERATOR_TEMPLATE1(template_name##1) |
|
775 |
|
776 |
|
777 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
778 |
|
779 # define BOOST_OPERATOR_TEMPLATE4(template_name4) \ |
|
780 BOOST_IMPORT_TEMPLATE4(template_name4) |
|
781 # define BOOST_OPERATOR_TEMPLATE3(template_name3) \ |
|
782 BOOST_IMPORT_TEMPLATE3(template_name3) |
|
783 # define BOOST_OPERATOR_TEMPLATE2(template_name2) \ |
|
784 BOOST_IMPORT_TEMPLATE2(template_name2) |
|
785 # define BOOST_OPERATOR_TEMPLATE1(template_name1) \ |
|
786 BOOST_IMPORT_TEMPLATE1(template_name1) |
|
787 |
|
788 // In this case we can only assume that template_name<> is equivalent to the |
|
789 // more commonly needed template_name1<> form. |
|
790 # define BOOST_OPERATOR_TEMPLATE(template_name) \ |
|
791 template <class T, class B = ::boost::detail::empty_base> \ |
|
792 struct template_name : template_name##1<T, B> {}; |
|
793 |
|
794 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
795 |
|
796 namespace boost { |
|
797 |
|
798 BOOST_OPERATOR_TEMPLATE(less_than_comparable) |
|
799 BOOST_OPERATOR_TEMPLATE(equality_comparable) |
|
800 BOOST_OPERATOR_TEMPLATE(multipliable) |
|
801 BOOST_OPERATOR_TEMPLATE(addable) |
|
802 BOOST_OPERATOR_TEMPLATE(subtractable) |
|
803 BOOST_OPERATOR_TEMPLATE2(subtractable2_left) |
|
804 BOOST_OPERATOR_TEMPLATE(dividable) |
|
805 BOOST_OPERATOR_TEMPLATE2(dividable2_left) |
|
806 BOOST_OPERATOR_TEMPLATE(modable) |
|
807 BOOST_OPERATOR_TEMPLATE2(modable2_left) |
|
808 BOOST_OPERATOR_TEMPLATE(xorable) |
|
809 BOOST_OPERATOR_TEMPLATE(andable) |
|
810 BOOST_OPERATOR_TEMPLATE(orable) |
|
811 |
|
812 BOOST_OPERATOR_TEMPLATE1(incrementable) |
|
813 BOOST_OPERATOR_TEMPLATE1(decrementable) |
|
814 |
|
815 BOOST_OPERATOR_TEMPLATE2(dereferenceable) |
|
816 BOOST_OPERATOR_TEMPLATE3(indexable) |
|
817 |
|
818 BOOST_OPERATOR_TEMPLATE(left_shiftable) |
|
819 BOOST_OPERATOR_TEMPLATE(right_shiftable) |
|
820 BOOST_OPERATOR_TEMPLATE(equivalent) |
|
821 BOOST_OPERATOR_TEMPLATE(partially_ordered) |
|
822 |
|
823 BOOST_OPERATOR_TEMPLATE(totally_ordered) |
|
824 BOOST_OPERATOR_TEMPLATE(additive) |
|
825 BOOST_OPERATOR_TEMPLATE(multiplicative) |
|
826 BOOST_OPERATOR_TEMPLATE(integer_multiplicative) |
|
827 BOOST_OPERATOR_TEMPLATE(arithmetic) |
|
828 BOOST_OPERATOR_TEMPLATE(integer_arithmetic) |
|
829 BOOST_OPERATOR_TEMPLATE(bitwise) |
|
830 BOOST_OPERATOR_TEMPLATE1(unit_steppable) |
|
831 BOOST_OPERATOR_TEMPLATE(shiftable) |
|
832 BOOST_OPERATOR_TEMPLATE(ring_operators) |
|
833 BOOST_OPERATOR_TEMPLATE(ordered_ring_operators) |
|
834 BOOST_OPERATOR_TEMPLATE(field_operators) |
|
835 BOOST_OPERATOR_TEMPLATE(ordered_field_operators) |
|
836 BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators) |
|
837 BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators) |
|
838 BOOST_OPERATOR_TEMPLATE2(input_iteratable) |
|
839 BOOST_OPERATOR_TEMPLATE1(output_iteratable) |
|
840 BOOST_OPERATOR_TEMPLATE2(forward_iteratable) |
|
841 BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable) |
|
842 BOOST_OPERATOR_TEMPLATE4(random_access_iteratable) |
|
843 |
|
844 #undef BOOST_OPERATOR_TEMPLATE |
|
845 #undef BOOST_OPERATOR_TEMPLATE4 |
|
846 #undef BOOST_OPERATOR_TEMPLATE3 |
|
847 #undef BOOST_OPERATOR_TEMPLATE2 |
|
848 #undef BOOST_OPERATOR_TEMPLATE1 |
|
849 #undef BOOST_IMPORT_TEMPLATE1 |
|
850 #undef BOOST_IMPORT_TEMPLATE2 |
|
851 #undef BOOST_IMPORT_TEMPLATE3 |
|
852 #undef BOOST_IMPORT_TEMPLATE4 |
|
853 |
|
854 // The following 'operators' classes can only be used portably if the derived class |
|
855 // declares ALL of the required member operators. |
|
856 template <class T, class U> |
|
857 struct operators2 |
|
858 : totally_ordered2<T,U |
|
859 , integer_arithmetic2<T,U |
|
860 , bitwise2<T,U |
|
861 > > > {}; |
|
862 |
|
863 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|
864 template <class T, class U = T> |
|
865 struct operators : operators2<T, U> {}; |
|
866 |
|
867 template <class T> struct operators<T, T> |
|
868 #else |
|
869 template <class T> struct operators |
|
870 #endif |
|
871 : totally_ordered<T |
|
872 , integer_arithmetic<T |
|
873 , bitwise<T |
|
874 , unit_steppable<T |
|
875 > > > > {}; |
|
876 |
|
877 // Iterator helper classes (contributed by Jeremy Siek) -------------------// |
|
878 // (Input and output iterator helpers contributed by Daryle Walker) -------// |
|
879 // (Changed to use combined operator classes by Daryle Walker) ------------// |
|
880 template <class T, |
|
881 class V, |
|
882 class D = std::ptrdiff_t, |
|
883 class P = V const *, |
|
884 class R = V const &> |
|
885 struct input_iterator_helper |
|
886 : input_iteratable<T, P |
|
887 , boost::iterator<std::input_iterator_tag, V, D, P, R |
|
888 > > {}; |
|
889 |
|
890 template<class T> |
|
891 struct output_iterator_helper |
|
892 : output_iteratable<T |
|
893 , boost::iterator<std::output_iterator_tag, void, void, void, void |
|
894 > > |
|
895 { |
|
896 T& operator*() { return static_cast<T&>(*this); } |
|
897 T& operator++() { return static_cast<T&>(*this); } |
|
898 }; |
|
899 |
|
900 template <class T, |
|
901 class V, |
|
902 class D = std::ptrdiff_t, |
|
903 class P = V*, |
|
904 class R = V&> |
|
905 struct forward_iterator_helper |
|
906 : forward_iteratable<T, P |
|
907 , boost::iterator<std::forward_iterator_tag, V, D, P, R |
|
908 > > {}; |
|
909 |
|
910 template <class T, |
|
911 class V, |
|
912 class D = std::ptrdiff_t, |
|
913 class P = V*, |
|
914 class R = V&> |
|
915 struct bidirectional_iterator_helper |
|
916 : bidirectional_iteratable<T, P |
|
917 , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R |
|
918 > > {}; |
|
919 |
|
920 template <class T, |
|
921 class V, |
|
922 class D = std::ptrdiff_t, |
|
923 class P = V*, |
|
924 class R = V&> |
|
925 struct random_access_iterator_helper |
|
926 : random_access_iteratable<T, P, D, R |
|
927 , boost::iterator<std::random_access_iterator_tag, V, D, P, R |
|
928 > > |
|
929 { |
|
930 friend D requires_difference_operator(const T& x, const T& y) { |
|
931 return x - y; |
|
932 } |
|
933 }; // random_access_iterator_helper |
|
934 |
|
935 } // namespace boost |
|
936 |
|
937 #if defined(__sgi) && !defined(__GNUC__) |
|
938 #pragma reset woff 1234 |
|
939 #endif |
|
940 |
|
941 #endif // BOOST_OPERATORS_HPP |