Re[2]: Как записать такое в современном C++?
От: Alekzander  
Дата: 20.06.23 06:23
Оценка:
Здравствуйте, BSOD, Вы писали:

A>>Как это записать в современном C++, чтобы не было performance penalty? Без конструирования контейнера и т.п. Нормальных макросов же (как в Немерле), насколько я понимаю, не завезли?


BSO>
BSO>switch(errno)
BSO>    case EAGAIN:
BSO>    case EWOULDBLOCK:
BSO>    case EINTR:
BSO>    case ENOSPC:
BSO>    case ENOBUFS:
BSO>    case ENOMEM:
BSO>    {...}
BSO>


Выше написали, что при дублировании будет ошибка компиляции. А от себя добавлю, что ! выражать через default это верный способ сделать больше ошибок, а не меньше.
Re[5]: Как записать такое в современном C++?
От: Maniacal Россия  
Дата: 20.06.23 08:05
Оценка: +1
Здравствуйте, Alekzander, Вы писали:

A>Чего только нет в std... Ничего нет!


Похоже на отсылку к Жванецкому

У нас чего только может не быть. У нас всего может не быть. У нас чего только не захочешь, того может и не быть.

— Михаил Жванецкий
Re: Как записать такое в современном C++?
От: Dair Россия https://dair.spb.ru
Дата: 20.06.23 08:39
Оценка:
Здравствуйте, Alekzander, Вы писали:

A> if (!(errno == EAGAIN || EWOULDBLOCK ||

A> errno == EINTR || errno == ENOSPC ||
A> errno == ENOBUFS || errno == ENOMEM)) {

Коллеги выше красиво написали, но почему-то упустили тот факт, что EWOULDBLOCK не находится в списке значений, которые не должен принимать errno.
Re[2]: Как записать такое в современном C++?
От: Sm0ke Россия ksi
Дата: 30.06.23 19:13
Оценка: 2 (1)
Здравствуйте, Dair, Вы писали:

D>Здравствуйте, Alekzander, Вы писали:


A>> if (!(errno == EAGAIN || EWOULDBLOCK ||

A>> errno == EINTR || errno == ENOSPC ||
A>> errno == ENOBUFS || errno == ENOMEM)) {

D>Коллеги выше красиво написали, но почему-то упустили тот факт, что EWOULDBLOCK не находится в списке значений, которые не должен принимать errno.


Этот фрагмент, как упоминается в исходной статье от студии PVS, содержит ошибку.

В исправленной версии там именно сравнение с errno.
Re[2]: Как записать такое в современном C++?
От: Sm0ke Россия ksi
Дата: 30.06.23 19:18
Оценка:
Здравствуйте, vopl, Вы писали:

V>например


V>
V>#include <errno.h>

V>template <auto... set>
V>bool isin(auto val)
V>{
V>    return (false || ... || (set == val));
V>}

V>int main() 
V>{
V>    // 
V>    if(isin<EAGAIN,
V>            EWOULDBLOCK,
V>            EINTR,
V>            ENOSPC,
V>            ENOBUFS,
V>            ENOMEM>(errno))
V>    {
V>        return 0;
V>    }

V>    return 1;
V>}
V>


Вот бы уменьшить число сравнений с помощью бинарного поиска в упорядоченном ряде значений.
Взять какой-нибудь constexpr set и вызвать метод contains().

Есть например https://github.com/serge-sans-paille/frozen , но я его не пробовал.
Отредактировано 30.06.2023 19:19 Sm0ke . Предыдущая версия .
Re: Как записать такое в современном C++?
От: B0FEE664  
Дата: 03.07.23 13:30
Оценка: 3 (1)
Здравствуйте, Alekzander, Вы писали:

A>Как это записать в современном C++, чтобы не было performance penalty?


Для такого случая у меня есть специальный класс:
template<class T>
class The
{
    public:
        constexpr explicit The(const T& x) noexcept
          : _x(x)
        {
        }

        template <class... TArgs>
        bool one_of(TArgs&&... args) const
        {
            return ((_x == args) || ...);
        }

        template <auto... VArgs>
        bool one_of() const
        {
            return ((_x == VArgs) || ...);
        }

    public:
        const T& _x;
};


На мой взгляд такой код легче читать, чем вариант с функцией
Автор: vopl
Дата: 17.06.23
:
int main() 
{
    // 
    if ( The(errno).one_of<
                           EAGAIN,
                           EWOULDBLOCK,
                           EINTR,
                           ENOSPC,
                           ENOBUFS,
                           ENOMEM
                         >()
       )
    {
        return 0;
    }

    return 1;
}
И каждый день — без права на ошибку...
Re[2]: Как записать такое в современном C++?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.07.23 14:22
Оценка:
Здравствуйте, BSOD, Вы писали:

BSO>switch(errno)

BSO> case EAGAIN:
BSO> case EWOULDBLOCK:
BSO> case EINTR:
BSO> case ENOSPC:
BSO> case ENOBUFS:
BSO> case ENOMEM:
BSO> {...}

Тут есть одна проблемка: на большинстве систем коды EAGAIN и EWOULDBLOCK сейчас совпадают (такое вот легаси), но есть специфические, где они различны. При совпадении switch выдаёт ошибку.
Можно проверять препроцессором, но это ещё больше левых слов.
А в варианте с == проблемы не возникает
The God is real, unless declared integer.
Re[3]: Как записать такое в современном C++?
От: kov_serg Россия  
Дата: 03.07.23 15:46
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Вот бы уменьшить число сравнений с помощью бинарного поиска в упорядоченном ряде значений.

S>Взять какой-нибудь constexpr set и вызвать метод contains().
C++ и так это способен оптимизировать до битовых полей, что бы сравнивать группами.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.