1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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
|