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