|
Embedded Artistry Framework
Embedded Systems C++ Framework
|
Functions that can be used to swap the endianness of a value. More...
|
Functions | |
| template<class T > | |
| constexpr std::enable_if< std::is_unsigned< T >::value, T >::type | embutil::byteswap (T i, T j=0u, std::size_t n=0u) noexcept |
| Recursive constexpr byteswap implementation without C++17 fold expressions. More... | |
| template<typename T > | |
| void | embutil::SwapEndian (T &val, typename std::enable_if< std::is_arithmetic< T >::value, std::nullptr_t >::type unused=nullptr) noexcept |
| Non-constexpr Robust Endian Swap. More... | |
| template<typename T > | |
| void | embutil::SwapEndian_UB (T &val) noexcept |
| Endian swap using undefined behavior. More... | |
Functions that can be used to swap the endianness of a value.
|
noexcept |
Recursive constexpr byteswap implementation without C++17 fold expressions.
Specialized implementations can be defined for specific types if desired. Example of template specialization for a specific type:
| T | The type of the value being byteswap'd. This is (typically) deduced by the compiler. |
| i | The value to byteswap. |
| j | Used in the recursive calculation; users should not set this. |
| n | Used in the recursive calculation; users shoudl not set this. |
References CHAR_BIT, n, and T.
Referenced by embdrv::vl53l1x::readTrim(), and embdrv::vl53l1x::writeReg().
|
noexcept |
Non-constexpr Robust Endian Swap.
Described here: https://mklimenko.github.io/english/2018/08/22/robust-endian-swap/ This approach avoids bitmasks/shifts and intrinsics, which can be non-portable and error prone
The idea is simple: we define a template function, in which there is a union, containing both the passed value and the std::array of the corresponding size. We create two objects of such union and perform the reverse copying from one to another. All the extra assignments will be optimized out by the compiler, which will make this code fast and efficient.
We use the SFINAE-d version to make sure you won’t pass anything wrong
The good thing about this is that we have a template for all the corner cases and possible types. But the greatest is that the compiler was able to optimize both of these functions into one assembly command bswap. Some instructions sets haven’t got that command and if this will become the bottleneck of your program, you can make a template specialization for the case you need.
| T | Type of integer to perform the swap on. This value is (typically) deduced by the compiler. |
| val | The value to perform an endian swap on. |
| unused | An unused parameter, present for use with std::enable_if. |
References T.
|
noexcept |
Endian swap using undefined behavior.
Original version of SwapEndian(). The undefined behavior is due to the use of an inactive member of the union. This function is efficient, but the undefined behavior makes it risky.
| T | Type of integer to perform the swap on. This value is (typically) deduced by the compiler. |
| val | The value to perform an endian swpa on. |
References T.
1.8.15