#include <cstddef>
#include <cstdint>
#include <iostream>
template<size_t bytesLeft>
void doXor(void *p1, void *p2) {
if constexpr(bytesLeft >= 8) {
*reinterpret_cast<uint64_t*>(p1) ^= *reinterpret_cast<uint64_t*>(p2);
doXor<bytesLeft - 8>(reinterpret_cast<uint8_t*>(p1) + 8, reinterpret_cast<uint8_t*>(p2) + 8);
} else if constexpr(bytesLeft >= 4) {
*reinterpret_cast<uint32_t*>(p1) ^= *reinterpret_cast<uint32_t*>(p2);
doXor<bytesLeft - 4>(reinterpret_cast<uint8_t*>(p1) + 4, reinterpret_cast<uint8_t*>(p2) + 4);
} else if constexpr(bytesLeft != 0) {
*reinterpret_cast<uint8_t*>(p1) ^= *reinterpret_cast<uint8_t*>(p2);
doXor<bytesLeft - 1>(reinterpret_cast<uint8_t*>(p1) + 1, reinterpret_cast<uint8_t*>(p2) + 1);
}
}
template<typename T>
T& operator^=(T& a, T& b) {
doXor<sizeof(T)>(&a, &b);
return a;
}
struct A {
uint64_t a;
uint64_t b;
uint64_t c;
uint64_t d;
};
int main() {
A a{1,2,3,4};
A b{5,6,7,8};
std::cout << a.a << " " << a.b << " " << a.c << " " << a.d << std::endl;
std::cout << b.a << " " << b.b << " " << b.c << " " << b.d << std::endl;
a ^= b;
b ^= a;
a ^= b;
std::cout << a.a << " " << a.b << " " << a.c << " " << a.d << std::endl;
std::cout << b.a << " " << b.b << " " << b.c << " " << b.d << std::endl;
}
I2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDxjc3RkaW50PgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZTxzaXplX3QgYnl0ZXNMZWZ0Pgp2b2lkIGRvWG9yKHZvaWQgKnAxLCB2b2lkICpwMikgewoJaWYgY29uc3RleHByKGJ5dGVzTGVmdCA+PSA4KSB7CgkJKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDY0X3QqPihwMSkgXj0gKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDY0X3QqPihwMik7CgkJZG9Yb3I8Ynl0ZXNMZWZ0IC0gOD4ocmVpbnRlcnByZXRfY2FzdDx1aW50OF90Kj4ocDEpICsgOCwgcmVpbnRlcnByZXRfY2FzdDx1aW50OF90Kj4ocDIpICsgOCk7Cgl9IGVsc2UgaWYgY29uc3RleHByKGJ5dGVzTGVmdCA+PSA0KSB7CgkJKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDMyX3QqPihwMSkgXj0gKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDMyX3QqPihwMik7CgkJZG9Yb3I8Ynl0ZXNMZWZ0IC0gND4ocmVpbnRlcnByZXRfY2FzdDx1aW50OF90Kj4ocDEpICsgNCwgcmVpbnRlcnByZXRfY2FzdDx1aW50OF90Kj4ocDIpICsgNCk7Cgl9IGVsc2UgaWYgY29uc3RleHByKGJ5dGVzTGVmdCAhPSAwKSB7CgkJKnJlaW50ZXJwcmV0X2Nhc3Q8dWludDhfdCo+KHAxKSBePSAqcmVpbnRlcnByZXRfY2FzdDx1aW50OF90Kj4ocDIpOwoJCWRvWG9yPGJ5dGVzTGVmdCAtIDE+KHJlaW50ZXJwcmV0X2Nhc3Q8dWludDhfdCo+KHAxKSArIDEsIHJlaW50ZXJwcmV0X2Nhc3Q8dWludDhfdCo+KHAyKSArIDEpOwoJfQp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpUJiBvcGVyYXRvcl49KFQmIGEsIFQmIGIpIHsKCWRvWG9yPHNpemVvZihUKT4oJmEsICZiKTsKCXJldHVybiBhOwp9CgpzdHJ1Y3QgQSB7Cgl1aW50NjRfdCBhOwoJdWludDY0X3QgYjsKCXVpbnQ2NF90IGM7Cgl1aW50NjRfdCBkOwp9OwoKaW50IG1haW4oKSB7CglBIGF7MSwyLDMsNH07CglBIGJ7NSw2LDcsOH07CgoJc3RkOjpjb3V0IDw8IGEuYSA8PCAiICIgPDwgYS5iIDw8ICIgIiA8PCBhLmMgPDwgIiAiIDw8IGEuZCA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgYi5hIDw8ICIgIiA8PCBiLmIgPDwgIiAiIDw8IGIuYyA8PCAiICIgPDwgYi5kIDw8IHN0ZDo6ZW5kbDsKCglhIF49IGI7CgliIF49IGE7CglhIF49IGI7CgoJc3RkOjpjb3V0IDw8IGEuYSA8PCAiICIgPDwgYS5iIDw8ICIgIiA8PCBhLmMgPDwgIiAiIDw8IGEuZCA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgYi5hIDw8ICIgIiA8PCBiLmIgPDwgIiAiIDw8IGIuYyA8PCAiICIgPDwgYi5kIDw8IHN0ZDo6ZW5kbDsKfQ==
prog.cpp: In function ‘void doXor(void*, void*)’:
prog.cpp:7:5: error: expected ‘(’ before ‘constexpr’
if constexpr(bytesLeft >= 8) {
^~~~~~~~~
prog.cpp:10:4: error: ‘else’ without a previous ‘if’
} else if constexpr(bytesLeft >= 4) {
^~~~
prog.cpp:10:12: error: expected ‘(’ before ‘constexpr’
} else if constexpr(bytesLeft >= 4) {
^~~~~~~~~
prog.cpp:13:4: error: ‘else’ without a previous ‘if’
} else if constexpr(bytesLeft != 0) {
^~~~
prog.cpp:13:12: error: expected ‘(’ before ‘constexpr’
} else if constexpr(bytesLeft != 0) {
^~~~~~~~~