Давненько я сюда не писал
Итак, как всегда, очередное изобретение велосипеда родилось вот из-за какой надобности:
1. Допустим, есть у меня в программе (под С++ Builder) такой вот enum:
typedef enum
{
One,
Two,
Three,
Four
} TSomeEnum;
Естественно, во многих случаях работать с таким перечислением удобнее, чем с отдельным набором констант. Поехали дальше:
2. Этот самый enum — это одна из настроек моей программы (например, кол-во одновременно обрабатываемых файлов).
3. И мне нужно вывести список всех возможных значений (в строковом виде, а именно "One", "Two" etc.) этого enum'а в TListBox, например. Про возможности .NET — поручик, молчать!
Естественно, можно и ручками. А ну как я добавлю еще один элемент в enum (например, Five)? Каждый раз дописывать код
В общем, о полезности нижеприведенного решения вывод я еще не сделал
, но, думаю, пригодится на досуге. Единственное НО: работает, если не указывать инициализирующее значение для элементов enum'а (т.е. писать так, как выше привел, без конструкций типа One=20).
Сырец (сорри за #define — из песни слова выкинуть не получилось):
//---------------------------------------------------------------------------
#include <Typinfo.hpp>
//---------------------------------------------------------------------------
#define IMPLEMENT_ENUM_INFO(EnumType) \
class _##EnumType : public TObject \
{ \
EnumType Fx; \
__published: \
__property EnumType X = {read=Fx}; \
public: \
__fastcall _##EnumType() {}; \
__fastcall ~_##EnumType() {}; \
}; \
void __fastcall EnumerateEnum(Classes::TStrings* Strings, EnumType enumType) \
{\
PTypeInfo pTypeInfo = *(GetPropInfo(__typeinfo(_##EnumType),"X"))->PropType;\
PTypeData pTypeData = GetTypeData(pTypeInfo);\
for(int i=pTypeData->MinValue;i<=pTypeData->MaxValue;i++)\
{ \
Strings->Add(GetEnumName(pTypeInfo,i));\
} \
}\
//---------------------------------------------------------------------------
Пример использования:
// описываем enum'ы
//---------------------------------------------------------------------------
typedef enum
{
One,
Two,
Three,
Four
} TSampleEnum;
//---------------------------------------------------------------------------
typedef enum
{
One2,
Two2,
Three2
} TSampleEnum2;
//---------------------------------------------------------------------------
// Подставляем это добро препроцессору...
//---------------------------------------------------------------------------
IMPLEMENT_ENUM_INFO(TSampleEnum);
IMPLEMENT_ENUM_INFO(TSampleEnum2);
//---------------------------------------------------------------------------
// А теперь побалуемся...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
EnumerateEnum(Memo1->Lines, One); // этот в TMemo
EnumerateEnum(ListBox1->Items,One2); // а этот - в TListBox
}
//---------------------------------------------------------------------------
Как вы уже заметили, в EnumerateEnum вторым параметром надо передавать одно из значений нужного enum'а. Первый параметр — экземпляр класса TStrings.
З.Ы. Как всегда, приведенное решение — не истина в последней инстанции. Ждем предложений/альтернатив/пр.