1// boost/endian/arithmetic.hpp -------------------------------------------------------//
2
3// (C) Copyright Darin Adler 2000
4// (C) Copyright Beman Dawes 2006, 2009, 2014
5// (C) Copyright Peter Dimov 2019
6
7// Distributed under the Boost Software License, Version 1.0.
8// See http://www.boost.org/LICENSE_1_0.txt
9
10// See library home page at http://www.boost.org/libs/endian
11
12//--------------------------------------------------------------------------------------//
13
14// Original design developed by Darin Adler based on classes developed by Mark
15// Borgerding. Four original class templates were combined into a single endian
16// class template by Beman Dawes, who also added the unrolled_byte_loops sign
17// partial specialization to correctly extend the sign when cover integer size
18// differs from endian representation size.
19
20// TODO: When a compiler supporting constexpr becomes available, try possible uses.
21
22#ifndef BOOST_ENDIAN_ARITHMETIC_HPP
23#define BOOST_ENDIAN_ARITHMETIC_HPP
24
25#if defined(_MSC_VER)
26# pragma warning(push)
27# pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
28#endif
29
30#include <boost/endian/buffers.hpp>
31#include <boost/endian/detail/static_assert.hpp>
32#include <boost/config.hpp>
33#include <cstdint>
34#include <iosfwd>
35#include <climits>
36
37#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
38# pragma pack(push, 1)
39#endif
40
41# if CHAR_BIT != 8
42# error Platforms with CHAR_BIT != 8 are not supported
43# endif
44
45# ifndef BOOST_ENDIAN_EXPLICIT_CTORS
46# define BOOST_ENDIAN_EXPLICIT_OPT
47# else
48# define BOOST_ENDIAN_EXPLICIT_OPT explicit
49# endif
50
51//---------------------------------- synopsis ----------------------------------------//
52
53namespace boost
54{
55namespace endian
56{
57
58 template <order Order, class T, std::size_t n_bits,
59 align Align = align::no>
60 class endian_arithmetic;
61
62 // big endian signed integer aligned types
63 typedef endian_arithmetic<order::big, std::int8_t, 8, align::yes> big_int8_at;
64 typedef endian_arithmetic<order::big, std::int16_t, 16, align::yes> big_int16_at;
65 typedef endian_arithmetic<order::big, std::int32_t, 32, align::yes> big_int32_at;
66 typedef endian_arithmetic<order::big, std::int64_t, 64, align::yes> big_int64_at;
67
68 // big endian unsigned integer aligned types
69 typedef endian_arithmetic<order::big, std::uint8_t, 8, align::yes> big_uint8_at;
70 typedef endian_arithmetic<order::big, std::uint16_t, 16, align::yes> big_uint16_at;
71 typedef endian_arithmetic<order::big, std::uint32_t, 32, align::yes> big_uint32_at;
72 typedef endian_arithmetic<order::big, std::uint64_t, 64, align::yes> big_uint64_at;
73
74 // little endian signed integer aligned types
75 typedef endian_arithmetic<order::little, std::int8_t, 8, align::yes> little_int8_at;
76 typedef endian_arithmetic<order::little, std::int16_t, 16, align::yes> little_int16_at;
77 typedef endian_arithmetic<order::little, std::int32_t, 32, align::yes> little_int32_at;
78 typedef endian_arithmetic<order::little, std::int64_t, 64, align::yes> little_int64_at;
79
80 // little endian unsigned integer aligned types
81 typedef endian_arithmetic<order::little, std::uint8_t, 8, align::yes> little_uint8_at;
82 typedef endian_arithmetic<order::little, std::uint16_t, 16, align::yes> little_uint16_at;
83 typedef endian_arithmetic<order::little, std::uint32_t, 32, align::yes> little_uint32_at;
84 typedef endian_arithmetic<order::little, std::uint64_t, 64, align::yes> little_uint64_at;
85
86 // aligned floating point types
87 typedef endian_arithmetic<order::big, float, 32, align::yes> big_float32_at;
88 typedef endian_arithmetic<order::big, double, 64, align::yes> big_float64_at;
89 typedef endian_arithmetic<order::little, float, 32, align::yes> little_float32_at;
90 typedef endian_arithmetic<order::little, double, 64, align::yes> little_float64_at;
91
92 // aligned native endian typedefs are not provided because
93 // <cstdint> types are superior for this use case
94
95 // big endian signed integer unaligned types
96 typedef endian_arithmetic<order::big, std::int_least8_t, 8> big_int8_t;
97 typedef endian_arithmetic<order::big, std::int_least16_t, 16> big_int16_t;
98 typedef endian_arithmetic<order::big, std::int_least32_t, 24> big_int24_t;
99 typedef endian_arithmetic<order::big, std::int_least32_t, 32> big_int32_t;
100 typedef endian_arithmetic<order::big, std::int_least64_t, 40> big_int40_t;
101 typedef endian_arithmetic<order::big, std::int_least64_t, 48> big_int48_t;
102 typedef endian_arithmetic<order::big, std::int_least64_t, 56> big_int56_t;
103 typedef endian_arithmetic<order::big, std::int_least64_t, 64> big_int64_t;
104
105 // big endian unsigned integer unaligned types
106 typedef endian_arithmetic<order::big, std::uint_least8_t, 8> big_uint8_t;
107 typedef endian_arithmetic<order::big, std::uint_least16_t, 16> big_uint16_t;
108 typedef endian_arithmetic<order::big, std::uint_least32_t, 24> big_uint24_t;
109 typedef endian_arithmetic<order::big, std::uint_least32_t, 32> big_uint32_t;
110 typedef endian_arithmetic<order::big, std::uint_least64_t, 40> big_uint40_t;
111 typedef endian_arithmetic<order::big, std::uint_least64_t, 48> big_uint48_t;
112 typedef endian_arithmetic<order::big, std::uint_least64_t, 56> big_uint56_t;
113 typedef endian_arithmetic<order::big, std::uint_least64_t, 64> big_uint64_t;
114
115 // little endian signed integer unaligned types
116 typedef endian_arithmetic<order::little, std::int_least8_t, 8> little_int8_t;
117 typedef endian_arithmetic<order::little, std::int_least16_t, 16> little_int16_t;
118 typedef endian_arithmetic<order::little, std::int_least32_t, 24> little_int24_t;
119 typedef endian_arithmetic<order::little, std::int_least32_t, 32> little_int32_t;
120 typedef endian_arithmetic<order::little, std::int_least64_t, 40> little_int40_t;
121 typedef endian_arithmetic<order::little, std::int_least64_t, 48> little_int48_t;
122 typedef endian_arithmetic<order::little, std::int_least64_t, 56> little_int56_t;
123 typedef endian_arithmetic<order::little, std::int_least64_t, 64> little_int64_t;
124
125 // little endian unsigned integer unaligned types
126 typedef endian_arithmetic<order::little, std::uint_least8_t, 8> little_uint8_t;
127 typedef endian_arithmetic<order::little, std::uint_least16_t, 16> little_uint16_t;
128 typedef endian_arithmetic<order::little, std::uint_least32_t, 24> little_uint24_t;
129 typedef endian_arithmetic<order::little, std::uint_least32_t, 32> little_uint32_t;
130 typedef endian_arithmetic<order::little, std::uint_least64_t, 40> little_uint40_t;
131 typedef endian_arithmetic<order::little, std::uint_least64_t, 48> little_uint48_t;
132 typedef endian_arithmetic<order::little, std::uint_least64_t, 56> little_uint56_t;
133 typedef endian_arithmetic<order::little, std::uint_least64_t, 64> little_uint64_t;
134
135 // native endian signed integer unaligned types
136 typedef endian_arithmetic<order::native, std::int_least8_t, 8> native_int8_t;
137 typedef endian_arithmetic<order::native, std::int_least16_t, 16> native_int16_t;
138 typedef endian_arithmetic<order::native, std::int_least32_t, 24> native_int24_t;
139 typedef endian_arithmetic<order::native, std::int_least32_t, 32> native_int32_t;
140 typedef endian_arithmetic<order::native, std::int_least64_t, 40> native_int40_t;
141 typedef endian_arithmetic<order::native, std::int_least64_t, 48> native_int48_t;
142 typedef endian_arithmetic<order::native, std::int_least64_t, 56> native_int56_t;
143 typedef endian_arithmetic<order::native, std::int_least64_t, 64> native_int64_t;
144
145 // native endian unsigned integer unaligned types
146 typedef endian_arithmetic<order::native, std::uint_least8_t, 8> native_uint8_t;
147 typedef endian_arithmetic<order::native, std::uint_least16_t, 16> native_uint16_t;
148 typedef endian_arithmetic<order::native, std::uint_least32_t, 24> native_uint24_t;
149 typedef endian_arithmetic<order::native, std::uint_least32_t, 32> native_uint32_t;
150 typedef endian_arithmetic<order::native, std::uint_least64_t, 40> native_uint40_t;
151 typedef endian_arithmetic<order::native, std::uint_least64_t, 48> native_uint48_t;
152 typedef endian_arithmetic<order::native, std::uint_least64_t, 56> native_uint56_t;
153 typedef endian_arithmetic<order::native, std::uint_least64_t, 64> native_uint64_t;
154
155 // unaligned floating point types
156 typedef endian_arithmetic<order::big, float, 32, align::no> big_float32_t;
157 typedef endian_arithmetic<order::big, double, 64, align::no> big_float64_t;
158 typedef endian_arithmetic<order::little, float, 32, align::no> little_float32_t;
159 typedef endian_arithmetic<order::little, double, 64, align::no> little_float64_t;
160 typedef endian_arithmetic<order::native, float, 32, align::no> native_float32_t;
161 typedef endian_arithmetic<order::native, double, 64, align::no> native_float64_t;
162
163//---------------------------------- end synopsis ------------------------------------//
164
165template <order Order, class T, std::size_t n_bits,
166 align Align>
167class endian_arithmetic
168{
169private:
170
171 typedef endian_buffer<Order, T, n_bits, Align> buffer_type;
172
173#ifdef BOOST_ENDIAN_NO_CTORS
174public:
175#else
176private:
177#endif
178
179 buffer_type buf_;
180
181public:
182
183 typedef T value_type;
184
185#ifndef BOOST_ENDIAN_NO_CTORS
186
187 endian_arithmetic() = default;
188
189 BOOST_ENDIAN_EXPLICIT_OPT endian_arithmetic( T val ) BOOST_NOEXCEPT: buf_( val )
190 {
191 }
192
193#endif
194
195 endian_arithmetic& operator=( T val ) BOOST_NOEXCEPT
196 {
197 buf_ = val;
198 return *this;
199 }
200
201 value_type value() const BOOST_NOEXCEPT
202 {
203 return buf_.value();
204 }
205
206 unsigned char const * data() const BOOST_NOEXCEPT
207 {
208 return buf_.data();
209 }
210
211 unsigned char * data() BOOST_NOEXCEPT
212 {
213 return buf_.data();
214 }
215
216 operator value_type() const BOOST_NOEXCEPT
217 {
218 return this->value();
219 }
220
221 operator buffer_type& () BOOST_NOEXCEPT
222 {
223 return buf_;
224 }
225
226 operator buffer_type const& () BOOST_NOEXCEPT
227 {
228 return buf_;
229 }
230
231 // operators
232
233 T operator+() const BOOST_NOEXCEPT
234 {
235 return this->value();
236 }
237
238 endian_arithmetic& operator+=( T y ) BOOST_NOEXCEPT
239 {
240 *this = static_cast<T>( this->value() + y );
241 return *this;
242 }
243
244 endian_arithmetic& operator-=( T y ) BOOST_NOEXCEPT
245 {
246 *this = static_cast<T>( this->value() - y );
247 return *this;
248 }
249
250 endian_arithmetic& operator*=( T y ) BOOST_NOEXCEPT
251 {
252 *this = static_cast<T>( this->value() * y );
253 return *this;
254 }
255
256 endian_arithmetic& operator/=( T y ) BOOST_NOEXCEPT
257 {
258 *this = static_cast<T>( this->value() / y );
259 return *this;
260 }
261
262 endian_arithmetic& operator%=( T y ) BOOST_NOEXCEPT
263 {
264 *this = static_cast<T>( this->value() % y );
265 return *this;
266 }
267
268 endian_arithmetic& operator&=( T y ) BOOST_NOEXCEPT
269 {
270 *this = static_cast<T>( this->value() & y );
271 return *this;
272 }
273
274 endian_arithmetic& operator|=( T y ) BOOST_NOEXCEPT
275 {
276 *this = static_cast<T>( this->value() | y );
277 return *this;
278 }
279
280 endian_arithmetic& operator^=( T y ) BOOST_NOEXCEPT
281 {
282 *this = static_cast<T>( this->value() ^ y );
283 return *this;
284 }
285
286 endian_arithmetic& operator<<=( T y ) BOOST_NOEXCEPT
287 {
288 *this = static_cast<T>( this->value() << y );
289 return *this;
290 }
291
292 endian_arithmetic& operator>>=( T y ) BOOST_NOEXCEPT
293 {
294 *this = static_cast<T>( this->value() >> y );
295 return *this;
296 }
297
298 endian_arithmetic& operator++() BOOST_NOEXCEPT
299 {
300 *this += 1;
301 return *this;
302 }
303
304 endian_arithmetic& operator--() BOOST_NOEXCEPT
305 {
306 *this -= 1;
307 return *this;
308 }
309
310 endian_arithmetic operator++(int) BOOST_NOEXCEPT
311 {
312 endian_arithmetic tmp( *this );
313 *this += 1;
314 return tmp;
315 }
316
317 endian_arithmetic operator--(int) BOOST_NOEXCEPT
318 {
319 endian_arithmetic tmp( *this );
320 *this -= 1;
321 return tmp;
322 }
323
324 template<class Ch, class Tr>
325 friend std::basic_ostream<Ch, Tr>&
326 operator<<( std::basic_ostream<Ch, Tr>& os, endian_arithmetic const& x )
327 {
328 return os << x.value();
329 }
330
331 template<class Ch, class Tr>
332 friend std::basic_istream<Ch, Tr>&
333 operator>>( std::basic_istream<Ch, Tr>& is, endian_arithmetic& x )
334 {
335 T i;
336
337 if( is >> i )
338 {
339 x = i;
340 }
341
342 return is;
343 }
344};
345
346} // namespace endian
347} // namespace boost
348
349#if defined(BOOST_BORLANDC) || defined(BOOST_CODEGEARC)
350# pragma pack(pop)
351#endif
352
353#if defined(_MSC_VER)
354# pragma warning(pop)
355#endif
356
357#endif // BOOST_ENDIAN_ARITHMETIC_HPP
358

source code of boost/libs/endian/include/boost/endian/arithmetic.hpp