Loading...
Searching...
No Matches
Endian.h
Go to the documentation of this file.
1#ifndef _BBM_ENDIAN_H_
2#define _BBM_ENDIAN_H_
3
4#include <utility>
5#include <cstdint>
6
7/***********************************************************************/
8/*! \file Endian.h
9 \brief Detect Endianess of processor and conversion methods
10************************************************************************/
11
12namespace bbm {
13 namespace endian {
14
15 /*** Implementation Details ***/
16 namespace detail {
17 //! \brief Union to determine the Endianess.
18 union magicNumberType
19 {
20 inline constexpr magicNumberType(void) : value16(1) {}
21
22 uint16_t value16;
23 uint8_t value8[2];
24 };
25
26 //! \brief Flag indicating whether the processor is little Endian
27 static const bool _isLittleEndian = (magicNumberType().value8[0] == 1);
28
29 //! \brief Helper method to swap the order from little to big or vice versa
30 template<typename T>
31 inline T swapOrder(const T& value)
32 {
33 // init
34 T result;
35
36 // get pointers
37 void* result_p = static_cast<void*>(&result);
38 const void* value_p = static_cast<const void*>(&value);
39
40 const uint8_t* valueItr = static_cast<const uint8_t*>(value_p) + sizeof(T) - 1;
41 uint8_t* resultItr = static_cast<uint8_t*>(result_p);
42 uint8_t* resultEnd = resultItr + sizeof(T);
43
44 // swap order
45 for(; resultItr != resultEnd; valueItr--, resultItr++)
46 *resultItr = *valueItr;
47
48 // done.
49 return result;
50 }
51 } // end detail namespace
52
53
54 //! @{ \name determine Endianess
55 static const bool isLittleEndian = detail::_isLittleEndian;
56 static const bool isBigEndian = !detail::_isLittleEndian;
57 //! @}
58
59
60 //! @{ \name Convert to Little Endian <=> Machine Representation
61 template<typename T>
62 inline T little(const T& value)
63 {
64 if(isLittleEndian) return value;
65 else return detail::swapOrder(value);
66 }
67
68 template<typename Iterator>
69 inline void little(const Iterator& begin, const Iterator& end)
70 {
71 if(isLittleEndian) return;
72 for(Iterator itr=begin; itr != end; ++itr)
73 *itr = detail::swapOrder(*itr);
74 }
75 //! @}
76
77
78 //! @{ \name Convert Big Endian <=> Machine Representation
79 template<typename T>
80 inline T big(const T& value)
81 {
82 if(isBigEndian) return value;
83 else return detail::swapOrder(value);
84 }
85
86 template<typename Iterator>
87 inline void big(const Iterator& begin, const Iterator& end)
88 {
89 if(isBigEndian) return;
90 for(Iterator itr=begin; itr != end; ++itr)
91 *itr = detail::swapOrder(*itr);
92 }
93 //! @}
94
95 } // end endian namespace
96} // end bbm namespace
97
98#endif /* _BBM_ENDIAN_H_ */
static const bool isBigEndian
Definition: Endian.h:56
static const bool isLittleEndian
Definition: Endian.h:55
T big(const T &value)
Definition: Endian.h:80
T little(const T &value)
Definition: Endian.h:62
Definition: aggregatebsdf.h:29
auto end(T &&t)
Definition: iterator_util.h:43
auto begin(T &&t)
Definition: iterator_util.h:29
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20