mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-03 03:01:44 +00:00
[wpiutil] Remove bit.hpp; replace with C++23 bit (#8792)
#7492 didn't catch all the uses and #7973 patched out byteswap in Sleipnir for some reason (despite having upgraded compilers already)?
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <bit>
|
||||
#include <cassert>
|
||||
#include <span>
|
||||
#include <string>
|
||||
@@ -14,7 +15,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "wpi/util/StringMap.hpp"
|
||||
#include "wpi/util/bit.hpp"
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
@@ -457,7 +457,7 @@ class DynamicStruct {
|
||||
float GetFloatField(const StructFieldDescriptor* field,
|
||||
size_t arrIndex = 0) const {
|
||||
assert(field->m_type == StructFieldType::FLOAT);
|
||||
return bit_cast<float>(
|
||||
return std::bit_cast<float>(
|
||||
static_cast<uint32_t>(GetFieldImpl(field, arrIndex)));
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ class DynamicStruct {
|
||||
double GetDoubleField(const StructFieldDescriptor* field,
|
||||
size_t arrIndex = 0) const {
|
||||
assert(field->m_type == StructFieldType::DOUBLE);
|
||||
return bit_cast<double>(GetFieldImpl(field, arrIndex));
|
||||
return std::bit_cast<double>(GetFieldImpl(field, arrIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -591,7 +591,7 @@ class MutableDynamicStruct : public DynamicStruct {
|
||||
void SetFloatField(const StructFieldDescriptor* field, float value,
|
||||
size_t arrIndex = 0) {
|
||||
assert(field->m_type == StructFieldType::FLOAT);
|
||||
SetFieldImpl(field, bit_cast<uint32_t>(value), arrIndex);
|
||||
SetFieldImpl(field, std::bit_cast<uint32_t>(value), arrIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -604,7 +604,7 @@ class MutableDynamicStruct : public DynamicStruct {
|
||||
void SetDoubleField(const StructFieldDescriptor* field, double value,
|
||||
size_t arrIndex = 0) {
|
||||
assert(field->m_type == StructFieldType::DOUBLE);
|
||||
SetFieldImpl(field, bit_cast<uint64_t>(value), arrIndex);
|
||||
SetFieldImpl(field, std::bit_cast<uint64_t>(value), arrIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <bit>
|
||||
#include <concepts>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
@@ -19,7 +20,6 @@
|
||||
|
||||
#include "wpi/util/Endian.hpp"
|
||||
#include "wpi/util/array.hpp"
|
||||
#include "wpi/util/bit.hpp"
|
||||
#include "wpi/util/ct_string.hpp"
|
||||
#include "wpi/util/function_ref.hpp"
|
||||
#include "wpi/util/mutex.hpp"
|
||||
@@ -687,10 +687,10 @@ struct Struct<float> {
|
||||
static constexpr size_t GetSize() { return 4; }
|
||||
static constexpr std::string_view GetSchema() { return "float value"; }
|
||||
static float Unpack(std::span<const uint8_t> data) {
|
||||
return bit_cast<float>(support::endian::read32le(data.data()));
|
||||
return std::bit_cast<float>(support::endian::read32le(data.data()));
|
||||
}
|
||||
static void Pack(std::span<uint8_t> data, float value) {
|
||||
support::endian::write32le(data.data(), bit_cast<uint32_t>(value));
|
||||
support::endian::write32le(data.data(), std::bit_cast<uint32_t>(value));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -704,10 +704,10 @@ struct Struct<double> {
|
||||
static constexpr size_t GetSize() { return 8; }
|
||||
static constexpr std::string_view GetSchema() { return "double value"; }
|
||||
static double Unpack(std::span<const uint8_t> data) {
|
||||
return bit_cast<double>(support::endian::read64le(data.data()));
|
||||
return std::bit_cast<double>(support::endian::read64le(data.data()));
|
||||
}
|
||||
static void Pack(std::span<uint8_t> data, double value) {
|
||||
support::endian::write64le(data.data(), bit_cast<uint64_t>(value));
|
||||
support::endian::write64le(data.data(), std::bit_cast<uint64_t>(value));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "wpi/util/ConvertUTF.hpp"
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
#include "wpi/util/ErrorHandling.hpp"
|
||||
#include "wpi/util/SwapByteOrder.hpp"
|
||||
#include <bit>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@@ -103,7 +103,7 @@ bool convertUTF16ToUTF8String(std::span<const char> SrcBytes, SmallVectorImpl<ch
|
||||
if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
|
||||
ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
|
||||
for (UTF16 &I : ByteSwapped)
|
||||
I = wpi::util::byteswap<uint16_t>(I);
|
||||
I = std::byteswap(I);
|
||||
Src = &ByteSwapped[0];
|
||||
SrcEnd = &ByteSwapped[ByteSwapped.size() - 1] + 1;
|
||||
}
|
||||
@@ -161,7 +161,7 @@ bool convertUTF32ToUTF8String(std::span<const char> SrcBytes, std::string &Out)
|
||||
if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) {
|
||||
ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
|
||||
for (UTF32 &I : ByteSwapped)
|
||||
I = wpi::util::byteswap<uint32_t>(I);
|
||||
I = std::byteswap(I);
|
||||
Src = &ByteSwapped[0];
|
||||
SrcEnd = &ByteSwapped[ByteSwapped.size() - 1] + 1;
|
||||
}
|
||||
@@ -316,4 +316,3 @@ bool IsSingleCodeUnitUTF32Codepoint(unsigned V) {
|
||||
}
|
||||
|
||||
} // end namespace wpi::util
|
||||
|
||||
|
||||
@@ -13,9 +13,8 @@
|
||||
#ifndef WPIUTIL_WPI_ENDIAN_H
|
||||
#define WPIUTIL_WPI_ENDIAN_H
|
||||
|
||||
#include "wpi/util/bit.hpp"
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include "wpi/util/SwapByteOrder.hpp"
|
||||
#include <bit>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@@ -41,25 +40,25 @@ struct PickAlignment {
|
||||
namespace endian {
|
||||
|
||||
template <typename value_type>
|
||||
[[nodiscard]] inline value_type byte_swap(value_type value, endianness endian) {
|
||||
if (endian != wpi::util::endianness::native)
|
||||
sys::swapByteOrder(value);
|
||||
[[nodiscard]] inline value_type byte_swap(value_type value, std::endian endian) {
|
||||
if (endian != std::endian::native)
|
||||
return std::byteswap(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Swap the bytes of value to match the given endianness.
|
||||
template <typename value_type, endianness endian>
|
||||
template <typename value_type, std::endian endian>
|
||||
[[nodiscard]]
|
||||
LLVM_DEPRECATED("Pass endian as a function argument instead",
|
||||
"byte_swap") inline value_type byte_swap(value_type value) {
|
||||
if constexpr (endian != wpi::util::endianness::native)
|
||||
sys::swapByteOrder(value);
|
||||
if constexpr (endian != std::endian::native)
|
||||
return std::byteswap(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Read a value of a particular endianness from memory.
|
||||
template <typename value_type, std::size_t alignment = unaligned>
|
||||
[[nodiscard]] inline value_type read(const void *memory, endianness endian) {
|
||||
[[nodiscard]] inline value_type read(const void *memory, std::endian endian) {
|
||||
value_type ret;
|
||||
|
||||
memcpy(static_cast<void *>(&ret),
|
||||
@@ -69,7 +68,7 @@ template <typename value_type, std::size_t alignment = unaligned>
|
||||
return byte_swap<value_type>(ret, endian);
|
||||
}
|
||||
|
||||
template <typename value_type, endianness endian, std::size_t alignment>
|
||||
template <typename value_type, std::endian endian, std::size_t alignment>
|
||||
[[nodiscard]] LLVM_DEPRECATED("Pass endian as a function argument instead",
|
||||
"read") inline value_type
|
||||
read(const void *memory) {
|
||||
@@ -81,13 +80,13 @@ template <typename value_type, endianness endian, std::size_t alignment>
|
||||
template <typename value_type, std::size_t alignment = unaligned,
|
||||
typename CharT>
|
||||
[[nodiscard]] inline value_type readNext(const CharT *&memory,
|
||||
endianness endian) {
|
||||
std::endian endian) {
|
||||
value_type ret = read<value_type, alignment>(memory, endian);
|
||||
memory += sizeof(value_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename value_type, endianness endian,
|
||||
template <typename value_type, std::endian endian,
|
||||
std::size_t alignment = unaligned, typename CharT>
|
||||
[[nodiscard]] inline value_type readNext(const CharT *&memory) {
|
||||
return readNext<value_type, alignment, CharT>(memory, endian);
|
||||
@@ -95,14 +94,14 @@ template <typename value_type, endianness endian,
|
||||
|
||||
/// Write a value to memory with a particular endianness.
|
||||
template <typename value_type, std::size_t alignment = unaligned>
|
||||
inline void write(void *memory, value_type value, endianness endian) {
|
||||
inline void write(void *memory, value_type value, std::endian endian) {
|
||||
value = byte_swap<value_type>(value, endian);
|
||||
memcpy(LLVM_ASSUME_ALIGNED(
|
||||
memory, (detail::PickAlignment<value_type, alignment>::value)),
|
||||
&value, sizeof(value_type));
|
||||
}
|
||||
|
||||
template <typename value_type, endianness endian, std::size_t alignment>
|
||||
template <typename value_type, std::endian endian, std::size_t alignment>
|
||||
LLVM_DEPRECATED("Pass endian as a function argument instead", "write")
|
||||
inline void write(void *memory, value_type value) {
|
||||
write<value_type, alignment>(memory, value, endian);
|
||||
@@ -112,12 +111,12 @@ inline void write(void *memory, value_type value) {
|
||||
/// value.
|
||||
template <typename value_type, std::size_t alignment = unaligned,
|
||||
typename CharT>
|
||||
inline void writeNext(CharT *&memory, value_type value, endianness endian) {
|
||||
inline void writeNext(CharT *&memory, value_type value, std::endian endian) {
|
||||
write(memory, value, endian);
|
||||
memory += sizeof(value_type);
|
||||
}
|
||||
|
||||
template <typename value_type, endianness endian,
|
||||
template <typename value_type, std::endian endian,
|
||||
std::size_t alignment = unaligned, typename CharT>
|
||||
inline void writeNext(CharT *&memory, value_type value) {
|
||||
writeNext<value_type, alignment, CharT>(memory, value, endian);
|
||||
@@ -128,7 +127,7 @@ using make_unsigned_t = std::make_unsigned_t<value_type>;
|
||||
|
||||
/// Read a value of a particular endianness from memory, for a location
|
||||
/// that starts at the given bit offset within the first byte.
|
||||
template <typename value_type, endianness endian, std::size_t alignment>
|
||||
template <typename value_type, std::endian endian, std::size_t alignment>
|
||||
[[nodiscard]] inline value_type readAtBitAlignment(const void *memory,
|
||||
uint64_t startBit) {
|
||||
assert(startBit < 8);
|
||||
@@ -163,7 +162,7 @@ template <typename value_type, endianness endian, std::size_t alignment>
|
||||
|
||||
/// Write a value to memory with a particular endianness, for a location
|
||||
/// that starts at the given bit offset within the first byte.
|
||||
template <typename value_type, endianness endian, std::size_t alignment>
|
||||
template <typename value_type, std::endian endian, std::size_t alignment>
|
||||
inline void writeAtBitAlignment(void *memory, value_type value,
|
||||
uint64_t startBit) {
|
||||
assert(startBit < 8);
|
||||
@@ -217,11 +216,11 @@ inline void writeAtBitAlignment(void *memory, value_type value,
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename ValueType, endianness Endian, std::size_t Alignment,
|
||||
template <typename ValueType, std::endian Endian, std::size_t Alignment,
|
||||
std::size_t ALIGN = PickAlignment<ValueType, Alignment>::value>
|
||||
struct packed_endian_specific_integral {
|
||||
using value_type = ValueType;
|
||||
static constexpr endianness endian = Endian;
|
||||
static constexpr std::endian endian = Endian;
|
||||
static constexpr std::size_t alignment = Alignment;
|
||||
|
||||
packed_endian_specific_integral() = default;
|
||||
@@ -284,210 +283,210 @@ public:
|
||||
} // end namespace detail
|
||||
|
||||
using ulittle8_t =
|
||||
detail::packed_endian_specific_integral<uint8_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<uint8_t, std::endian::little,
|
||||
unaligned>;
|
||||
using ulittle16_t =
|
||||
detail::packed_endian_specific_integral<uint16_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<uint16_t, std::endian::little,
|
||||
unaligned>;
|
||||
using ulittle32_t =
|
||||
detail::packed_endian_specific_integral<uint32_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<uint32_t, std::endian::little,
|
||||
unaligned>;
|
||||
using ulittle64_t =
|
||||
detail::packed_endian_specific_integral<uint64_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<uint64_t, std::endian::little,
|
||||
unaligned>;
|
||||
|
||||
using little16_t =
|
||||
detail::packed_endian_specific_integral<int16_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<int16_t, std::endian::little,
|
||||
unaligned>;
|
||||
using little32_t =
|
||||
detail::packed_endian_specific_integral<int32_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<int32_t, std::endian::little,
|
||||
unaligned>;
|
||||
using little64_t =
|
||||
detail::packed_endian_specific_integral<int64_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<int64_t, std::endian::little,
|
||||
unaligned>;
|
||||
|
||||
using aligned_ulittle16_t =
|
||||
detail::packed_endian_specific_integral<uint16_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<uint16_t, std::endian::little,
|
||||
aligned>;
|
||||
using aligned_ulittle32_t =
|
||||
detail::packed_endian_specific_integral<uint32_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<uint32_t, std::endian::little,
|
||||
aligned>;
|
||||
using aligned_ulittle64_t =
|
||||
detail::packed_endian_specific_integral<uint64_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<uint64_t, std::endian::little,
|
||||
aligned>;
|
||||
|
||||
using aligned_little16_t =
|
||||
detail::packed_endian_specific_integral<int16_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<int16_t, std::endian::little,
|
||||
aligned>;
|
||||
using aligned_little32_t =
|
||||
detail::packed_endian_specific_integral<int32_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<int32_t, std::endian::little,
|
||||
aligned>;
|
||||
using aligned_little64_t =
|
||||
detail::packed_endian_specific_integral<int64_t, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<int64_t, std::endian::little,
|
||||
aligned>;
|
||||
|
||||
using ubig16_t =
|
||||
detail::packed_endian_specific_integral<uint16_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<uint16_t, std::endian::big,
|
||||
unaligned>;
|
||||
using ubig32_t =
|
||||
detail::packed_endian_specific_integral<uint32_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<uint32_t, std::endian::big,
|
||||
unaligned>;
|
||||
using ubig64_t =
|
||||
detail::packed_endian_specific_integral<uint64_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<uint64_t, std::endian::big,
|
||||
unaligned>;
|
||||
|
||||
using big16_t =
|
||||
detail::packed_endian_specific_integral<int16_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<int16_t, std::endian::big,
|
||||
unaligned>;
|
||||
using big32_t =
|
||||
detail::packed_endian_specific_integral<int32_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<int32_t, std::endian::big,
|
||||
unaligned>;
|
||||
using big64_t =
|
||||
detail::packed_endian_specific_integral<int64_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<int64_t, std::endian::big,
|
||||
unaligned>;
|
||||
|
||||
using aligned_ubig16_t =
|
||||
detail::packed_endian_specific_integral<uint16_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<uint16_t, std::endian::big,
|
||||
aligned>;
|
||||
using aligned_ubig32_t =
|
||||
detail::packed_endian_specific_integral<uint32_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<uint32_t, std::endian::big,
|
||||
aligned>;
|
||||
using aligned_ubig64_t =
|
||||
detail::packed_endian_specific_integral<uint64_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<uint64_t, std::endian::big,
|
||||
aligned>;
|
||||
|
||||
using aligned_big16_t =
|
||||
detail::packed_endian_specific_integral<int16_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<int16_t, std::endian::big,
|
||||
aligned>;
|
||||
using aligned_big32_t =
|
||||
detail::packed_endian_specific_integral<int32_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<int32_t, std::endian::big,
|
||||
aligned>;
|
||||
using aligned_big64_t =
|
||||
detail::packed_endian_specific_integral<int64_t, wpi::util::endianness::big,
|
||||
detail::packed_endian_specific_integral<int64_t, std::endian::big,
|
||||
aligned>;
|
||||
|
||||
using unaligned_uint16_t =
|
||||
detail::packed_endian_specific_integral<uint16_t, wpi::util::endianness::native,
|
||||
detail::packed_endian_specific_integral<uint16_t, std::endian::native,
|
||||
unaligned>;
|
||||
using unaligned_uint32_t =
|
||||
detail::packed_endian_specific_integral<uint32_t, wpi::util::endianness::native,
|
||||
detail::packed_endian_specific_integral<uint32_t, std::endian::native,
|
||||
unaligned>;
|
||||
using unaligned_uint64_t =
|
||||
detail::packed_endian_specific_integral<uint64_t, wpi::util::endianness::native,
|
||||
detail::packed_endian_specific_integral<uint64_t, std::endian::native,
|
||||
unaligned>;
|
||||
|
||||
using unaligned_int16_t =
|
||||
detail::packed_endian_specific_integral<int16_t, wpi::util::endianness::native,
|
||||
detail::packed_endian_specific_integral<int16_t, std::endian::native,
|
||||
unaligned>;
|
||||
using unaligned_int32_t =
|
||||
detail::packed_endian_specific_integral<int32_t, wpi::util::endianness::native,
|
||||
detail::packed_endian_specific_integral<int32_t, std::endian::native,
|
||||
unaligned>;
|
||||
using unaligned_int64_t =
|
||||
detail::packed_endian_specific_integral<int64_t, wpi::util::endianness::native,
|
||||
detail::packed_endian_specific_integral<int64_t, std::endian::native,
|
||||
unaligned>;
|
||||
|
||||
template <typename T>
|
||||
using little_t =
|
||||
detail::packed_endian_specific_integral<T, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<T, std::endian::little,
|
||||
unaligned>;
|
||||
template <typename T>
|
||||
using big_t = detail::packed_endian_specific_integral<T, wpi::util::endianness::big,
|
||||
using big_t = detail::packed_endian_specific_integral<T, std::endian::big,
|
||||
unaligned>;
|
||||
|
||||
template <typename T>
|
||||
using aligned_little_t =
|
||||
detail::packed_endian_specific_integral<T, wpi::util::endianness::little,
|
||||
detail::packed_endian_specific_integral<T, std::endian::little,
|
||||
aligned>;
|
||||
template <typename T>
|
||||
using aligned_big_t =
|
||||
detail::packed_endian_specific_integral<T, wpi::util::endianness::big, aligned>;
|
||||
detail::packed_endian_specific_integral<T, std::endian::big, aligned>;
|
||||
|
||||
namespace endian {
|
||||
|
||||
template <typename T, endianness E> [[nodiscard]] inline T read(const void *P) {
|
||||
template <typename T, std::endian E> [[nodiscard]] inline T read(const void *P) {
|
||||
return *(const detail::packed_endian_specific_integral<T, E, unaligned> *)P;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline uint16_t read16(const void *P, endianness E) {
|
||||
[[nodiscard]] inline uint16_t read16(const void *P, std::endian E) {
|
||||
return read<uint16_t>(P, E);
|
||||
}
|
||||
[[nodiscard]] inline uint32_t read32(const void *P, endianness E) {
|
||||
[[nodiscard]] inline uint32_t read32(const void *P, std::endian E) {
|
||||
return read<uint32_t>(P, E);
|
||||
}
|
||||
[[nodiscard]] inline uint64_t read64(const void *P, endianness E) {
|
||||
[[nodiscard]] inline uint64_t read64(const void *P, std::endian E) {
|
||||
return read<uint64_t>(P, E);
|
||||
}
|
||||
|
||||
template <endianness E> [[nodiscard]] inline uint16_t read16(const void *P) {
|
||||
template <std::endian E> [[nodiscard]] inline uint16_t read16(const void *P) {
|
||||
return read<uint16_t, E>(P);
|
||||
}
|
||||
template <endianness E> [[nodiscard]] inline uint32_t read32(const void *P) {
|
||||
template <std::endian E> [[nodiscard]] inline uint32_t read32(const void *P) {
|
||||
return read<uint32_t, E>(P);
|
||||
}
|
||||
template <endianness E> [[nodiscard]] inline uint64_t read64(const void *P) {
|
||||
template <std::endian E> [[nodiscard]] inline uint64_t read64(const void *P) {
|
||||
return read<uint64_t, E>(P);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline uint16_t read16le(const void *P) {
|
||||
return read16<wpi::util::endianness::little>(P);
|
||||
return read16<std::endian::little>(P);
|
||||
}
|
||||
[[nodiscard]] inline uint32_t read32le(const void *P) {
|
||||
return read32<wpi::util::endianness::little>(P);
|
||||
return read32<std::endian::little>(P);
|
||||
}
|
||||
[[nodiscard]] inline uint64_t read64le(const void *P) {
|
||||
return read64<wpi::util::endianness::little>(P);
|
||||
return read64<std::endian::little>(P);
|
||||
}
|
||||
[[nodiscard]] inline uint16_t read16be(const void *P) {
|
||||
return read16<wpi::util::endianness::big>(P);
|
||||
return read16<std::endian::big>(P);
|
||||
}
|
||||
[[nodiscard]] inline uint32_t read32be(const void *P) {
|
||||
return read32<wpi::util::endianness::big>(P);
|
||||
return read32<std::endian::big>(P);
|
||||
}
|
||||
[[nodiscard]] inline uint64_t read64be(const void *P) {
|
||||
return read64<wpi::util::endianness::big>(P);
|
||||
return read64<std::endian::big>(P);
|
||||
}
|
||||
|
||||
template <typename T, endianness E> inline void write(void *P, T V) {
|
||||
template <typename T, std::endian E> inline void write(void *P, T V) {
|
||||
*(detail::packed_endian_specific_integral<T, E, unaligned> *)P = V;
|
||||
}
|
||||
|
||||
inline void write16(void *P, uint16_t V, endianness E) {
|
||||
inline void write16(void *P, uint16_t V, std::endian E) {
|
||||
write<uint16_t>(P, V, E);
|
||||
}
|
||||
inline void write32(void *P, uint32_t V, endianness E) {
|
||||
inline void write32(void *P, uint32_t V, std::endian E) {
|
||||
write<uint32_t>(P, V, E);
|
||||
}
|
||||
inline void write64(void *P, uint64_t V, endianness E) {
|
||||
inline void write64(void *P, uint64_t V, std::endian E) {
|
||||
write<uint64_t>(P, V, E);
|
||||
}
|
||||
|
||||
template <endianness E> inline void write16(void *P, uint16_t V) {
|
||||
template <std::endian E> inline void write16(void *P, uint16_t V) {
|
||||
write<uint16_t, E>(P, V);
|
||||
}
|
||||
template <endianness E> inline void write32(void *P, uint32_t V) {
|
||||
template <std::endian E> inline void write32(void *P, uint32_t V) {
|
||||
write<uint32_t, E>(P, V);
|
||||
}
|
||||
template <endianness E> inline void write64(void *P, uint64_t V) {
|
||||
template <std::endian E> inline void write64(void *P, uint64_t V) {
|
||||
write<uint64_t, E>(P, V);
|
||||
}
|
||||
|
||||
inline void write16le(void *P, uint16_t V) {
|
||||
write16<wpi::util::endianness::little>(P, V);
|
||||
write16<std::endian::little>(P, V);
|
||||
}
|
||||
inline void write32le(void *P, uint32_t V) {
|
||||
write32<wpi::util::endianness::little>(P, V);
|
||||
write32<std::endian::little>(P, V);
|
||||
}
|
||||
inline void write64le(void *P, uint64_t V) {
|
||||
write64<wpi::util::endianness::little>(P, V);
|
||||
write64<std::endian::little>(P, V);
|
||||
}
|
||||
inline void write16be(void *P, uint16_t V) {
|
||||
write16<wpi::util::endianness::big>(P, V);
|
||||
write16<std::endian::big>(P, V);
|
||||
}
|
||||
inline void write32be(void *P, uint32_t V) {
|
||||
write32<wpi::util::endianness::big>(P, V);
|
||||
write32<std::endian::big>(P, V);
|
||||
}
|
||||
inline void write64be(void *P, uint64_t V) {
|
||||
write64<wpi::util::endianness::big>(P, V);
|
||||
write64<std::endian::big>(P, V);
|
||||
}
|
||||
|
||||
} // end namespace endian
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#define WPIUTIL_WPI_MATHEXTRAS_H
|
||||
|
||||
#include "wpi/util/STLForwardCompat.hpp"
|
||||
#include "wpi/util/bit.hpp"
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <bit>
|
||||
#include <cassert>
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
//===- SwapByteOrder.h - Generic and optimized byte swaps -------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares generic and optimized functions to swap the byte order of
|
||||
// an integral type.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef WPIUTIL_WPI_SWAPBYTEORDER_H
|
||||
#define WPIUTIL_WPI_SWAPBYTEORDER_H
|
||||
|
||||
#include "wpi/util/STLForwardCompat.hpp"
|
||||
#include "wpi/util/bit.hpp"
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
namespace sys {
|
||||
|
||||
constexpr bool IsBigEndianHost =
|
||||
wpi::util::endianness::native == wpi::util::endianness::big;
|
||||
|
||||
constexpr bool IsLittleEndianHost = !IsBigEndianHost;
|
||||
|
||||
inline unsigned char getSwappedBytes(unsigned char C) { return wpi::util::byteswap(C); }
|
||||
inline signed char getSwappedBytes( signed char C) { return wpi::util::byteswap(C); }
|
||||
inline char getSwappedBytes( char C) { return wpi::util::byteswap(C); }
|
||||
|
||||
inline unsigned short getSwappedBytes(unsigned short C) { return wpi::util::byteswap(C); }
|
||||
inline signed short getSwappedBytes( signed short C) { return wpi::util::byteswap(C); }
|
||||
|
||||
inline unsigned int getSwappedBytes(unsigned int C) { return wpi::util::byteswap(C); }
|
||||
inline signed int getSwappedBytes( signed int C) { return wpi::util::byteswap(C); }
|
||||
|
||||
inline unsigned long getSwappedBytes(unsigned long C) { return wpi::util::byteswap(C); }
|
||||
inline signed long getSwappedBytes( signed long C) { return wpi::util::byteswap(C); }
|
||||
|
||||
inline unsigned long long getSwappedBytes(unsigned long long C) { return wpi::util::byteswap(C); }
|
||||
inline signed long long getSwappedBytes( signed long long C) { return wpi::util::byteswap(C); }
|
||||
|
||||
inline float getSwappedBytes(float C) {
|
||||
return wpi::util::bit_cast<float>(wpi::util::byteswap(wpi::util::bit_cast<uint32_t>(C)));
|
||||
}
|
||||
|
||||
inline double getSwappedBytes(double C) {
|
||||
return wpi::util::bit_cast<double>(wpi::util::byteswap(wpi::util::bit_cast<uint64_t>(C)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::enable_if_t<std::is_enum_v<T>, T> getSwappedBytes(T C) {
|
||||
return static_cast<T>(wpi::util::byteswap(wpi::util::to_underlying(C)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void swapByteOrder(T &Value) {
|
||||
Value = getSwappedBytes(Value);
|
||||
}
|
||||
|
||||
} // end namespace sys
|
||||
} // end namespace wpi::util
|
||||
|
||||
#endif
|
||||
@@ -1,110 +0,0 @@
|
||||
//===-- llvm/ADT/bit.h - C++20 <bit> ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// This file implements the C++20 <bit> header.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef WPIUTIL_WPI_BIT_H
|
||||
#define WPIUTIL_WPI_BIT_H
|
||||
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#if !__has_builtin(__builtin_bit_cast)
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_DEBUG)
|
||||
#include <cstdlib> // for _byteswap_{ushort,ulong,uint64}
|
||||
#endif
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
enum class endianness {
|
||||
big,
|
||||
little,
|
||||
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
|
||||
native = big
|
||||
#else
|
||||
native = little
|
||||
#endif
|
||||
};
|
||||
|
||||
// This implementation of bit_cast is different from the C++20 one in two ways:
|
||||
// - It isn't constexpr because that requires compiler support.
|
||||
// - It requires trivially-constructible To, to avoid UB in the implementation.
|
||||
template <
|
||||
typename To, typename From,
|
||||
typename = std::enable_if_t<sizeof(To) == sizeof(From)>,
|
||||
typename = std::enable_if_t<std::is_trivially_constructible<To>::value>,
|
||||
typename = std::enable_if_t<std::is_trivially_copyable<To>::value>,
|
||||
typename = std::enable_if_t<std::is_trivially_copyable<From>::value>>
|
||||
[[nodiscard]] inline To bit_cast(const From &from) noexcept {
|
||||
#if __has_builtin(__builtin_bit_cast)
|
||||
return __builtin_bit_cast(To, from);
|
||||
#else
|
||||
To to;
|
||||
std::memcpy(&to, &from, sizeof(To));
|
||||
return to;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Reverses the bytes in the given integer value V.
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
[[nodiscard]] constexpr T byteswap(T V) noexcept {
|
||||
if constexpr (sizeof(T) == 1) {
|
||||
return V;
|
||||
} else if constexpr (sizeof(T) == 2) {
|
||||
uint16_t UV = V;
|
||||
#if defined(_MSC_VER) && !defined(_DEBUG)
|
||||
// The DLL version of the runtime lacks these functions (bug!?), but in a
|
||||
// release build they're replaced with BSWAP instructions anyway.
|
||||
return _byteswap_ushort(UV);
|
||||
#else
|
||||
uint16_t Hi = UV << 8;
|
||||
uint16_t Lo = UV >> 8;
|
||||
return Hi | Lo;
|
||||
#endif
|
||||
} else if constexpr (sizeof(T) == 4) {
|
||||
uint32_t UV = V;
|
||||
#if __has_builtin(__builtin_bswap32)
|
||||
return __builtin_bswap32(UV);
|
||||
#elif defined(_MSC_VER) && !defined(_DEBUG)
|
||||
return _byteswap_ulong(UV);
|
||||
#else
|
||||
uint32_t Byte0 = UV & 0x000000FF;
|
||||
uint32_t Byte1 = UV & 0x0000FF00;
|
||||
uint32_t Byte2 = UV & 0x00FF0000;
|
||||
uint32_t Byte3 = UV & 0xFF000000;
|
||||
return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
|
||||
#endif
|
||||
} else if constexpr (sizeof(T) == 8) {
|
||||
uint64_t UV = V;
|
||||
#if __has_builtin(__builtin_bswap64)
|
||||
return __builtin_bswap64(UV);
|
||||
#elif defined(_MSC_VER) && !defined(_DEBUG)
|
||||
return _byteswap_uint64(UV);
|
||||
#else
|
||||
uint64_t Hi = wpi::util::byteswap<uint32_t>(UV);
|
||||
uint32_t Lo = wpi::util::byteswap<uint32_t>(UV >> 32);
|
||||
return (Hi << 32) | Lo;
|
||||
#endif
|
||||
} else {
|
||||
static_assert(!sizeof(T *), "Don't know how to handle the given type.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wpi::util
|
||||
|
||||
#endif
|
||||
@@ -23,33 +23,32 @@ TEST(Endian, Read) {
|
||||
unsigned char littleval[] = {0x00, 0x04, 0x03, 0x02, 0x01};
|
||||
int32_t BigAsHost = 0x00010203;
|
||||
EXPECT_EQ(BigAsHost,
|
||||
(endian::read<int32_t, unaligned>(bigval, wpi::util::endianness::big)));
|
||||
(endian::read<int32_t, unaligned>(bigval, std::endian::big)));
|
||||
int32_t LittleAsHost = 0x02030400;
|
||||
EXPECT_EQ(LittleAsHost, (endian::read<int32_t, unaligned>(
|
||||
littleval, wpi::util::endianness::little)));
|
||||
littleval, std::endian::little)));
|
||||
|
||||
EXPECT_EQ(
|
||||
(endian::read<int32_t, unaligned>(bigval + 1, wpi::util::endianness::big)),
|
||||
(endian::read<int32_t, unaligned>(littleval + 1,
|
||||
wpi::util::endianness::little)));
|
||||
(endian::read<int32_t, unaligned>(bigval + 1, std::endian::big)),
|
||||
(endian::read<int32_t, unaligned>(littleval + 1, std::endian::little)));
|
||||
}
|
||||
|
||||
TEST(Endian, WriteNext) {
|
||||
unsigned char bigval[] = {0x00, 0x00}, *p = bigval;
|
||||
endian::writeNext<int16_t, wpi::util::endianness::big>(p, short(0xaabb));
|
||||
endian::writeNext<int16_t, std::endian::big>(p, short(0xaabb));
|
||||
EXPECT_EQ(bigval[0], 0xaa);
|
||||
EXPECT_EQ(bigval[1], 0xbb);
|
||||
EXPECT_EQ(p, bigval + 2);
|
||||
|
||||
char littleval[8] = {}, *q = littleval;
|
||||
endian::writeNext<uint32_t, wpi::util::endianness::little>(q, 0x44556677);
|
||||
endian::writeNext<uint32_t, std::endian::little>(q, 0x44556677);
|
||||
EXPECT_EQ(littleval[0], 0x77);
|
||||
EXPECT_EQ(littleval[1], 0x66);
|
||||
EXPECT_EQ(littleval[2], 0x55);
|
||||
EXPECT_EQ(littleval[3], 0x44);
|
||||
EXPECT_EQ(q, littleval + 4);
|
||||
|
||||
endian::writeNext<uint32_t>(q, 0x11223344, wpi::util::endianness::little);
|
||||
endian::writeNext<uint32_t>(q, 0x11223344, std::endian::little);
|
||||
EXPECT_EQ(littleval[4], 0x44);
|
||||
EXPECT_EQ(littleval[5], 0x33);
|
||||
EXPECT_EQ(littleval[6], 0x22);
|
||||
@@ -62,10 +61,10 @@ TEST(Endian, ReadBitAligned) {
|
||||
unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};
|
||||
unsigned char bigval[] = {0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0};
|
||||
EXPECT_EQ(
|
||||
(endian::readAtBitAlignment<int, wpi::util::endianness::little, unaligned>(
|
||||
(endian::readAtBitAlignment<int, std::endian::little, unaligned>(
|
||||
&littleval[0], 6)),
|
||||
0x0);
|
||||
EXPECT_EQ((endian::readAtBitAlignment<int, wpi::util::endianness::big, unaligned>(
|
||||
EXPECT_EQ((endian::readAtBitAlignment<int, std::endian::big, unaligned>(
|
||||
&bigval[0], 6)),
|
||||
0x0);
|
||||
// Test to make sure that signed right shift of 0xf0000000 is masked
|
||||
@@ -73,18 +72,18 @@ TEST(Endian, ReadBitAligned) {
|
||||
unsigned char littleval2[] = {0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00};
|
||||
unsigned char bigval2[] = {0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
EXPECT_EQ(
|
||||
(endian::readAtBitAlignment<int, wpi::util::endianness::little, unaligned>(
|
||||
(endian::readAtBitAlignment<int, std::endian::little, unaligned>(
|
||||
&littleval2[0], 4)),
|
||||
0x0f000000);
|
||||
EXPECT_EQ((endian::readAtBitAlignment<int, wpi::util::endianness::big, unaligned>(
|
||||
EXPECT_EQ((endian::readAtBitAlignment<int, std::endian::big, unaligned>(
|
||||
&bigval2[0], 4)),
|
||||
0x0f000000);
|
||||
// Test to make sure left shift of start bit doesn't overflow.
|
||||
EXPECT_EQ(
|
||||
(endian::readAtBitAlignment<int, wpi::util::endianness::little, unaligned>(
|
||||
(endian::readAtBitAlignment<int, std::endian::little, unaligned>(
|
||||
&littleval2[0], 1)),
|
||||
0x78000000);
|
||||
EXPECT_EQ((endian::readAtBitAlignment<int, wpi::util::endianness::big, unaligned>(
|
||||
EXPECT_EQ((endian::readAtBitAlignment<int, std::endian::big, unaligned>(
|
||||
&bigval2[0], 1)),
|
||||
0x78000000);
|
||||
// Test to make sure 64-bit int doesn't overflow.
|
||||
@@ -93,11 +92,11 @@ TEST(Endian, ReadBitAligned) {
|
||||
unsigned char bigval3[] = {0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
EXPECT_EQ(
|
||||
(endian::readAtBitAlignment<int64_t, wpi::util::endianness::little, unaligned>(
|
||||
(endian::readAtBitAlignment<int64_t, std::endian::little, unaligned>(
|
||||
&littleval3[0], 4)),
|
||||
0x0f00000000000000);
|
||||
EXPECT_EQ(
|
||||
(endian::readAtBitAlignment<int64_t, wpi::util::endianness::big, unaligned>(
|
||||
(endian::readAtBitAlignment<int64_t, std::endian::big, unaligned>(
|
||||
&bigval3[0], 4)),
|
||||
0x0f00000000000000);
|
||||
}
|
||||
@@ -106,7 +105,7 @@ TEST(Endian, WriteBitAligned) {
|
||||
// This test ensures that signed right shift of 0xffffaa is masked
|
||||
// properly.
|
||||
unsigned char bigval[8] = {0x00};
|
||||
endian::writeAtBitAlignment<int32_t, wpi::util::endianness::big, unaligned>(
|
||||
endian::writeAtBitAlignment<int32_t, std::endian::big, unaligned>(
|
||||
bigval, (int)0xffffaaaa, 4);
|
||||
EXPECT_EQ(bigval[0], 0xff);
|
||||
EXPECT_EQ(bigval[1], 0xfa);
|
||||
@@ -118,7 +117,7 @@ TEST(Endian, WriteBitAligned) {
|
||||
EXPECT_EQ(bigval[7], 0x0f);
|
||||
|
||||
unsigned char littleval[8] = {0x00};
|
||||
endian::writeAtBitAlignment<int32_t, wpi::util::endianness::little, unaligned>(
|
||||
endian::writeAtBitAlignment<int32_t, std::endian::little, unaligned>(
|
||||
littleval, (int)0xffffaaaa, 4);
|
||||
EXPECT_EQ(littleval[0], 0xa0);
|
||||
EXPECT_EQ(littleval[1], 0xaa);
|
||||
@@ -132,7 +131,7 @@ TEST(Endian, WriteBitAligned) {
|
||||
// This test makes sure 1<<31 doesn't overflow.
|
||||
// Test to make sure left shift of start bit doesn't overflow.
|
||||
unsigned char bigval2[8] = {0x00};
|
||||
endian::writeAtBitAlignment<int32_t, wpi::util::endianness::big, unaligned>(
|
||||
endian::writeAtBitAlignment<int32_t, std::endian::big, unaligned>(
|
||||
bigval2, (int)0xffffffff, 1);
|
||||
EXPECT_EQ(bigval2[0], 0xff);
|
||||
EXPECT_EQ(bigval2[1], 0xff);
|
||||
@@ -144,7 +143,7 @@ TEST(Endian, WriteBitAligned) {
|
||||
EXPECT_EQ(bigval2[7], 0x01);
|
||||
|
||||
unsigned char littleval2[8] = {0x00};
|
||||
endian::writeAtBitAlignment<int32_t, wpi::util::endianness::little, unaligned>(
|
||||
endian::writeAtBitAlignment<int32_t, std::endian::little, unaligned>(
|
||||
littleval2, (int)0xffffffff, 1);
|
||||
EXPECT_EQ(littleval2[0], 0xfe);
|
||||
EXPECT_EQ(littleval2[1], 0xff);
|
||||
@@ -157,7 +156,7 @@ TEST(Endian, WriteBitAligned) {
|
||||
|
||||
// Test to make sure 64-bit int doesn't overflow.
|
||||
unsigned char bigval64[16] = {0x00};
|
||||
endian::writeAtBitAlignment<int64_t, wpi::util::endianness::big, unaligned>(
|
||||
endian::writeAtBitAlignment<int64_t, std::endian::big, unaligned>(
|
||||
bigval64, (int64_t)0xffffffffffffffff, 1);
|
||||
EXPECT_EQ(bigval64[0], 0xff);
|
||||
EXPECT_EQ(bigval64[1], 0xff);
|
||||
@@ -177,7 +176,7 @@ TEST(Endian, WriteBitAligned) {
|
||||
EXPECT_EQ(bigval64[15], 0x01);
|
||||
|
||||
unsigned char littleval64[16] = {0x00};
|
||||
endian::writeAtBitAlignment<int64_t, wpi::util::endianness::little, unaligned>(
|
||||
endian::writeAtBitAlignment<int64_t, std::endian::little, unaligned>(
|
||||
littleval64, (int64_t)0xffffffffffffffff, 1);
|
||||
EXPECT_EQ(littleval64[0], 0xfe);
|
||||
EXPECT_EQ(littleval64[1], 0xff);
|
||||
@@ -199,26 +198,26 @@ TEST(Endian, WriteBitAligned) {
|
||||
|
||||
TEST(Endian, Write) {
|
||||
unsigned char data[5];
|
||||
endian::write<int32_t, unaligned>(data, -1362446643, wpi::util::endianness::big);
|
||||
endian::write<int32_t, unaligned>(data, -1362446643, std::endian::big);
|
||||
EXPECT_EQ(data[0], 0xAE);
|
||||
EXPECT_EQ(data[1], 0xCA);
|
||||
EXPECT_EQ(data[2], 0xB6);
|
||||
EXPECT_EQ(data[3], 0xCD);
|
||||
endian::write<int32_t, unaligned>(data + 1, -1362446643,
|
||||
wpi::util::endianness::big);
|
||||
std::endian::big);
|
||||
EXPECT_EQ(data[1], 0xAE);
|
||||
EXPECT_EQ(data[2], 0xCA);
|
||||
EXPECT_EQ(data[3], 0xB6);
|
||||
EXPECT_EQ(data[4], 0xCD);
|
||||
|
||||
endian::write<int32_t, unaligned>(data, -1362446643,
|
||||
wpi::util::endianness::little);
|
||||
std::endian::little);
|
||||
EXPECT_EQ(data[0], 0xCD);
|
||||
EXPECT_EQ(data[1], 0xB6);
|
||||
EXPECT_EQ(data[2], 0xCA);
|
||||
EXPECT_EQ(data[3], 0xAE);
|
||||
endian::write<int32_t, unaligned>(data + 1, -1362446643,
|
||||
wpi::util::endianness::little);
|
||||
std::endian::little);
|
||||
EXPECT_EQ(data[1], 0xCD);
|
||||
EXPECT_EQ(data[2], 0xB6);
|
||||
EXPECT_EQ(data[3], 0xCA);
|
||||
@@ -238,13 +237,4 @@ TEST(Endian, PackedEndianSpecificIntegral) {
|
||||
EXPECT_EQ(big_val->value(), little_val->value());
|
||||
}
|
||||
|
||||
TEST(Endian, PacketEndianSpecificIntegralAsEnum) {
|
||||
enum class Test : uint16_t { ONETWO = 0x0102, TWOONE = 0x0201 };
|
||||
unsigned char bytes[] = {0x01, 0x02};
|
||||
using LittleTest = little_t<Test>;
|
||||
using BigTest = big_t<Test>;
|
||||
EXPECT_EQ(Test::TWOONE, *reinterpret_cast<LittleTest *>(bytes));
|
||||
EXPECT_EQ(Test::ONETWO, *reinterpret_cast<BigTest *>(bytes));
|
||||
}
|
||||
|
||||
} // end anon namespace
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
//===- unittests/Support/SwapByteOrderTest.cpp - swap byte order test -----===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "wpi/util/SwapByteOrder.hpp"
|
||||
#include "gtest/gtest.h"
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
using namespace wpi::util;
|
||||
|
||||
#undef max
|
||||
|
||||
namespace {
|
||||
|
||||
// In these first two tests all of the original_uintx values are truncated
|
||||
// except for 64. We could avoid this, but there's really no point.
|
||||
|
||||
TEST(getSwappedBytes, UnsignedRoundTrip) {
|
||||
// The point of the bit twiddling of magic is to test with and without bits
|
||||
// in every byte.
|
||||
uint64_t value = 1;
|
||||
for (std::size_t i = 0; i <= sizeof(value); ++i) {
|
||||
uint8_t original_uint8 = static_cast<uint8_t>(value);
|
||||
EXPECT_EQ(original_uint8,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_uint8)));
|
||||
|
||||
uint16_t original_uint16 = static_cast<uint16_t>(value);
|
||||
EXPECT_EQ(original_uint16,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_uint16)));
|
||||
|
||||
uint32_t original_uint32 = static_cast<uint32_t>(value);
|
||||
EXPECT_EQ(original_uint32,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_uint32)));
|
||||
|
||||
uint64_t original_uint64 = static_cast<uint64_t>(value);
|
||||
EXPECT_EQ(original_uint64,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_uint64)));
|
||||
|
||||
value = (value << 8) | 0x55; // binary 0101 0101.
|
||||
}
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, SignedRoundTrip) {
|
||||
// The point of the bit twiddling of magic is to test with and without bits
|
||||
// in every byte.
|
||||
uint64_t value = 1;
|
||||
for (std::size_t i = 0; i <= sizeof(value); ++i) {
|
||||
int8_t original_int8 = static_cast<int8_t>(value);
|
||||
EXPECT_EQ(original_int8,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int8)));
|
||||
|
||||
int16_t original_int16 = static_cast<int16_t>(value);
|
||||
EXPECT_EQ(original_int16,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int16)));
|
||||
|
||||
int32_t original_int32 = static_cast<int32_t>(value);
|
||||
EXPECT_EQ(original_int32,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int32)));
|
||||
|
||||
int64_t original_int64 = static_cast<int64_t>(value);
|
||||
EXPECT_EQ(original_int64,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int64)));
|
||||
|
||||
// Test other sign.
|
||||
value *= -1;
|
||||
|
||||
original_int8 = static_cast<int8_t>(value);
|
||||
EXPECT_EQ(original_int8,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int8)));
|
||||
|
||||
original_int16 = static_cast<int16_t>(value);
|
||||
EXPECT_EQ(original_int16,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int16)));
|
||||
|
||||
original_int32 = static_cast<int32_t>(value);
|
||||
EXPECT_EQ(original_int32,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int32)));
|
||||
|
||||
original_int64 = static_cast<int64_t>(value);
|
||||
EXPECT_EQ(original_int64,
|
||||
sys::getSwappedBytes(sys::getSwappedBytes(original_int64)));
|
||||
|
||||
// Return to normal sign and twiddle.
|
||||
value *= -1;
|
||||
value = (value << 8) | 0x55; // binary 0101 0101.
|
||||
}
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, uint8_t) {
|
||||
EXPECT_EQ(uint8_t(0x11), sys::getSwappedBytes(uint8_t(0x11)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, uint16_t) {
|
||||
EXPECT_EQ(uint16_t(0x1122), sys::getSwappedBytes(uint16_t(0x2211)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, uint32_t) {
|
||||
EXPECT_EQ(uint32_t(0x11223344), sys::getSwappedBytes(uint32_t(0x44332211)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, uint64_t) {
|
||||
EXPECT_EQ(uint64_t(0x1122334455667788ULL),
|
||||
sys::getSwappedBytes(uint64_t(0x8877665544332211ULL)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, int8_t) {
|
||||
EXPECT_EQ(int8_t(0x11), sys::getSwappedBytes(int8_t(0x11)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, int16_t) {
|
||||
EXPECT_EQ(int16_t(0x1122), sys::getSwappedBytes(int16_t(0x2211)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, int32_t) {
|
||||
EXPECT_EQ(int32_t(0x11223344), sys::getSwappedBytes(int32_t(0x44332211)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, int64_t) {
|
||||
EXPECT_EQ(int64_t(0x1122334455667788LL),
|
||||
sys::getSwappedBytes(int64_t(0x8877665544332211LL)));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, float) {
|
||||
EXPECT_EQ(1.79366203433576585078237386661e-43f, sys::getSwappedBytes(-0.0f));
|
||||
// 0x11223344
|
||||
EXPECT_EQ(7.1653228759765625e2f, sys::getSwappedBytes(1.2795344e-28f));
|
||||
}
|
||||
|
||||
TEST(getSwappedBytes, double) {
|
||||
EXPECT_EQ(6.32404026676795576546008054871e-322, sys::getSwappedBytes(-0.0));
|
||||
// 0x1122334455667788
|
||||
EXPECT_EQ(-7.08687663657301358331704585496e-268,
|
||||
sys::getSwappedBytes(3.84141202447173065923064450234e-226));
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, uint8_t) {
|
||||
uint8_t value = 0x11;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(uint8_t(0x11), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, uint16_t) {
|
||||
uint16_t value = 0x2211;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(uint16_t(0x1122), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, uint32_t) {
|
||||
uint32_t value = 0x44332211;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(uint32_t(0x11223344), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, uint64_t) {
|
||||
uint64_t value = 0x8877665544332211ULL;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(uint64_t(0x1122334455667788ULL), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, int8_t) {
|
||||
int8_t value = 0x11;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(int8_t(0x11), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, int16_t) {
|
||||
int16_t value = 0x2211;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(int16_t(0x1122), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, int32_t) {
|
||||
int32_t value = 0x44332211;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(int32_t(0x11223344), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, int64_t) {
|
||||
int64_t value = 0x8877665544332211LL;
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(int64_t(0x1122334455667788LL), value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, float) {
|
||||
float value = 7.1653228759765625e2f; // 0x44332211
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(1.2795344e-28f, value);
|
||||
}
|
||||
|
||||
TEST(swapByteOrder, double) {
|
||||
double value = -7.08687663657301358331704585496e-268; // 0x8877665544332211
|
||||
sys::swapByteOrder(value);
|
||||
EXPECT_EQ(3.84141202447173065923064450234e-226, value);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user