cover_operators.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // boost/endian/detail/cover_operators.hpp ----------------------------------//
  2. // Copyright Darin Adler 2000
  3. // Copyright Beman Dawes 2008
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP
  7. #define BOOST_ENDIAN_COVER_OPERATORS_HPP
  8. #if defined(_MSC_VER)
  9. # pragma warning(push)
  10. # pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
  11. #endif
  12. # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
  13. # include <boost/operators.hpp>
  14. # endif
  15. #include <boost/config.hpp>
  16. #include <iosfwd>
  17. namespace boost
  18. {
  19. namespace endian
  20. {
  21. //--------------------------------------------------------------------------------------//
  22. // A class that adds arithmetic operators to an arithmetic cover class
  23. //
  24. // Uses the curiously recurring template pattern (CRTP).
  25. //
  26. // If the class being covered has a non-explicit conversion to an integer type
  27. // then a smaller number of cover operations are needed. Define the macro
  28. // BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this.
  29. //
  30. // Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
  31. //--------------------------------------------------------------------------------------//
  32. template <class D, // D is the CRTP derived type, i.e. the cover class
  33. class ArithmeticT>
  34. class cover_operators
  35. # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
  36. : boost::operators<D>
  37. # endif
  38. {
  39. // The other operations take advantage of the type conversion that's
  40. // built into unary +.
  41. // Unary operations.
  42. friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; }
  43. # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
  44. friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; }
  45. friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; }
  46. friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; }
  47. // The basic ordering operations.
  48. friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; }
  49. friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; }
  50. # endif
  51. // The basic arithmetic operations.
  52. friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  53. { return x = static_cast<ArithmeticT>(+x + y); }
  54. friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  55. { return x = static_cast<ArithmeticT>(+x - y); }
  56. friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  57. { return x = static_cast<ArithmeticT>(+x * y); }
  58. friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  59. { return x = static_cast<ArithmeticT>(+x / y); }
  60. friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  61. { return x = static_cast<ArithmeticT>(+x % y); }
  62. friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  63. { return x = static_cast<ArithmeticT>(+x & y); }
  64. friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  65. { return x = static_cast<ArithmeticT>(+x | y); }
  66. friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  67. { return x = static_cast<ArithmeticT>(+x ^ y); }
  68. friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  69. { return x = static_cast<ArithmeticT>(+x << y); }
  70. friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT
  71. { return x = static_cast<ArithmeticT>(+x >> y); }
  72. // A few binary arithmetic operations not covered by operators base class.
  73. friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT
  74. { return static_cast<ArithmeticT>(+x << y); }
  75. friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT
  76. { return static_cast<ArithmeticT>(+x >> y); }
  77. // Auto-increment and auto-decrement can be defined in terms of the
  78. // arithmetic operations.
  79. friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; }
  80. friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; }
  81. # ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS
  82. friend D operator++(D& x, int) BOOST_NOEXCEPT
  83. {
  84. D tmp(x);
  85. x += 1;
  86. return tmp;
  87. }
  88. friend D operator--(D& x, int) BOOST_NOEXCEPT
  89. {
  90. D tmp(x);
  91. x -= 1;
  92. return tmp;
  93. }
  94. # endif
  95. # ifndef BOOST_NO_IO_COVER_OPERATORS
  96. // Stream inserter
  97. template <class charT, class traits>
  98. friend std::basic_ostream<charT, traits>&
  99. operator<<(std::basic_ostream<charT, traits>& os, const D& x)
  100. {
  101. return os << +x;
  102. }
  103. // Stream extractor
  104. template <class charT, class traits>
  105. friend std::basic_istream<charT, traits>&
  106. operator>>(std::basic_istream<charT, traits>& is, D& x)
  107. {
  108. ArithmeticT i;
  109. if (is >> i)
  110. x = i;
  111. return is;
  112. }
  113. # endif
  114. };
  115. } // namespace endian
  116. } // namespace boost
  117. #if defined(_MSC_VER)
  118. # pragma warning(pop)
  119. #endif
  120. #endif // BOOST_ENDIAN_COVER_OPERATORS_HPP