Здравствуйте,
В программе обрабатываются сущности (назовём их элементами).
С каждым элементом связан массив аттрибутов.
Каждый аттрибут задаётся структурой:
enum attr_e {/**/};
struct attr_data
{
attr_e code; // код аттрибута
iterator_range data; // пара итераторов, указывающих откуда можно считать значение аттрибута
};
В итоге имеем метод обработки элемента:
enum element_e {/**/};
struct element_data
{
element_e code;
const attr_data* attr;
unsigned num_attr;
};
void proceed_element(const element_data&)
{
//...
}
Количество аттрибутов во много раз превышает количество элементов.(аттрибутов ~= 300, элементов ~= 25)
Типы аттрибутов подразделяются на группы
У различных элементов есть одинаковые типы аттрибутов.
То есть общая картина получается такой:
void proceed_element(const element_data& el)
{
switch (el.code)
{
case elem_1:
proceed_element_1(el.attr, el.num_attr);
break;
case elem_2:
proceed_element_2(el.attr, el.num_attr);
break;
};
}
//---------------------------------------------
void proceed_element_1(const attr_data* attr, unsigned num_attr)
{
set_group1_attributes(attr, num_attr);
set_group2_attributes(attr, num_attr);
set_group3_attributes(attr, num_attr);
// обработка индивидуальных аттрибутов для этого элемента
//...
}
//---------------------------------------------
void proceed_element_1(const attr_data* attr, unsigned num_attr)
{
set_group1_attributes(attr, num_attr);
set_group3_attributes(attr, num_attr);
// обработка индивидуальных аттрибутов для этого элемента
//...
}
//---------------------------------------------
void set_group1_attributes(const attr_data * attr, unsigned num_attr)
{
for (unsigned i(0); i < num_attr; ++i)
{
switch (attr[i].code)
{
// обработка аттрибутов из своей группы
}
}
}
все функции set_groupX_attributes(...) реализованы одинаковым образом, то есть цикл по массиву аттрибутов, в теле цикла обрабатываются аттрибуты из своей группы.
Уффф... вроде всё... Итак, мне не нравится то что мне приходится по несколько раз проходится по всем элементам одного и того же массива.
И даже если я уже обработал аттрибут, его код всё равно будет проверяться в других функциях.
Что мне пришло на ум:
я добавляю два дополнительных члена к структуре attr_data
struct attr_data
{
unsigned char next;
unsigned char prev; //(255 элементов в списке будет достаточно)
attr_e code; // код аттрибута
iterator_range data; // пара итераторов, указывающих откуда можно считать значение аттрибута
};
и с помощью них организую простой двухсвязный список. Потом, если аттрибут обработан, я удаляю его из списка (удаление сводится к корректировке членов next, prev)
Больше мне ничего уже не придумывается.
Собственно вопрос в том, что может кто то подскажет что то лучше.
Спасибо если дочитали до конца.