Ludovic 'Archivist' Lagouardette 2 years ago
parent
commit
64817741b5
2 changed files with 75 additions and 70 deletions
  1. +3
    -4
      include/gp/ipc/envelope/cbor.hpp
  2. +72
    -66
      include/gp/math/boolean/bitops.hpp

+ 3
- 4
include/gp/ipc/envelope/cbor.hpp View File

@ -126,19 +126,19 @@ namespace gp {
} else if(norm_v < (1ll<<16ll)) {
endian_wrapper<uint16_t, endian::big> wrapper = norm_v;
src.push_back(header+25);
for(auto byte : wrapper.bytes) {
for(auto byte : wrapper.bytes()) {
src.push_back(byte);
}
} else if(norm_v < (1ll<<32ll)) {
endian_wrapper<uint32_t, endian::big> wrapper = norm_v;
src.push_back(header+26);
for(auto byte : wrapper.bytes) {
for(auto byte : wrapper.bytes()) {
src.push_back(byte);
}
} else {
endian_wrapper<uint64_t, endian::big> wrapper = norm_v;
src.push_back(header+27);
for(auto byte : wrapper.bytes) {
for(auto byte : wrapper.bytes()) {
src.push_back(byte);
}
}
@ -477,4 +477,3 @@ namespace gp {
}
}
}

+ 72
- 66
include/gp/math/boolean/bitops.hpp View File

@ -2,79 +2,85 @@
#include "gp/containers/array.hpp"
#include <bit>
#include <stddef.h>
#include <stdint.h>
namespace gp{
namespace _impl{
constexpr uint32_t uint32_ = 0x01020304;
constexpr uint8_t magic_ = (const uint8_t&)uint32_;
}
namespace gp {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfour-char-constants"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmultichar"
enum class endian : uint16_t
{
#ifdef _WIN32
little = 0,
big = 1,
native = little
#elseif defined(__BYTE_ORDER__)
little = __ORDER_LITTLE_ENDIAN__,
big = __ORDER_BIG_ENDIAN__,
native = __BYTE_ORDER__
#else
little = true,
big = false,
native = ('ABCD'==0x41424344UL)
};
#endif
#pragma GCC diagnostic pop
#pragma clang diagnostic pop
using endian = std::endian;
template <typename T>
T swap_endian(T value) noexcept {
union {
T v;
uint8_t u8[sizeof(T)];
} src, dest;
src.v = value;
template <typename T>
T swap_endian(T value)
{
union
{
T v;
uint8_t u8[sizeof(T)];
} src, dest;
for (size_t idx = 0;idx<sizeof(T);idx++) {
dest.u8[idx] = src.u8[sizeof(T)-idx-1];
}
src.v = value;
for (size_t idx = 0;idx<sizeof(T);idx++)
{
dest.u8[idx] = src.u8[sizeof(T)-idx-1];
}
return dest.v;
return dest.v;
}
template<typename T, endian mode = endian::big>
struct endian_wrapper {
T value = 0;
constexpr endian_wrapper() noexcept = default;
endian_wrapper(T v) noexcept
: value{adjust(v)} {}
endian_wrapper& operator=(T v) noexcept {
value = adjust(v);
return *this;
}
operator T() const noexcept {
return adjust(value);
}
template<typename T, endian mode = endian::big>
struct endian_wrapper {
union{
T value;
auto bytes() const noexcept -> gp::array<uint8_t, sizeof(T)> {
union {
T t;
gp::array<uint8_t, sizeof(T)> bytes;
};
endian_wrapper(){};
endian_wrapper(T v) : value{
mode == endian::native ? v : swap_endian(v)
}{}
endian_wrapper(endian_wrapper& v) : value{
v.value
}{}
endian_wrapper& operator=(T p) {
value = mode == endian::native ? p : swap_endian(p);
return *this;
}
operator T(){
return mode == endian::native ? value : swap_endian(value);
}
};
}
} tmp {.t = value};
return tmp.bytes;
}
// arithmetic assignment operators
endian_wrapper& operator+=(T rhs) noexcept {
value = adjust(adjust(value) + rhs);
return *this;
}
endian_wrapper& operator+=(endian_wrapper rhs) noexcept {
value = adjust(adjust(value) + adjust(rhs.value));
return *this;
}
endian_wrapper& operator-=(T rhs) noexcept {
value = adjust(adjust(value) - rhs);
return *this;
}
endian_wrapper& operator-=(endian_wrapper rhs) noexcept {
value = adjust(adjust(value) - adjust(rhs.value));
return *this;
}
private:
T adjust(T x) const noexcept {
return (mode == endian::native ? x : swap_endian(x));
}
};
}

Loading…
Cancel
Save