Кресты / Говнокод #26908 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
void Argument::parseAsInt()
{
    auto res = std::from_chars(data.data(), data.data() + data.size(), dataInt);
    if (res.ec == std::errc()) {
        setTypeFlag(ArgType::Int);
    }
}

void Argument::parseAsFloat()
{
    // Rww: gcc still does not support float from_chars(), lol
    const char *begin = data.data();
    const char *end = begin + data.size();
    char *endPtr = nullptr;

    dataFloat = std::strtof(begin, &endPtr);
    if (endPtr == end || dataFloat != 0.0f) {
        setTypeFlag(ArgType::Float);
    } else {
        for (const char *it = endPtr; it < end; it++) {
            if (!std::isspace(*it)) {
                return;
            }
        }
        setTypeFlag(ArgType::Float);
    }
}

Говнокодил тут недавно, долго думал, что считать числом (пет, ТЗ нет). В конце-концов решил считать всё, что можно распарсить.

Запостил: gost gost, (Updated )

Комментарии (14) RSS

  • > // Rww: gcc still does not support float from_chars(), lol
    Такова участь крестобляди.
    Ответить
  • > setTypeFlag
    - а что это за функция? Дока не гуглится по ней
    Ответить
      • А, тупо задаёт тип прочитанного значения?

        А то я подумал, что это какая-то стандартная крестометушня, чтобы подсказывать компилятору, с каким типом мы щас будем работать или в этом духе
        Ответить
        • пс-пс, в крестах нету типа "Float". И "Int". И "ArgTypes" тоже нету. Это всё выдумки госта
          Ответить
      • Подтверждаю. «Argument» — это самописный класс от парсера команд, а в этих методах определяется тип аргумента.
        Ответить
  • > gcc still does not support

    Вот интересно на самом деле, в чем сложность реализации этих функций. Чел из майкрософта пишет, что он на основе готового strtod месяц (!) пилил реализацию для их либы.

    Понятно, что парсинг флоата это нетривиальная задача. Но она ведь уже давным-давно решена в сишке. И наборы тестов там уже есть.
    Ответить
    • Хуй пойми. Для плавающих питухов в «MSVCRT» есть три перегрузки:
      inline from_chars_result from_chars(const char* const _First, const char* const _Last, float& _Value,
          const chars_format _Fmt = chars_format::general) noexcept /* strengthened */ {
          return _Floating_from_chars(_First, _Last, _Value, _Fmt);
      }
      inline from_chars_result from_chars(const char* const _First, const char* const _Last, double& _Value,
          const chars_format _Fmt = chars_format::general) noexcept /* strengthened */ {
          return _Floating_from_chars(_First, _Last, _Value, _Fmt);
      }
      inline from_chars_result from_chars(const char* const _First, const char* const _Last, long double& _Value,
          const chars_format _Fmt = chars_format::general) noexcept /* strengthened */ {
          double _Dbl; // intentionally default-init
          const from_chars_result _Result = _Floating_from_chars(_First, _Last, _Dbl, _Fmt);
      
          if (_Result.ec == errc{}) {
              _Value = _Dbl;
          }
      
          return _Result;
      }
      Ответить
      • И сама реализация:
        template <class _Floating>
        _NODISCARD from_chars_result _Floating_from_chars(
            const char* const _First, const char* const _Last, _Floating& _Value, const chars_format _Fmt) noexcept {
            _Adl_verify_range(_First, _Last);
        
            _STL_ASSERT(_Fmt == chars_format::general || _Fmt == chars_format::scientific || _Fmt == chars_format::fixed
                            || _Fmt == chars_format::hex,
                "invalid format in from_chars()");
        
            bool _Minus_sign = false;
        
            const char* _Next = _First;
        
            if (_Next == _Last) {
                return {_First, errc::invalid_argument};
            }
        
            if (*_Next == '-') {
                _Minus_sign = true;
                ++_Next;
        
                if (_Next == _Last) {
                    return {_First, errc::invalid_argument};
                }
            }
        // продолжение следует
        Ответить
        • // Distinguish ordinary numbers versus inf/nan with a single test.
              // ordinary numbers start with ['.'] ['0', '9'] ['A', 'F'] ['a', 'f']
              // inf/nan start with ['I'] ['N'] ['i'] ['n']
              // All other starting characters are invalid.
              // Setting the 0x20 bit folds these ranges in a useful manner.
              // ordinary (and some invalid) starting characters are folded to ['.'] ['0', '9'] ['a', 'f']
              // inf/nan starting characters are folded to ['i'] ['n']
              // These are ordered: ['.'] ['0', '9'] ['a', 'f'] < ['i'] ['n']
              // Note that invalid starting characters end up on both sides of this test.
              const unsigned char _Folded_start = static_cast<unsigned char>(static_cast<unsigned char>(*_Next) | 0x20);
          
              if (_Folded_start <= 'f') { // possibly an ordinary number
                  return _Ordinary_floating_from_chars(_First, _Last, _Value, _Fmt, _Minus_sign, _Next);
              } else if (_Folded_start == 'i') { // possibly inf
                  return _Infinity_from_chars(_First, _Last, _Value, _Minus_sign, _Next);
              } else if (_Folded_start == 'n') { // possibly nan
                  return _Nan_from_chars(_First, _Last, _Value, _Minus_sign, _Next);
              } else { // definitely invalid
                  return {_First, errc::invalid_argument};
              }
          }
          Ответить
      • Ну я почитал в мейл листе гцц - они пишут, что реализация должна порвать принтфы и стртоды в клочья. Иначе нету смысла её пилить и можно просто сишную позвать.
        Ответить
          • Ага. Но сишники ведь потом обратно это портанут. Языки то одинаковые почти, по крайней мере в битоёбстве.
            Ответить

Добавить комментарий для guest Отменить ответ

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8