OT Ceckarsky kviz
Miroslav Mraz
mrazik na volny.cz
Pátek Leden 28 09:59:36 CET 2022
Nedalo mi to, přepsal jsem to podle specifikace, takže by to měly sežrat
i běžné překladače jako je g++.
namespace hex { // jen tak pro srandu to obalíme namespace, ale je to
zbytečné
// 2. pomocná funkce pro operátor _h, aby to bylo trochu čitelnější.
static constexpr unsigned long hexa_c (const char c, const unsigned
long k) {
return (c >= '0') and (c <= '9') ? k * 0x10ul + c - '0' :
(c >= 'a') and (c <= 'f') ? k * 0x10ul + c - 'a' + 10 : k;
}
// 1. pomocná funkce pro operátor _h, je použita rekurze místo cyklu,
ale to je v pořádku.
static constexpr unsigned long hexa_r (const char * const str, const
size_t n, const unsigned long m, const size_t i) {
return i == n ? m : hexa_r (str, n, hexa_c (str [i] | '\x20', m), i
+ 1ul);
}
};
// Vlastní definice operátoru podle specifikace - constexpr funkce sice
mohou obsahovat jen return ale ternární ? nevadí
static constexpr unsigned long operator"" _h (const char * const str,
size_t n) {
return hex::hexa_r (str, n, 0ul, 0ul);
}
Je vidět, že je to docela divoké, ostatně optimalizace takové bývají.
Mrazík
Dne 27. 01. 22 v 14:46 Miroslav Mraz napsal(a):
> ...
>
> static constexpr unsigned long operator"" _h (const char * const str,
> size_t n) {
> unsigned long result = 0ul;
> for (unsigned i=0u; i<n; i++) {
> const char c = str [i] | '\x20'; // to lowercase
> if ((c >= '0') and (c <= '9')) {
> result *= 0x10ul;
> result += c - '0';
> } else if ((c >= 'a') and (c <= 'f')) {
> result *= 0x10ul;
> result += c - 'a' + 10;
> } // ostatni znaky jako je '_' ignoruj
> }
> return result;
> }
Další informace o konferenci Hw-list