Типизированные флаги - что сейчас есть?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 27.05.19 17:01
Оценка:
Здравствуйте!

Вроде в новых стандартах появились всякие вкусные enum class'ы. Это конечно здорово, но что может предложить в 19ом году современная конструкторскаясипипишная мысль по поводу типизированных флагов?
Хочется всякие битовые операции производить максимально оптимально даже на всяких глупых компиляторах, и чтобы нельзя было так просто взять и подсунуть какой-нибудь подходящий по размеру по размеру int
Маньяк Робокряк колесит по городу
Re: Типизированные флаги - что сейчас есть?
От: PM  
Дата: 28.05.19 05:36
Оценка: 12 (2)
Здравствуйте, Marty, Вы писали:

M>Вроде в новых стандартах появились всякие вкусные enum class'ы. Это конечно здорово, но что может предложить в 19ом году современная конструкторскаясипипишная мысль по поводу типизированных флагов?

M>Хочется всякие битовые операции производить максимально оптимально даже на всяких глупых компиляторах, и чтобы нельзя было так просто взять и подсунуть какой-нибудь подходящий по размеру по размеру int

Для `enum class` можно объявлять пользовательские операторы | ^ & ~ внутри которых аргументы приводится к `std::underlying_type`, на полученном целочисленном типе выполняются битовые операции, результат перед возвратом приводится назад к типу `enum class`.

Чтобы не писать для каждого `enum class` пачку одних и тех же операторов, делают их шаблонными и разрешают через SFINAE только для определенных типов.

Типа такого: https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
Re: Типизированные флаги - что сейчас есть?
От: so5team https://stiffstream.com
Дата: 28.05.19 05:56
Оценка:
Здравствуйте, Marty, Вы писали:

M>Это конечно здорово, но что может предложить в 19ом году современная конструкторскаясипипишная мысль по поводу типизированных флагов?

M>Хочется всякие битовые операции производить максимально оптимально даже на всяких глупых компиляторах, и чтобы нельзя было так просто взять и подсунуть какой-нибудь подходящий по размеру по размеру int

Можно посмотреть на библиотеку type_safe. В частности на strong_typedef оттуда (здесь немного пояснений от автора библиотеки).
Re[2]: Типизированные флаги - что сейчас есть?
От: B0FEE664  
Дата: 28.05.19 11:08
Оценка:
Здравствуйте, PM, Вы писали:

PM>Для `enum class` можно объявлять пользовательские операторы | ^ & ~ внутри которых аргументы приводится к `std::underlying_type`, на полученном целочисленном типе выполняются битовые операции, результат перед возвратом приводится назад к типу `enum class`.


PM>Чтобы не писать для каждого `enum class` пачку одних и тех же операторов, делают их шаблонными и разрешают через SFINAE только для определенных типов.


А вот зачем так делать? Ведь, казалось бы, наконец ввели строгое типизирование для энумов, чтобы их нельзя было использовать не по назначению — и всё равно, в двадцать первом веке люди продолжают путать перечисления с битовыми полями. Не понимаю я этого. Для меня это всё равно, что целые числа во float хранить.

PM>Типа такого: https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html


Там первый комментарий, IMHO, правильный.
И каждый день — без права на ошибку...
Re: Типизированные флаги - что сейчас есть?
От: ononim  
Дата: 28.05.19 15:23
Оценка:
M>Хочется всякие битовые операции производить максимально оптимально даже на всяких глупых компиляторах, и чтобы нельзя было так просто взять и подсунуть какой-нибудь подходящий по размеру по размеру int
struct с битовыми полями?
Как много веселых ребят, и все делают велосипед...
Re[2]: Типизированные флаги - что сейчас есть?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 28.05.19 17:05
Оценка:
Здравствуйте, ononim, Вы писали:

M>>Хочется всякие битовые операции производить максимально оптимально даже на всяких глупых компиляторах, и чтобы нельзя было так просто взять и подсунуть какой-нибудь подходящий по размеру по размеру int

O>struct с битовыми полями?

Поподробнее можно?
Маньяк Робокряк колесит по городу
Re[3]: Типизированные флаги - что сейчас есть?
От: PM  
Дата: 28.05.19 21:18
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>А вот зачем так делать? Ведь, казалось бы, наконец ввели строгое типизирование для энумов, чтобы их нельзя было использовать не по назначению — и всё равно, в двадцать первом веке люди продолжают путать перечисления с битовыми полями. Не понимаю я этого. Для меня это всё равно, что целые числа во float хранить.


Ну да, не очень однозначное применение. Но в отличие от целочисленных значений, с `enum class` мы имеем явно ограниченный набор операторов, без целочисленной арифметики. Лично для меня не проблема, что значения могут выходить за пределы перечисленных в class enum, т.к. в конечном итоге все равно требуется знать факт, установлен какой-то флаг из набора заданных, или нет. Упомянутая выше бибилиотека type_safe вроде бы реализует набор флагов как strong typedef.

А битовые поля для меня это такое
struct flags
{
    uint32_t A : 1;
    uint32_t B : 1;
};


Можно конечно использовать как набор флагов, но как-то не очень надежно при объявлении, и не уверен что на 100% переносимо.
Re[3]: Типизированные флаги - что сейчас есть?
От: ononim  
Дата: 29.05.19 07:29
Оценка:
M>>>Хочется всякие битовые операции производить максимально оптимально даже на всяких глупых компиляторах, и чтобы нельзя было так просто взять и подсунуть какой-нибудь подходящий по размеру по размеру int
O>>struct с битовыми полями?
M>Поподробнее можно?
#include <stdio.h>
#include <stdlib.h>

struct Flags
{
        bool enabled : 1;
        enum Color
        {
                BLACK,
                RED,
                BLUE,
                GREEN
        } color : 2;
        unsigned int value : 29;
};


void Foobar(Flags flags)
{
        printf("sizeof(flags)=%d\n", (int)sizeof(flags));
        printf("enabled=%d\n", flags.enabled);
        printf("color=%d\n", flags.color);
        printf("value=%d\n", flags.value);
}

int main(int argc, char **argv)
{
        Flags flags = {};
        flags.enabled = (argc >=2 ) ? atoi(argv[1]) : true;
        flags.color = (argc >= 3) ? (Flags::Color)atoi(argv[2]) : Flags::BLUE;
        flags.value = (argc >= 4 ) ? atoi(argv[3]) : 123;
        Foobar(flags);
        return 0;
}
Как много веселых ребят, и все делают велосипед...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.