Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
bibmaster opened this issue Aug 9, 2023 · 4 comments
Open

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

bibmaster opened this issue Aug 9, 2023 · 4 comments

Comments

@bibmaster
Copy link

bibmaster commented Aug 9, 2023

Добавить маркер 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);
@kin4stat
Copy link

kin4stat commented Aug 9, 2023

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

@bibmaster
Copy link
Author

bibmaster commented Aug 9, 2023

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

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

@vtopunov
Copy link

vtopunov commented Aug 9, 2023

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

@bibmaster
Copy link
Author

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants