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