Endianness is very simple, light, header-only library designed to reduce conversions between big-endian and little-endian data.
- Requires STL C++17
Endianness library can be built and installed as any other cmake project. After that add to your CMake project file CMakeLists.txt
:
find_package(Endianness)
And link to your target imported target ENDIAN::Endian
target_link_libraries(<target> ENDIAN::Endian)
If you prefer submodule instead of install add to your CMakeLists.txt
add_subdirectory(<Endianness source realative path>)
target_link_libraries(<target> ENDIAN::Endian)
With happy debugging on MSVS you can use Endian.natvis
This natvis
file can swap bytes of big-endian data for better view.
- You can use the
Endian
inconstexpr
- It is possible to use the
Endian
as a key in unordered associative containers. Avoid to use with containers that need the less operator for comparision - only==
and!=
operators have no byte swap. - Not necessary, but useful aliases:
#include <endianness.h>
#include <stdint.h>
using int16le = endianness::LittleEndian<int16_t>;
using uint16le = endianness::LittleEndian<uint16_t>;
using int32le = endianness::LittleEndian<int32_t>;
using uint32le = endianness::LittleEndian<uint32_t>;
using int64le = endianness::LittleEndian<int64_t>;
using uint64le = endianness::LittleEndian<uint64_t>;
using int16be = endianness::BigEndian<int16_t>;
using uint16be = endianness::BigEndian<uint16_t>;
using int32be = endianness::BigEndian<int32_t>;
using uint32be = endianness::BigEndian<uint32_t>;
using int64be = endianness::BigEndian<int64_t>;
using uint64be = endianness::BigEndian<uint64_t>;
- No byte swap type conversion:
constexpr uint32be MASK = 0xF0F01234; //Compile-time expressions
#pragma pack(push, 1)
struct FileHeader
{
static constexpr uint32be SIGNATURE = 'A123'; //Compile-time expressions
uint32be signature;
uint32be tag;
};
#pragma pop()
...
std::unordered_set<uint32be> tags{'qwer','tyui','opas','dfgh'};
std::unordered_map<uint32be, int> hashmap;
auto fileHeader = reinterpret_cast<const FileHeader*>(pointer);
if (fileHeader && fileHeader->signature == FileHeader::SIGNATURE){
uint32be tag = fileHeader->tag;
if(tags.count(tag)){
tag &= MASK;
++hashmap[tag];
}
}
- With byte swap:
// no byte swap on big-endian platform
uint16be a = 7;
uint32be b = a;// uint16be -> uint16_t -> uint32_t -> uint32be
int c = a + b;
bool d = (a < 32) // ok: uint16be -> uint16_t : d = true
//bool e = (a != 3) // error: need explicitly cast a to int or 3 to uint16be
bool e = (a != (uint16be)3) // ok: e = true