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