fork download
  1. #include <cstddef>
  2. #include <cstdint>
  3. #include <iostream>
  4.  
  5. template<size_t bytesLeft>
  6. void doXor(void *p1, void *p2) {
  7. *reinterpret_cast<uint64_t*>(p1) ^= *reinterpret_cast<uint64_t*>(p2);
  8. doXor<bytesLeft - 8>(reinterpret_cast<uint8_t*>(p1) + 8, reinterpret_cast<uint8_t*>(p2) + 8);
  9. }
  10. template<>
  11. void doXor<0>(void*, void*) {}
  12. template<>
  13. void doXor<1>(void *p1, void *p2) {
  14. *reinterpret_cast<uint8_t*>(p1) ^= *reinterpret_cast<uint8_t*>(p2);
  15. }
  16. template<>
  17. void doXor<2>(void *p1, void *p2) {
  18. *reinterpret_cast<uint8_t*>(p1) ^= *reinterpret_cast<uint8_t*>(p2);
  19. *(reinterpret_cast<uint8_t*>(p1) + 1) ^= *(reinterpret_cast<uint8_t*>(p2) + 1);
  20. }
  21. template<>
  22. void doXor<3>(void *p1, void *p2) {
  23. *reinterpret_cast<uint8_t*>(p1) ^= *reinterpret_cast<uint8_t*>(p2);
  24. *(reinterpret_cast<uint8_t*>(p1) + 1) ^= *(reinterpret_cast<uint8_t*>(p2) + 1);
  25. *(reinterpret_cast<uint8_t*>(p1) + 2) ^= *(reinterpret_cast<uint8_t*>(p2) + 2);
  26. }
  27. template<>
  28. void doXor<4>(void *p1, void *p2) {
  29. *reinterpret_cast<uint32_t*>(p1) ^= *reinterpret_cast<uint32_t*>(p2);
  30. }
  31. template<>
  32. void doXor<5>(void *p1, void *p2) {
  33. *reinterpret_cast<uint32_t*>(p1) ^= *reinterpret_cast<uint32_t*>(p2);
  34. doXor<1>(reinterpret_cast<uint8_t*>(p1) + 4, reinterpret_cast<uint8_t*>(p2) + 4);
  35. }
  36. template<>
  37. void doXor<6>(void *p1, void *p2) {
  38. *reinterpret_cast<uint32_t*>(p1) ^= *reinterpret_cast<uint32_t*>(p2);
  39. doXor<2>(reinterpret_cast<uint8_t*>(p1) + 4, reinterpret_cast<uint8_t*>(p2) + 4);
  40. }
  41. template<>
  42. void doXor<7>(void *p1, void *p2) {
  43. *reinterpret_cast<uint32_t*>(p1) ^= *reinterpret_cast<uint32_t*>(p2);
  44. doXor<3>(reinterpret_cast<uint8_t*>(p1) + 4, reinterpret_cast<uint8_t*>(p2) + 4);
  45. }
  46.  
  47. template<typename T>
  48. T& operator^=(T& a, T& b) {
  49. doXor<sizeof(T)>(&a, &b);
  50. return a;
  51. }
  52.  
  53. struct A {
  54. uint64_t a;
  55. uint64_t b;
  56. uint64_t c;
  57. uint64_t d;
  58. };
  59.  
  60. int main() {
  61. A a{1,2,3,4};
  62. A b{5,6,7,8};
  63.  
  64. std::cout << a.a << " " << a.b << " " << a.c << " " << a.d << std::endl;
  65. std::cout << b.a << " " << b.b << " " << b.c << " " << b.d << std::endl;
  66.  
  67. a ^= b;
  68. b ^= a;
  69. a ^= b;
  70.  
  71. std::cout << a.a << " " << a.b << " " << a.c << " " << a.d << std::endl;
  72. std::cout << b.a << " " << b.b << " " << b.c << " " << b.d << std::endl;
  73. }
Success #stdin #stdout 0s 4396KB
stdin
Standard input is empty
stdout
1 2 3 4
5 6 7 8
5 6 7 8
1 2 3 4