This increases the indentation of function's main logic by 1 level,
which is a bad thing in my book.
Anyway, I do not like any of the shown variants very much, they remind
me C style too much (or for Alf's variant, Pascal) where 95% of code is
dedicated for error checking and handling. In C++ we can have main logic
clear and visible, with error checking still there, but not taking the
most prominent place. Maybe something like that (you can see I still
prefer 'continue;' over an extra indentation level in main logic):
inline constexpr Uint_128 operator""_u128( const char* spec) {
Uint_128 result = 0;
for (int i = 0; spec[i]; ++i ) {
if (Preprocess(spec[i])) {
continue;
}
// actual work
result = result*10 + (spec[i] - '0');
}
return result;
}
// Range checking, error handling, and trivial preprocessing
// tucked away from the main logic.
inline constexpr bool Preprocess(char ch) {
if (ch == '\'') {
// processed fully
return true;
}
if (ch<'0' || ch>'9') {
throw runtime_error(
"Invalid character ‘"s << ch << "’ in _u128 literal."
);
}
// not processed
return false;
}