Я работаю над подсистемой анализатора/генератора сообщений. Я создаю автогенератор, который использует базу данных, которая содержит всю информацию об этом протоколе, включая списки перечислений, для генерации кода. Одна вещь, с которой я столкнулся, - это необходимость иерархических перечислений.
обновляется
(Я пытался упростить ситуацию, не описывая полную проблему, но приведенные ниже комментарии делают очевидным, что я ошибся, упростив слишком много.)
Используемая база данных будет хранить вещи как упрощенные строки (решение для клиентов), но протокол говорит только о байтовых триплетах (также называемых Иерархическим перечислением). Полная проблема может быть описана как таковая:
Учитывая набор уникальных строк, каждый из которых соответствует уникальному триплету, 1) найдите триплет для любой заданной строки и 2) найдите строку для любого данного триплета. Обязательно учитывайте перечисления "Undefined" и "No Statement" (которые не имеют связанных с ними строк). [Как отметил один плакат, да, это безумие.]
(Предостережение: я занимаюсь С++ уже более десяти лет, но в прошлом году я занимался Java - мой С++, вероятно, "поврежден".)
Итак, чтобы использовать по-настоящему надуманный пример, учитывая:
// There is only one category
// POP= "P", COUNTRY= "K", CLASSICAL= "C"
enum Category {POP, COUNTRY, CLASSICAL};
// There is one Type enum for each Category.
// ROCK= "R", BIG_BAND = "B", COUNTRY_POP= "C"
enum PopType {ROCK, BIG_BAND, COUNTRY_POP};
enum CountryType {CLASSICAL_COUNTRY, MODERN_COUNTRY, BLUEGRASS, COUNTRY_AND_WESTERN};
// ...
// There is one Subtype for each Type
// EIGHTIES= "E", HEAVY_METAL= "H", SOFT_ROCK= "S"
enum RockSubType { EIGHTIES, HEAVY_METAL, SOFT_ROCK};
// ...
Когда я получаю 0, 0, 0 (Pop, Rock, Eighties), мне нужно перевести это на "PRE". И наоборот, если я вижу "ПК" в базе данных, необходимо отправить провод в 0, 2 (поп, страна, NULL).
Я откровенно игнорирую "Undefined" и "Нет инструкции" на этом этапе. Создание триплета из строки кажется прямым (используйте неупорядоченную карту, строку для тройки). Создание строки из триплета (что может содержат NULL в последней записи)... не так много. Большинство "перечисляемых трюков", которые, как я знаю, не будут работать: например, типы повторяют значения - каждое перечисление типа начинается с нуля - t индексирует массив на основе значения Enum для захвата строки.
То, что получило меня, - это отношения. На первый взгляд кажется, что это довольно прямое отношение "есть-а", но это не работает, потому что этот случай двунаправлен. Листинг → коренная навигация очень прямолинейна и подходит для иерархии классов; к сожалению, идти в другую сторону не так прямо.
Я не могу "вручную рулить" это - мне нужно сгенерировать код, чтобы, вероятно, устранить любые решения на основе XML. Он также должен быть "достаточно быстрым". "Java Solution" включает использование защищенных статических переменных, инициализированных по построению и абстрактных базовых классов; однако, я не считаю, что это сработает на С++ (порядок инициализации и т.д.). Плюс, эстетически, я чувствую, что это должно быть... больше "const". Другой код, который я видел, для решения этой проблемы использует объединения, явно перечисляя все типы перечислений в объединении.
Единственное, что я могу придумать, это использовать специализацию шаблонов и явную специализацию, но я в недоумении. Я сделал веб-поиск, но я не нашел ничего, что могло бы сказать мне, будет ли оно работать. Тем не менее, если это можно сделать с помощью объединения, не может ли это быть сделано с помощью специализации шаблона?
Можно ли сделать что-то подобное, используя шаблоны, специализацию, явную специализацию? Есть ли еще одно, более очевидное решение (т.е. Шаблон, который я забыл), который мне не хватает?
О, прежде чем я забуду - решение должно быть переносимым. Более конкретно, он должен работать на Windows (Visual Studio 2010) и Redhat Enterprise 6/Centos 6 (GCC 4.4.4 IIRC).
И, чтобы я не забыл, этот протокол огромен. Теоретический максимум в этом случае составляет около 133 000 записей; как только я включу "Undefined" и "No Statement", у меня, вероятно, будет много записей.
Спасибо.