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