Chris@102: // boost/endian/detail/cover_operators.hpp ----------------------------------// Chris@102: Chris@102: // Copyright Darin Adler 2000 Chris@102: // Copyright Beman Dawes 2008 Chris@102: Chris@102: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@102: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@102: Chris@102: #ifndef BOOST_ENDIAN_COVER_OPERATORS_HPP Chris@102: #define BOOST_ENDIAN_COVER_OPERATORS_HPP Chris@102: Chris@102: #if defined(_MSC_VER) Chris@102: # pragma warning(push) Chris@102: # pragma warning(disable:4365) // conversion ... signed/unsigned mismatch Chris@102: #endif Chris@102: Chris@102: # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS Chris@102: # include Chris@102: # endif Chris@102: Chris@102: #include Chris@102: #include Chris@102: Chris@102: namespace boost Chris@102: { Chris@102: namespace endian Chris@102: { Chris@102: Chris@102: //--------------------------------------------------------------------------------------// Chris@102: Chris@102: // A class that adds arithmetic operators to an arithmetic cover class Chris@102: // Chris@102: // Uses the curiously recurring template pattern (CRTP). Chris@102: // Chris@102: // If the class being covered has a non-explicit conversion to an integer type Chris@102: // then a smaller number of cover operations are needed. Define the macro Chris@102: // BOOST_ENDIAN_MINIMAL_COVER_OPERATORS to indicate this. Chris@102: // Chris@102: // Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired. Chris@102: Chris@102: //--------------------------------------------------------------------------------------// Chris@102: Chris@102: template Chris@102: class cover_operators Chris@102: # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS Chris@102: : boost::operators Chris@102: # endif Chris@102: { Chris@102: // The other operations take advantage of the type conversion that's Chris@102: // built into unary +. Chris@102: Chris@102: // Unary operations. Chris@102: friend ArithmeticT operator+(const D& x) BOOST_NOEXCEPT { return x; } Chris@102: # ifndef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS Chris@102: friend ArithmeticT operator-(const D& x) BOOST_NOEXCEPT { return -+x; } Chris@102: friend ArithmeticT operator~(const D& x) BOOST_NOEXCEPT { return ~+x; } Chris@102: friend ArithmeticT operator!(const D& x) BOOST_NOEXCEPT { return !+x; } Chris@102: Chris@102: // The basic ordering operations. Chris@102: friend bool operator==(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x == y; } Chris@102: friend bool operator<(const D& x, ArithmeticT y) BOOST_NOEXCEPT { return +x < y; } Chris@102: # endif Chris@102: Chris@102: // The basic arithmetic operations. Chris@102: friend D& operator+=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x + y); } Chris@102: friend D& operator-=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x - y); } Chris@102: friend D& operator*=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x * y); } Chris@102: friend D& operator/=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x / y); } Chris@102: friend D& operator%=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x % y); } Chris@102: friend D& operator&=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x & y); } Chris@102: friend D& operator|=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x | y); } Chris@102: friend D& operator^=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x ^ y); } Chris@102: friend D& operator<<=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x << y); } Chris@102: friend D& operator>>=(D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return x = static_cast(+x >> y); } Chris@102: Chris@102: // A few binary arithmetic operations not covered by operators base class. Chris@102: friend ArithmeticT operator<<(const D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return static_cast(+x << y); } Chris@102: friend ArithmeticT operator>>(const D& x, ArithmeticT y) BOOST_NOEXCEPT Chris@102: { return static_cast(+x >> y); } Chris@102: Chris@102: // Auto-increment and auto-decrement can be defined in terms of the Chris@102: // arithmetic operations. Chris@102: friend D& operator++(D& x) BOOST_NOEXCEPT { return x += 1; } Chris@102: friend D& operator--(D& x) BOOST_NOEXCEPT { return x -= 1; } Chris@102: Chris@102: # ifdef BOOST_ENDIAN_MINIMAL_COVER_OPERATORS Chris@102: friend D operator++(D& x, int) BOOST_NOEXCEPT Chris@102: { Chris@102: D tmp(x); Chris@102: x += 1; Chris@102: return tmp; Chris@102: } Chris@102: friend D operator--(D& x, int) BOOST_NOEXCEPT Chris@102: { Chris@102: D tmp(x); Chris@102: x -= 1; Chris@102: return tmp; Chris@102: } Chris@102: # endif Chris@102: Chris@102: # ifndef BOOST_NO_IO_COVER_OPERATORS Chris@102: Chris@102: // Stream inserter Chris@102: template Chris@102: friend std::basic_ostream& Chris@102: operator<<(std::basic_ostream& os, const D& x) Chris@102: { Chris@102: return os << +x; Chris@102: } Chris@102: Chris@102: // Stream extractor Chris@102: template Chris@102: friend std::basic_istream& Chris@102: operator>>(std::basic_istream& is, D& x) Chris@102: { Chris@102: ArithmeticT i; Chris@102: if (is >> i) Chris@102: x = i; Chris@102: return is; Chris@102: } Chris@102: # endif Chris@102: }; Chris@102: } // namespace endian Chris@102: } // namespace boost Chris@102: Chris@102: #if defined(_MSC_VER) Chris@102: # pragma warning(pop) Chris@102: #endif Chris@102: Chris@102: #endif // BOOST_ENDIAN_COVER_OPERATORS_HPP