Можно как-то автоматически найти границы енума?
От: Hоmunculus  
Дата: 05.02.26 18:44
Оценка:
Ясно, что обычно начинается с нуля и есть именованный последний типа MY_ENUM_LAST.
И можно в цикле от нуля до последнего пройтись по всем.

Но пусть таких условий нет. Тот есть начинаться может не с нуля и последнего именованного нет.
Как определить границы в этом случае?
Re: Можно как-то автоматически найти границы енума?
От: Alexander_S_U https://github.com/alexanders-code/cmdxmlinstaller
Дата: 05.02.26 19:51
Оценка: 8 (2) +1
Здравствуйте, Hоmunculus, Вы писали:

...
H>Но пусть таких условий нет. Тот есть начинаться может не с нуля и последнего именованного нет.
H>Как определить границы в этом случае?

Если С++17 можно посмотреть из этой библиотеки magic_enum
enum_values и enum_count.
https://github.com/alexanders-code/cmdxmlinstaller
Re: Можно как-то автоматически найти границы енума?
От: Pzz Россия https://github.com/alexpevzner
Дата: 05.02.26 19:54
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Но пусть таких условий нет. Тот есть начинаться может не с нуля и последнего именованного нет.

H>Как определить границы в этом случае?

А разве присваивание enum-у int-а не из числа перечисленных — это UB?
Re: Можно как-то автоматически найти границы енума?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.02.26 20:10
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Ясно, что обычно начинается с нуля и есть именованный последний типа MY_ENUM_LAST.

H>И можно в цикле от нуля до последнего пройтись по всем.

Если значения идут не по порядку, могут быть проблемы


H>Но пусть таких условий нет. Тот есть начинаться может не с нуля и последнего именованного нет.

H>Как определить границы в этом случае?

Нет.

Я себе сделал генератор, энумы только через него делаю, он мету разную добавляет, в основном для (де)сериализации
Маньяк Робокряк колесит по городу
Re: Можно как-то автоматически найти границы енума?
От: kov_serg Россия  
Дата: 06.02.26 05:42
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Ясно, что обычно начинается с нуля и есть именованный последний типа MY_ENUM_LAST.

H>И можно в цикле от нуля до последнего пройтись по всем.
H>Но пусть таких условий нет. Тот есть начинаться может не с нуля и последнего именованного нет.
H>Как определить границы в этом случае?

А кто мешает явно их задать?
template<class T> struct Bounds;
template<class T> int min(const T&) { return Bounds<T>::min; }
template<class T> int max(const T&) { return Bounds<T>::max; }
#define DECL_BOUNDS(E,a,b) template<> struct Bounds<enum E> { enum { min=a, max=b }; };
enum E { A,B,C,D };
DECL_BOUNDS(E,A,D);
int main(int argc,char** argv) {
    enum E e;
    int first=Bounds<E>::min, last=Bounds<E>::max;
    for(int k=min(e);k<=max(e);k++) {}
    return 0;
}
Re[2]: Можно как-то автоматически найти границы енума?
От: Hоmunculus  
Дата: 06.02.26 06:06
Оценка:
Здравствуйте, kov_serg, Вы писали:

Лишние правки при расширении енума, которые стопроцентно забудутся
Re[3]: Можно как-то автоматически найти границы енума?
От: kov_serg Россия  
Дата: 06.02.26 06:20
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Лишние правки при расширении енума, которые стопроцентно забудутся

С чего бы это. Если у вас много длинных енумов их лучше генерировать скриптами из базы вместе со всей обвязкой.
И потом как часто вы вносите лишние правки в енумы по пьяни в безсознательном состоянии? И разве в таком случае вы не обновляете тесты?
Да и принцип KISS советует использовать максимально простое и явное решение. Или вы предпочитаете стоя и в гамаке?
Отредактировано 06.02.2026 6:22 kov_serg . Предыдущая версия .
Re[3]: Можно как-то автоматически найти границы енума?
От: sergii.p  
Дата: 06.02.26 13:45
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Лишние правки при расширении енума, которые стопроцентно забудутся


так magic_enum тоже надо настраивать. По умолчанию оно проверяет значения от -128 до 127. И тоже это забудется (даже хуже — мало кто помнит об этом ограничении). Так что золотой пули здесь всё равно нет. Если нужно только находить границы, я бы не тянул весь magic_enum. Там куча compiler specific штук, которые могут в любой момент перестать работать.
Re[3]: Можно как-то автоматически найти границы енума?
От: sergii.p  
Дата: 06.02.26 13:58
Оценка: +1
Здравствуйте, Hоmunculus, Вы писали:

H>Лишние правки при расширении енума, которые стопроцентно забудутся


стандартный здесь подход: определять специальные значения н-р BEGIN END

enum class Color {
    RED = -100,
    GREEN = 0,
    BLUE = 100,
    BEGIN = RED,
    END = BLUE,
};


тогда забыть очень сложно. Не совсем понятно, почему вы сразу забанили этот вариант в первом сообщении. У вас нет возможности менять перечисления?
Re[4]: Можно как-то автоматически найти границы енума?
От: Hоmunculus  
Дата: 06.02.26 14:00
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>тогда забыть очень сложно. Не совсем понятно, почему вы сразу забанили этот вариант в первом сообщении. У вас нет возможности менять перечисления?


Ну, грубо говоря, возможность есть, но код не мой, не хотел бы в него лезть
Re[2]: Можно как-то автоматически найти границы енума?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 06.02.26 14:14
Оценка:
Здравствуйте, Alexander_S_U, Вы писали:

A_S>можно посмотреть из этой библиотеки


Если такие вещи и использовать, то не глядя. Когда втуда смотришь — одно расстройство.
Re[5]: Можно как-то автоматически найти границы енума?
От: kov_serg Россия  
Дата: 07.02.26 09:51
Оценка: 6 (1)
Здравствуйте, Hоmunculus, Вы писали:

H>Здравствуйте, sergii.p, Вы писали:


SP>>тогда забыть очень сложно. Не совсем понятно, почему вы сразу забанили этот вариант в первом сообщении. У вас нет возможности менять перечисления?


H>Ну, грубо говоря, возможность есть, но код не мой, не хотел бы в него лезть


Так вам в него и не надо лезть.
  bounds.h
template<class T> struct Bounds;
template<class T> int min(const T&) { return Bounds<T>::min; }
template<class T> int max(const T&) { return Bounds<T>::max; }

template<class T,class I=int> struct enum_iterator {
    I i; enum_iterator(I i) : i(i) {}
    enum_iterator& operator++ () { i++;return *this; }
    bool operator!= (const enum_iterator& rv) { return i!=rv.i; }
    T operator* () { return (T)i; }
};

#define DECL_BOUNDS(E,a,b) \
    template<> struct Bounds<E> { enum { min=a, max=b }; }; \
    inline enum_iterator<E> begin(const E&) { return a; } \
    inline enum_iterator<E> end(const E&) { return b+1; }
Просто создаёте файл support_not_my_lib.h в котором задаёте все необходимые границы (в одном месте)
#include "not_my_lib.h"
DECL_BOUNDS(Enum1,e1_fisrt,e1_last);
//...
DECL_BOUNDS(Enum100500,e100500_first,e100500_last);
и потом юзаете как вам удобнее
#include "crutches/support_not_my_lib.h"

int main(int argc,char** argv) {
    Enum1 e;
    int first=Bounds<Enum1>::min, last=Bounds<Enum1>::max;
    for(int k=min(e);k<=max(e);k++) {}    
    for(auto v:e) {}
    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.