diff options
Diffstat (limited to 'boost/endian/detail/cover_operators.hpp')
-rw-r--r-- | boost/endian/detail/cover_operators.hpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/boost/endian/detail/cover_operators.hpp b/boost/endian/detail/cover_operators.hpp new file mode 100644 index 0000000000..f4fd052803 --- /dev/null +++ b/boost/endian/detail/cover_operators.hpp @@ -0,0 +1,142 @@ +// 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 |