Coverage Report

Created: 2026-04-01 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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