General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
  1. #pragma once
  2. #include <stdint.h>
  3. #include <stddef.h>
  4. namespace gp{
  5. namespace _impl{
  6. constexpr uint32_t uint32_ = 0x01020304;
  7. constexpr uint8_t magic_ = (const uint8_t&)uint32_;
  8. }
  9. #pragma clang diagnostic push
  10. #pragma clang diagnostic ignored "-Wfour-char-constants"
  11. #pragma GCC diagnostic push
  12. #pragma GCC diagnostic ignored "-Wmultichar"
  13. enum class endian : uint16_t
  14. {
  15. #ifdef _WIN32
  16. little = 0,
  17. big = 1,
  18. native = little
  19. #elseif defined(__BYTE_ORDER__)
  20. little = __ORDER_LITTLE_ENDIAN__,
  21. big = __ORDER_BIG_ENDIAN__,
  22. native = __BYTE_ORDER__
  23. #else
  24. little = true,
  25. big = false,
  26. native = ('ABCD'==0x41424344UL)
  27. };
  28. #endif
  29. #pragma GCC diagnostic pop
  30. #pragma clang diagnostic pop
  31. template <typename T>
  32. T swap_endian(T value)
  33. {
  34. union
  35. {
  36. T v;
  37. uint8_t u8[sizeof(T)];
  38. } src, dest;
  39. src.v = value;
  40. for (size_t idx = 0;idx<sizeof(T);idx++)
  41. {
  42. dest.u8[idx] = src.u8[sizeof(T)-idx-1];
  43. }
  44. return dest.v;
  45. }
  46. template<typename T, endian mode = endian::big>
  47. struct endian_wrapper {
  48. T value;
  49. endian_wrapper(){};
  50. endian_wrapper(T v) : value{
  51. mode == endian::native ? v : swap_endian(v)
  52. }{}
  53. endian_wrapper(endian_wrapper& v) : value{
  54. v.value
  55. }{}
  56. endian_wrapper& operator=(T p) {
  57. value = mode == endian::native ? p : swap_endian(p);
  58. return *this;
  59. }
  60. operator T(){
  61. return mode == endian::native ? value : swap_endian(value);
  62. }
  63. };
  64. }