cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

constexpr std::regex #312

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +46, -1 Автор идеи: yndx-antoshkka

Множество языков программирования в данный момент компилируют/транслируют регулярные выражения ещё перед запуском программы. Таким образом, когда программа стартует, все регулярные выражения уже преобразованы в соптимизированный конечный автомат.

Предлагаю добавить подобную возможность и для C++.

bool is_valid_mail(std::string_view mail) {
    static const std::regex mail_regex(R"((?:(?:[^<>()\[\].,;:\s@\"]+(?:\.[^<>()\[\].,;:\s@\"]+)*)|\".+\")@(?:(?:[^<>()\[\].,;:\s@\"]+\.)+[^<>()\[\].,;:\s@\"]{2,}))");

    return std::regex_match(
        std::cbegin(mail),
        std::cend(mail),
        mail_regex
    );
}

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

С готовящимися новинками для constexpr вычислений (constexpr new, is_constexpr_evaluated() и др.) можно будет в C++20 делать множество вещей на этапе компиляции, в том числе можно будет сделать constexpr std::regex.

С constexpr std::regex конечный автомат для функции is_valid_mail() построится ещё на этапе компиляции. Более того, GCC сможет генерировать оптимизированные регулярки на этапе компиляции без static const, т.к. начиная с GCC-6 если у constexpr функции все параметры на вход — константы, GCC форсирует вычисление на этапе компиляции. Багрепорт на добавление аналогично функционала в Clang уже есть

apolukhin commented 3 years ago

Виктор Губин, 14 июня 2018, 13:07 Т.е. - смержить regexp (бывший boost regexp) и boost xpressive, или заменить реализацию на xpressive с портированием на С++ 20 без MPL, или заставить компилятор генерировать код конечного автомата на этапе компиляции наподобие Bison или Antlr только сразу в машинных кодах? У xpressive и Spirit есть существенные недостатки - очень внушительное время компиляции, сложность определения ошибки в регулярном выражении и т.п. (ко всему нельзя отключить исключения и RTTI, т.е. Проблемы для embedded/device drivers/kernel development и т.п.)

yndx-antoshkka, 14 июня 2018, 18:13 Виктор Губин, да, заставить компилятор генерировать код конечного автомата в машинных кодах на этапе компиляции. При этом бинарная совместимость и все имеющиеся интерфесы [boost|std]::regex останутся старыми.

neondev9, 16 июня 2018, 12:12 Добрый день. Немного не по теме, но где можно почитать про constexpr новинки?

yndx-antoshkka, 5 июля 2018, 12:43 neondev9, либо вот тут выискивать нужные бумаги.

Либо можно обзоры новинок брать из постов на хабре (пример).

Evgeny Basargin, 18 июля 2018, 17:57 и литерал до кучи std::literals::regex_literals::operator""r

apolukhin commented 3 years ago

std::regex слишком сломан... в комитете не особо желают его чинить.

Вместо этого, Hana Dusíková предлагает создать отдельный тип для регулярных выражений с constexpr посторением автомата в https://wg21.link/P1433