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