robot-ya-builder 96458ea3c7 External build system generator release 65 11 месяцев назад
..
CMakeLists.darwin-arm64.txt ffff7a34e4 add darwin-arm64 CMakeLists 1 год назад
CMakeLists.darwin-x86_64.txt 33ed6077e6 Intermediate changes 1 год назад
CMakeLists.linux-aarch64.txt 9f448c9c67 Intermediate changes 1 год назад
CMakeLists.linux-x86_64.txt 33ed6077e6 Intermediate changes 1 год назад
CMakeLists.txt 96458ea3c7 External build system generator release 65 11 месяцев назад
CMakeLists.windows-x86_64.txt 6324d075a5 Intermediate changes 1 год назад
README.md cc2baf0174 intermediate changes 2 лет назад
dispatch_methods.cpp 8e7094c87f intermediate changes 2 лет назад
dispatch_methods.h e5e7d3b69b [enum_parser] generate ToStringBuf specialization 2 лет назад
enum_runtime.cpp 8e7094c87f intermediate changes 2 лет назад
enum_runtime.h e5e7d3b69b [enum_parser] generate ToStringBuf specialization 2 лет назад
ordered_pairs.cpp 8e7094c87f intermediate changes 2 лет назад
ordered_pairs.h c04b663c7b intermediate changes 2 лет назад
ya.make bf0f13dd39 add ymake export to ydb 1 год назад

README.md

Enum serialization runtime support library

{% note warning %}

This library should not be used or referred directly. Use GENERATE_ENUM_SERIALIZATION_WITH_HEADER and GENERATE_ENUM_SERIALIZATION macros instead.

{% endnote %}

Implementation details

Code bloat

Использование шаблонов вида TVector<EEnum>, std::array<EEnum> или TMap<EEnum, TStringBuf>, а также алгоритмов поверх них, приводит к значительному разбуханию коде. Так как компилятор для разных перечислений вынужден генерировать разные специализации, даже если они компилируются в идентичный машинный код. Можно во многом выиграть если хранить не массив из EEnum, а массив из std::underlying_type_t<EEnum> (или из TSelectEnumRepresentationType<EEnum>::TType). Ведь различных типов-перечислений намного больше, чем целочисленных типов, на которых они базируются (и тем более больше, чем различных TSelectEnumRepresentationType::TType, коих всего четыре). И когда компилятор встречает вызов std::lower_bound, то для двух массивов из двух перечислений enum A: int {} и enum B: int{} он создаст две специализации, а если использовать целочисленные типы — то только одну. Всё это позволяет вынести вызовы вроде std::lower_bound в универсальные и переиспользуемые функции, принимающие например (TArrayRef<const int> values, int enumValue) своими аргументами. За счёт этого код 1) быстрее компилируется, 2) результат получается более компактным, 3) как следствие, он меньше засоряет во время исполнения кеш инструкций процессора одинаковыми или очень похожими специализациями функций.

Преобразование между enum и int выносится в пользовательский код (в шаблонные inline функции), и производится только в момент непосредственного использования (первым действием в семействе функций ToString, последним действием в семуйстве функций FromString), где оптимизирующий компилятор обычно может заменить их на no-op или на простые операции со значениями в регистрах. А контейнеры вида TVector<EEnum> и TMap<EEnum, ...>, которые возвращаются из функций util/generic/serialized_enum.h, заменяются на специальные классы TArrayView и TMappedDictView. Они также поддерживают быстрое и преобразование из перечислений в целочисленные типы и обратно в момент использования, и не требуют создавать специализации для каждого из возможных типов-перечислений.