選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

88 行
2.5 KiB

  1. #pragma once
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <climits>
  5. #include <type_traits>
  6. // https://stackoverflow.com/a/263738
  7. /* a=target variable, b=bit number to act upon 0-n */
  8. #define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
  9. #define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
  10. #define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
  11. #define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1
  12. /* x=target variable, y=mask */
  13. #define BITMASK_SET(x,y) ((x) |= (y))
  14. #define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
  15. #define BITMASK_FLIP(x,y) ((x) ^= (y))
  16. #define BITMASK_CHECK_ALL(x,y) (!(~(x) & (y)))
  17. #define BITMASK_CHECK_ANY(x,y) ((x) & (y))
  18. namespace itsy_bitsy {
  19. template <std::size_t sz, typename C = void>
  20. struct bit_type {
  21. typedef uint64_t type;
  22. };
  23. template <std::size_t sz>
  24. struct bit_type<sz, std::enable_if_t<(sz <= 1)>> {
  25. typedef bool type;
  26. };
  27. template <std::size_t sz>
  28. struct bit_type<sz, std::enable_if_t<(sz > 2 && sz <= 16)>> {
  29. typedef uint16_t type;
  30. };
  31. template <std::size_t sz>
  32. struct bit_type<sz, std::enable_if_t<(sz > 16 && sz <= 32)>> {
  33. typedef uint32_t type;
  34. };
  35. template <std::size_t sz>
  36. struct bit_type<sz, std::enable_if_t<(sz > 32 && sz <= 64)>> {
  37. typedef uint64_t type;
  38. };
  39. template <std::size_t sz>
  40. using bit_type_t = typename bit_type<sz>::type;
  41. template <typename T, typename V>
  42. bool vcxx_warning_crap(std::true_type, V val) {
  43. return val != 0;
  44. }
  45. template <typename T, typename V>
  46. T vcxx_warning_crap(std::false_type, V val) {
  47. return static_cast<T>(val);
  48. }
  49. template <typename T, typename V>
  50. auto vcxx_warning_crap(V val) {
  51. return vcxx_warning_crap<T>(std::is_same<bool, T>(), val);
  52. }
  53. template <typename Base, std::size_t baseOffset = 0x0, std::size_t bit_target = 0x0, std::size_t size = 0x1>
  54. void write(Base& b, bit_type_t<size> bits) {
  55. uintptr_t baseAddr = reinterpret_cast<uintptr_t>(&b);
  56. uintptr_t offs = baseOffset;
  57. unsigned char* byt = reinterpret_cast<unsigned char*>(baseAddr + offs);
  58. char testb = *byt & (1 << bit_target);
  59. if (bits)
  60. BIT_SET(*byt, bit_target);
  61. else
  62. BIT_CLEAR(*byt, bit_target);
  63. }
  64. template <typename Base, std::size_t baseOffset = 0x0, std::size_t bit_target = 0x0, std::size_t size = 0x1>
  65. bit_type_t<size> read(Base& b) {
  66. uintptr_t baseAddr = reinterpret_cast<uintptr_t>(&b);
  67. uintptr_t offs = baseOffset;
  68. unsigned char* byt = reinterpret_cast<unsigned char*>(baseAddr + offs);
  69. char test = *byt & (1 << bit_target);
  70. if (test)
  71. return true;
  72. return false;
  73. }
  74. }