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