ideas icon indicating copy to clipboard operation
ideas copied to clipboard

Автоматические BitmaskType для scoped enum

Open bibmaster opened this issue 2 years ago • 4 comments

Добавить маркер bitmask для scoped enum.

В стандарте есть различные scoped enum удовлетворяющие требованиям BitmaskType. Но реализация этих требований выливается в большое количество boilerplate кода. Примеры: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/fs_fwd.h#L165 https://github.com/microsoft/STL/blob/ed8150e099f6124c50dd4f002cd2ab8c429a81e3/stl/inc/type_traits#L2270

Предлагается переложить эту работу на компилятор, явно указав допустимость выполненения битовых операций со значениями enum. Во избежание добавления новых ключевых слов можно расширить enum-key. Сейчас это one of enum, enum class, or enum struct, добавить enum union

enum union perms

При этом предполагается что операции вида Enum::x <op> Enum::y будут эквивалентны следующему коду:

static_cast<Enum>(static_cast<undelying_type_t<Enum>>(x) <op> static_cast<underlying_type_t<Enum>>(y))

Вторая проблема с использованием scoped enum в качестве bitmask это проверки на 0. Пример из gcc:

namespace
{
  template<typename Bitmask>
    inline bool
    is_set(Bitmask obj, Bitmask bits)
    {
      return (obj & bits) != Bitmask::none;
    }
}

Предлагается для значений bitmask enum использовать правила explicit bool conversion аналогичные таковым для соотвествующих underlying type.

// Было
if(is_set(mask, options::x))
if((mask & options::x) != options::none)

// Стало
if(mask & options::x)

Дополнительно можно добавить concept Bitmask и функцию проверки

template<Bitmask T> constexpr bool std::is_set(T mask, T bits)

bool x_enabled = std::is_set(mask, option::x);

bibmaster avatar Aug 09 '23 10:08 bibmaster

Проблема в том, что атрибуты - опциональны. Тут нужен кейворд, или что-то подобное

kin4stat avatar Aug 09 '23 11:08 kin4stat

Проблема в том, что атрибуты - опциональны. Тут нужен кейворд, или что-то подобное

Ok, пусть будет например enum union вместо enum class

bibmaster avatar Aug 09 '23 11:08 bibmaster

А может лучше Bitmask operator & (Bitmask, Bitmask) = default; и constexpr bool is_set(Bitmask obj, Bitmask bits) noexcept { return (obj & bits) == bits; }

vtopunov avatar Aug 09 '23 20:08 vtopunov

А может лучше Bitmask operator & (Bitmask, Bitmask) = default; и constexpr bool is_set(Bitmask obj, Bitmask bits) noexcept { return (obj & bits) == bits; }

Ну так то можно это всё и в макрос завернуть, но лучший код тот которого нет. С теми же default всё равно же придется расписать &,|,^,~. А с contextual bool conversion вообще никак не решить вручную. Ну и компиляторам легче, не нужно вообще ничего искать, сам тип содержит информацию о возможности битовых операций.

bibmaster avatar Aug 09 '23 22:08 bibmaster