]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/endian/conversion.hpp
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / boost / boost / endian / conversion.hpp
1 // boost/endian/conversion.hpp -------------------------------------------------------//
2
3 // Copyright Beman Dawes 2010, 2011, 2014
4
5 // Distributed under the Boost Software License, Version 1.0.
6 // http://www.boost.org/LICENSE_1_0.txt
7
8 #ifndef BOOST_ENDIAN_CONVERSION_HPP
9 #define BOOST_ENDIAN_CONVERSION_HPP
10
11 #include <boost/endian/detail/endian_reverse.hpp>
12 #include <boost/endian/detail/endian_load.hpp>
13 #include <boost/endian/detail/endian_store.hpp>
14 #include <boost/endian/detail/order.hpp>
15 #include <boost/type_traits/is_class.hpp>
16 #include <boost/type_traits/is_array.hpp>
17 #include <boost/type_traits/integral_constant.hpp>
18 #include <boost/static_assert.hpp>
19 #include <boost/cstdint.hpp>
20 #include <boost/config.hpp>
21
22 //------------------------------------- synopsis ---------------------------------------//
23
24 namespace boost
25 {
26 namespace endian
27 {
28
29 //--------------------------------------------------------------------------------------//
30 // //
31 // return-by-value interfaces //
32 // suggested by Phil Endecott //
33 // //
34 // user-defined types (UDTs) //
35 // //
36 // All return-by-value conversion function templates are required to be implemented in //
37 // terms of an unqualified call to "endian_reverse(x)", a function returning the //
38 // value of x with endianness reversed. This provides a customization point for any //
39 // UDT that provides a "endian_reverse" free-function meeting the requirements. //
40 // It must be defined in the same namespace as the UDT itself so that it will be found //
41 // by argument dependent lookup (ADL). //
42 // //
43 //--------------------------------------------------------------------------------------//
44
45 // reverse byte order
46 // requires T to be a non-bool integral type
47 // in detail/endian_reverse.hpp
48 //
49 // template<class T> inline BOOST_CONSTEXPR T endian_reverse( T x ) BOOST_NOEXCEPT;
50
51 // reverse byte order unless native endianness is big
52 template <class EndianReversible >
53 inline BOOST_CONSTEXPR EndianReversible big_to_native(EndianReversible x) BOOST_NOEXCEPT;
54 // Returns: x if native endian order is big, otherwise endian_reverse(x)
55 template <class EndianReversible >
56 inline BOOST_CONSTEXPR EndianReversible native_to_big(EndianReversible x) BOOST_NOEXCEPT;
57 // Returns: x if native endian order is big, otherwise endian_reverse(x)
58
59 // reverse byte order unless native endianness is little
60 template <class EndianReversible >
61 inline BOOST_CONSTEXPR EndianReversible little_to_native(EndianReversible x) BOOST_NOEXCEPT;
62 // Returns: x if native endian order is little, otherwise endian_reverse(x)
63 template <class EndianReversible >
64 inline BOOST_CONSTEXPR EndianReversible native_to_little(EndianReversible x) BOOST_NOEXCEPT;
65 // Returns: x if native endian order is little, otherwise endian_reverse(x)
66
67 // generic conditional reverse byte order
68 template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
69 class EndianReversible>
70 inline BOOST_CONSTEXPR EndianReversible conditional_reverse(EndianReversible from) BOOST_NOEXCEPT;
71 // Returns: If From == To have different values, from.
72 // Otherwise endian_reverse(from).
73 // Remarks: The From == To test, and as a consequence which form the return takes, is
74 // is determined at compile time.
75
76 // runtime conditional reverse byte order
77 template <class EndianReversible >
78 inline BOOST_CONSTEXPR EndianReversible conditional_reverse(EndianReversible from,
79 BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
80 BOOST_NOEXCEPT;
81 // Returns: from_order == to_order ? from : endian_reverse(from).
82
83 //------------------------------------------------------------------------------------//
84
85
86 // Q: What happened to bswap, htobe, and the other synonym functions based on names
87 // popularized by BSD, OS X, and Linux?
88 // A: Turned out these may be implemented as macros on some systems. Ditto POSIX names
89 // for such functionality. Since macros would cause endless problems with functions
90 // of the same names, and these functions are just synonyms anyhow, they have been
91 // removed.
92
93
94 //------------------------------------------------------------------------------------//
95 // //
96 // reverse in place interfaces //
97 // //
98 // user-defined types (UDTs) //
99 // //
100 // All reverse in place function templates are required to be implemented in terms //
101 // of an unqualified call to "endian_reverse_inplace(x)", a function reversing //
102 // the endianness of x, which is a non-const reference. This provides a //
103 // customization point for any UDT that provides a "reverse_inplace" free-function //
104 // meeting the requirements. The free-function must be declared in the same //
105 // namespace as the UDT itself so that it will be found by argument-dependent //
106 // lookup (ADL). //
107 // //
108 //------------------------------------------------------------------------------------//
109
110 // reverse in place
111 // in detail/endian_reverse.hpp
112 //
113 // template <class EndianReversible>
114 // inline void endian_reverse_inplace(EndianReversible& x) BOOST_NOEXCEPT;
115 //
116 // Effects: x = endian_reverse(x)
117
118 // reverse in place unless native endianness is big
119 template <class EndianReversibleInplace>
120 inline void big_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
121 // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
122 template <class EndianReversibleInplace>
123 inline void native_to_big_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
124 // Effects: none if native byte-order is big, otherwise endian_reverse_inplace(x)
125
126 // reverse in place unless native endianness is little
127 template <class EndianReversibleInplace>
128 inline void little_to_native_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
129 // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
130 template <class EndianReversibleInplace>
131 inline void native_to_little_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
132 // Effects: none if native byte-order is little, otherwise endian_reverse_inplace(x);
133
134 // generic conditional reverse in place
135 template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To,
136 class EndianReversibleInplace>
137 inline void conditional_reverse_inplace(EndianReversibleInplace& x) BOOST_NOEXCEPT;
138
139 // runtime reverse in place
140 template <class EndianReversibleInplace>
141 inline void conditional_reverse_inplace(EndianReversibleInplace& x,
142 BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order)
143 BOOST_NOEXCEPT;
144
145 //----------------------------------- end synopsis -------------------------------------//
146
147 template <class EndianReversible>
148 inline BOOST_CONSTEXPR EndianReversible big_to_native( EndianReversible x ) BOOST_NOEXCEPT
149 {
150 return boost::endian::conditional_reverse<order::big, order::native>( x );
151 }
152
153 template <class EndianReversible>
154 inline BOOST_CONSTEXPR EndianReversible native_to_big( EndianReversible x ) BOOST_NOEXCEPT
155 {
156 return boost::endian::conditional_reverse<order::native, order::big>( x );
157 }
158
159 template <class EndianReversible>
160 inline BOOST_CONSTEXPR EndianReversible little_to_native( EndianReversible x ) BOOST_NOEXCEPT
161 {
162 return boost::endian::conditional_reverse<order::little, order::native>( x );
163 }
164
165 template <class EndianReversible>
166 inline BOOST_CONSTEXPR EndianReversible native_to_little( EndianReversible x ) BOOST_NOEXCEPT
167 {
168 return boost::endian::conditional_reverse<order::native, order::little>( x );
169 }
170
171 namespace detail
172 {
173
174 template<class EndianReversible>
175 inline BOOST_CONSTEXPR EndianReversible conditional_reverse_impl( EndianReversible x, boost::true_type ) BOOST_NOEXCEPT
176 {
177 return x;
178 }
179
180 template<class EndianReversible>
181 inline BOOST_CONSTEXPR EndianReversible conditional_reverse_impl( EndianReversible x, boost::false_type ) BOOST_NOEXCEPT
182 {
183 return endian_reverse( x );
184 }
185
186 } // namespace detail
187
188 // generic conditional reverse
189 template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class EndianReversible>
190 inline BOOST_CONSTEXPR EndianReversible conditional_reverse( EndianReversible x ) BOOST_NOEXCEPT
191 {
192 BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
193 return detail::conditional_reverse_impl( x, boost::integral_constant<bool, From == To>() );
194 }
195
196 // runtime conditional reverse
197 template <class EndianReversible>
198 inline BOOST_CONSTEXPR EndianReversible conditional_reverse( EndianReversible x,
199 BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order ) BOOST_NOEXCEPT
200 {
201 BOOST_STATIC_ASSERT( boost::is_class<EndianReversible>::value || detail::is_endian_reversible<EndianReversible>::value );
202 return from_order == to_order? x: endian_reverse( x );
203 }
204
205 //--------------------------------------------------------------------------------------//
206 // reverse-in-place implementation //
207 //--------------------------------------------------------------------------------------//
208
209 template <class EndianReversibleInplace>
210 inline void big_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
211 {
212 boost::endian::conditional_reverse_inplace<order::big, order::native>( x );
213 }
214
215 template <class EndianReversibleInplace>
216 inline void native_to_big_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
217 {
218 boost::endian::conditional_reverse_inplace<order::native, order::big>( x );
219 }
220
221 template <class EndianReversibleInplace>
222 inline void little_to_native_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
223 {
224 boost::endian::conditional_reverse_inplace<order::little, order::native>( x );
225 }
226
227 template <class EndianReversibleInplace>
228 inline void native_to_little_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
229 {
230 boost::endian::conditional_reverse_inplace<order::native, order::little>( x );
231 }
232
233 namespace detail
234 {
235
236 template<class EndianReversibleInplace>
237 inline void conditional_reverse_inplace_impl( EndianReversibleInplace&, boost::true_type ) BOOST_NOEXCEPT
238 {
239 }
240
241 template<class EndianReversibleInplace>
242 inline void conditional_reverse_inplace_impl( EndianReversibleInplace& x, boost::false_type ) BOOST_NOEXCEPT
243 {
244 endian_reverse_inplace( x );
245 }
246
247 } // namespace detail
248
249 // generic conditional reverse in place
250 template <BOOST_SCOPED_ENUM(order) From, BOOST_SCOPED_ENUM(order) To, class EndianReversibleInplace>
251 inline void conditional_reverse_inplace( EndianReversibleInplace& x ) BOOST_NOEXCEPT
252 {
253 BOOST_STATIC_ASSERT(
254 boost::is_class<EndianReversibleInplace>::value ||
255 boost::is_array<EndianReversibleInplace>::value ||
256 detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
257
258 detail::conditional_reverse_inplace_impl( x, boost::integral_constant<bool, From == To>() );
259 }
260
261 // runtime reverse in place
262 template <class EndianReversibleInplace>
263 inline void conditional_reverse_inplace( EndianReversibleInplace& x,
264 BOOST_SCOPED_ENUM(order) from_order, BOOST_SCOPED_ENUM(order) to_order ) BOOST_NOEXCEPT
265 {
266 BOOST_STATIC_ASSERT(
267 boost::is_class<EndianReversibleInplace>::value ||
268 boost::is_array<EndianReversibleInplace>::value ||
269 detail::is_endian_reversible_inplace<EndianReversibleInplace>::value );
270
271 if( from_order != to_order )
272 {
273 endian_reverse_inplace( x );
274 }
275 }
276
277 // load/store convenience functions
278
279 // load 16
280
281 inline boost::int16_t load_little_s16( unsigned char const * p ) BOOST_NOEXCEPT
282 {
283 return boost::endian::endian_load<boost::int16_t, 2, order::little>( p );
284 }
285
286 inline boost::uint16_t load_little_u16( unsigned char const * p ) BOOST_NOEXCEPT
287 {
288 return boost::endian::endian_load<boost::uint16_t, 2, order::little>( p );
289 }
290
291 inline boost::int16_t load_big_s16( unsigned char const * p ) BOOST_NOEXCEPT
292 {
293 return boost::endian::endian_load<boost::int16_t, 2, order::big>( p );
294 }
295
296 inline boost::uint16_t load_big_u16( unsigned char const * p ) BOOST_NOEXCEPT
297 {
298 return boost::endian::endian_load<boost::uint16_t, 2, order::big>( p );
299 }
300
301 // load 24
302
303 inline boost::int32_t load_little_s24( unsigned char const * p ) BOOST_NOEXCEPT
304 {
305 return boost::endian::endian_load<boost::int32_t, 3, order::little>( p );
306 }
307
308 inline boost::uint32_t load_little_u24( unsigned char const * p ) BOOST_NOEXCEPT
309 {
310 return boost::endian::endian_load<boost::uint32_t, 3, order::little>( p );
311 }
312
313 inline boost::int32_t load_big_s24( unsigned char const * p ) BOOST_NOEXCEPT
314 {
315 return boost::endian::endian_load<boost::int32_t, 3, order::big>( p );
316 }
317
318 inline boost::uint32_t load_big_u24( unsigned char const * p ) BOOST_NOEXCEPT
319 {
320 return boost::endian::endian_load<boost::uint32_t, 3, order::big>( p );
321 }
322
323 // load 32
324
325 inline boost::int32_t load_little_s32( unsigned char const * p ) BOOST_NOEXCEPT
326 {
327 return boost::endian::endian_load<boost::int32_t, 4, order::little>( p );
328 }
329
330 inline boost::uint32_t load_little_u32( unsigned char const * p ) BOOST_NOEXCEPT
331 {
332 return boost::endian::endian_load<boost::uint32_t, 4, order::little>( p );
333 }
334
335 inline boost::int32_t load_big_s32( unsigned char const * p ) BOOST_NOEXCEPT
336 {
337 return boost::endian::endian_load<boost::int32_t, 4, order::big>( p );
338 }
339
340 inline boost::uint32_t load_big_u32( unsigned char const * p ) BOOST_NOEXCEPT
341 {
342 return boost::endian::endian_load<boost::uint32_t, 4, order::big>( p );
343 }
344
345 // load 40
346
347 inline boost::int64_t load_little_s40( unsigned char const * p ) BOOST_NOEXCEPT
348 {
349 return boost::endian::endian_load<boost::int64_t, 5, order::little>( p );
350 }
351
352 inline boost::uint64_t load_little_u40( unsigned char const * p ) BOOST_NOEXCEPT
353 {
354 return boost::endian::endian_load<boost::uint64_t, 5, order::little>( p );
355 }
356
357 inline boost::int64_t load_big_s40( unsigned char const * p ) BOOST_NOEXCEPT
358 {
359 return boost::endian::endian_load<boost::int64_t, 5, order::big>( p );
360 }
361
362 inline boost::uint64_t load_big_u40( unsigned char const * p ) BOOST_NOEXCEPT
363 {
364 return boost::endian::endian_load<boost::uint64_t, 5, order::big>( p );
365 }
366
367 // load 48
368
369 inline boost::int64_t load_little_s48( unsigned char const * p ) BOOST_NOEXCEPT
370 {
371 return boost::endian::endian_load<boost::int64_t, 6, order::little>( p );
372 }
373
374 inline boost::uint64_t load_little_u48( unsigned char const * p ) BOOST_NOEXCEPT
375 {
376 return boost::endian::endian_load<boost::uint64_t, 6, order::little>( p );
377 }
378
379 inline boost::int64_t load_big_s48( unsigned char const * p ) BOOST_NOEXCEPT
380 {
381 return boost::endian::endian_load<boost::int64_t, 6, order::big>( p );
382 }
383
384 inline boost::uint64_t load_big_u48( unsigned char const * p ) BOOST_NOEXCEPT
385 {
386 return boost::endian::endian_load<boost::uint64_t, 6, order::big>( p );
387 }
388
389 // load 56
390
391 inline boost::int64_t load_little_s56( unsigned char const * p ) BOOST_NOEXCEPT
392 {
393 return boost::endian::endian_load<boost::int64_t, 7, order::little>( p );
394 }
395
396 inline boost::uint64_t load_little_u56( unsigned char const * p ) BOOST_NOEXCEPT
397 {
398 return boost::endian::endian_load<boost::uint64_t, 7, order::little>( p );
399 }
400
401 inline boost::int64_t load_big_s56( unsigned char const * p ) BOOST_NOEXCEPT
402 {
403 return boost::endian::endian_load<boost::int64_t, 7, order::big>( p );
404 }
405
406 inline boost::uint64_t load_big_u56( unsigned char const * p ) BOOST_NOEXCEPT
407 {
408 return boost::endian::endian_load<boost::uint64_t, 7, order::big>( p );
409 }
410
411 // load 64
412
413 inline boost::int64_t load_little_s64( unsigned char const * p ) BOOST_NOEXCEPT
414 {
415 return boost::endian::endian_load<boost::int64_t, 8, order::little>( p );
416 }
417
418 inline boost::uint64_t load_little_u64( unsigned char const * p ) BOOST_NOEXCEPT
419 {
420 return boost::endian::endian_load<boost::uint64_t, 8, order::little>( p );
421 }
422
423 inline boost::int64_t load_big_s64( unsigned char const * p ) BOOST_NOEXCEPT
424 {
425 return boost::endian::endian_load<boost::int64_t, 8, order::big>( p );
426 }
427
428 inline boost::uint64_t load_big_u64( unsigned char const * p ) BOOST_NOEXCEPT
429 {
430 return boost::endian::endian_load<boost::uint64_t, 8, order::big>( p );
431 }
432
433 // store 16
434
435 inline void store_little_s16( unsigned char * p, boost::int16_t v )
436 {
437 boost::endian::endian_store<boost::int16_t, 2, order::little>( p, v );
438 }
439
440 inline void store_little_u16( unsigned char * p, boost::uint16_t v )
441 {
442 boost::endian::endian_store<boost::uint16_t, 2, order::little>( p, v );
443 }
444
445 inline void store_big_s16( unsigned char * p, boost::int16_t v )
446 {
447 boost::endian::endian_store<boost::int16_t, 2, order::big>( p, v );
448 }
449
450 inline void store_big_u16( unsigned char * p, boost::uint16_t v )
451 {
452 boost::endian::endian_store<boost::uint16_t, 2, order::big>( p, v );
453 }
454
455 // store 24
456
457 inline void store_little_s24( unsigned char * p, boost::int32_t v )
458 {
459 boost::endian::endian_store<boost::int32_t, 3, order::little>( p, v );
460 }
461
462 inline void store_little_u24( unsigned char * p, boost::uint32_t v )
463 {
464 boost::endian::endian_store<boost::uint32_t, 3, order::little>( p, v );
465 }
466
467 inline void store_big_s24( unsigned char * p, boost::int32_t v )
468 {
469 boost::endian::endian_store<boost::int32_t, 3, order::big>( p, v );
470 }
471
472 inline void store_big_u24( unsigned char * p, boost::uint32_t v )
473 {
474 boost::endian::endian_store<boost::uint32_t, 3, order::big>( p, v );
475 }
476
477 // store 32
478
479 inline void store_little_s32( unsigned char * p, boost::int32_t v )
480 {
481 boost::endian::endian_store<boost::int32_t, 4, order::little>( p, v );
482 }
483
484 inline void store_little_u32( unsigned char * p, boost::uint32_t v )
485 {
486 boost::endian::endian_store<boost::uint32_t, 4, order::little>( p, v );
487 }
488
489 inline void store_big_s32( unsigned char * p, boost::int32_t v )
490 {
491 boost::endian::endian_store<boost::int32_t, 4, order::big>( p, v );
492 }
493
494 inline void store_big_u32( unsigned char * p, boost::uint32_t v )
495 {
496 boost::endian::endian_store<boost::uint32_t, 4, order::big>( p, v );
497 }
498
499 // store 40
500
501 inline void store_little_s40( unsigned char * p, boost::int64_t v )
502 {
503 boost::endian::endian_store<boost::int64_t, 5, order::little>( p, v );
504 }
505
506 inline void store_little_u40( unsigned char * p, boost::uint64_t v )
507 {
508 boost::endian::endian_store<boost::uint64_t, 5, order::little>( p, v );
509 }
510
511 inline void store_big_s40( unsigned char * p, boost::int64_t v )
512 {
513 boost::endian::endian_store<boost::int64_t, 5, order::big>( p, v );
514 }
515
516 inline void store_big_u40( unsigned char * p, boost::uint64_t v )
517 {
518 boost::endian::endian_store<boost::uint64_t, 5, order::big>( p, v );
519 }
520
521 // store 48
522
523 inline void store_little_s48( unsigned char * p, boost::int64_t v )
524 {
525 boost::endian::endian_store<boost::int64_t, 6, order::little>( p, v );
526 }
527
528 inline void store_little_u48( unsigned char * p, boost::uint64_t v )
529 {
530 boost::endian::endian_store<boost::uint64_t, 6, order::little>( p, v );
531 }
532
533 inline void store_big_s48( unsigned char * p, boost::int64_t v )
534 {
535 boost::endian::endian_store<boost::int64_t, 6, order::big>( p, v );
536 }
537
538 inline void store_big_u48( unsigned char * p, boost::uint64_t v )
539 {
540 boost::endian::endian_store<boost::uint64_t, 6, order::big>( p, v );
541 }
542
543 // store 56
544
545 inline void store_little_s56( unsigned char * p, boost::int64_t v )
546 {
547 boost::endian::endian_store<boost::int64_t, 7, order::little>( p, v );
548 }
549
550 inline void store_little_u56( unsigned char * p, boost::uint64_t v )
551 {
552 boost::endian::endian_store<boost::uint64_t, 7, order::little>( p, v );
553 }
554
555 inline void store_big_s56( unsigned char * p, boost::int64_t v )
556 {
557 boost::endian::endian_store<boost::int64_t, 7, order::big>( p, v );
558 }
559
560 inline void store_big_u56( unsigned char * p, boost::uint64_t v )
561 {
562 boost::endian::endian_store<boost::uint64_t, 7, order::big>( p, v );
563 }
564
565 // store 64
566
567 inline void store_little_s64( unsigned char * p, boost::int64_t v )
568 {
569 boost::endian::endian_store<boost::int64_t, 8, order::little>( p, v );
570 }
571
572 inline void store_little_u64( unsigned char * p, boost::uint64_t v )
573 {
574 boost::endian::endian_store<boost::uint64_t, 8, order::little>( p, v );
575 }
576
577 inline void store_big_s64( unsigned char * p, boost::int64_t v )
578 {
579 boost::endian::endian_store<boost::int64_t, 8, order::big>( p, v );
580 }
581
582 inline void store_big_u64( unsigned char * p, boost::uint64_t v )
583 {
584 boost::endian::endian_store<boost::uint64_t, 8, order::big>( p, v );
585 }
586
587 } // namespace endian
588 } // namespace boost
589
590 #endif // BOOST_ENDIAN_CONVERSION_HPP