Is there a way in c++ to get a different overload called based on the runtime/compile time constness of an input? My version(12) of MSVC can\'t do this using constexpr. Reading
To elaborate on my comment, you can try this to work around the limitation you're facing:
Run It Online
#include
using std::cout;
using std::endl;
template
constexpr int Flip4() {
return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) | ((n & 0xFF0000) >> 8) | ((n & 0xFF000000) >> 24);
}
inline int Flip4(int n) {
return _byteswap_ulong(n);
}
int main() {
constexpr int a = Flip4<0xabcd>(); // calc at compile time
int b = Flip4(0xabcd); // calc at runtime
static_assert(a == -844431360, "");
cout << "a: " << a << endl;
cout << "b: " << b << endl;
}
EDIT: Don't lose hope! User-defined literals are here to the rescue :)
Run It Online
#include
using std::cout;
using std::endl;
// wraps a single integer (unsigned long long) in order to use it in a user-defined literal
// the type (unsigned long long) is a limitation of the standard: https://stackoverflow.com/a/16596909/865719
struct IntegerWrapper
{
const unsigned long long value;
constexpr explicit IntegerWrapper(unsigned long long val) : value{val} {}
};
// user-defined literal
constexpr IntegerWrapper operator "" _iw (const unsigned long long value)
{
return IntegerWrapper{value};
}
constexpr int Flip4(IntegerWrapper&& n) {
return ((n.value & 0xFF) << 24) | ((n.value & 0xFF00) << 8) | ((n.value & 0xFF0000) >> 8) | ((n.value & 0xFF000000) >> 24);
}
inline int Flip4(int n) {
return _byteswap_ulong(n);
}
int main() {
constexpr int a = Flip4(0xabcd_iw); // calc at compile time
const int b = Flip4(0xabcd); // calc at runtime
static_assert(a == -844431360, "");
cout << "a: " << a << endl;
cout << "b: " << b << endl;
}