//! \~\file picodeinfo.h //! \~\ingroup Code //! \~\brief //! \~english C++ code info structs. See \ref code_model. //! \~russian Структуры для C++ кода. Подробнее \ref code_model. //! \~\details //! \~english Contains structures for code generation and reflection: TypeInfo, FunctionInfo, ClassInfo, EnumInfo, EnumeratorInfo. //! \~russian Содержит структуры для кодогенерации и рефлексии: TypeInfo, FunctionInfo, ClassInfo, EnumInfo, EnumeratorInfo. /* PIP - Platform Independent Primitives C++ code info structs Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PICODEINFO_H #define PICODEINFO_H #include "piconstchars.h" #include "pistringlist.h" #include "pivarianttypes.h" class PIVariant; //! \~english Namespace contains structures for code generation. See \ref code_model. //! \~russian Пространство имен содержит структуры для кодогенерации. Подробнее \ref code_model. //! \~\details //! \~english Provides classes and structures for code introspection, including type information, function details, class metadata, and enum //! information. //! \~russian Предоставляет классы и структуры для интроспекции кода, включая информацию о типах, детали функций, метаданные классов и //! информацию о перечислениях. namespace PICodeInfo { //! \~english Type modifiers. //! \~russian Модификаторы типа. enum TypeFlag { NoFlag /** \~english No modifiers. \~russian Модификаторы отсутствуют. */, Const = 0x01 /** \~english \c const modifier. \~russian Модификатор \c const. */, Static = 0x02 /** \~english \c static modifier. \~russian Модификатор \c static. */, Mutable = 0x04 /** \~english \c mutable modifier. \~russian Модификатор \c mutable. */, Volatile = 0x08 /** \~english \c volatile modifier. \~russian Модификатор \c volatile. */, Inline = 0x10 /** \~english \c inline modifier. \~russian Модификатор \c inline. */, Virtual = 0x20 /** \~english \c virtual modifier. \~russian Модификатор \c virtual. */, Extern = 0x40 /** \~english \c extern modifier. \~russian Модификатор \c extern. */ }; //! \~english Bitmask of type modifiers. //! \~russian Битовая маска модификаторов типа. typedef PIFlags TypeFlags; //! \~english Custom metadata map produced by \c PIMETA. //! \~russian Карта пользовательских метаданных, создаваемых \c PIMETA. typedef PIMap MetaMap; //! \~english Callback returning serialized member data by member name. //! \~russian Обратный вызов, возвращающий сериализованные данные члена по имени. typedef PIByteArray (*AccessValueFunction)(const void *, const char *); //! \~english Callback returning a member type name by member name. //! \~russian Обратный вызов, возвращающий имя типа члена по его имени. typedef const char * (*AccessTypeFunction)(const char *); //! \~english Callback returning a member offset by member name. //! \~russian Обратный вызов, возвращающий смещение члена по его имени. typedef int (*AccessOffsetFunction)(const char *); //! \~english Type information //! \~russian Информация о типе struct PIP_EXPORT TypeInfo { //! \~english Constructs type information for one variable or argument. //! \~russian Создает описание типа для одной переменной или аргумента. TypeInfo(const PIConstChars & n = PIConstChars(), const PIConstChars & t = PIConstChars(), PICodeInfo::TypeFlags f = 0, int b = -1) { name = n; type = t; flags = f; bits = b; } //! \~english Returns whether the described variable is a bitfield. //! \~russian Возвращает, является ли описываемая переменная битовым полем. bool isBitfield() const { return bits > 0; } //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA MetaMap meta; //! \~english Name //! \~russian Имя PIConstChars name; //! \~english Type //! \~russian Тип PIConstChars type; //! \~english Modifiers //! \~russian Модификаторы PICodeInfo::TypeFlags flags; //! \~english Bitfield variable bit count //! \~russian Количество бит битового поля int bits; }; //! \~english Method information //! \~russian Информация о методе struct PIP_EXPORT FunctionInfo { //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA MetaMap meta; //! \~english Name //! \~russian Имя PIConstChars name; //! \~english Return type //! \~russian Возвращаемый тип TypeInfo return_type; //! \~english Arguments types //! \~russian Типы аргументов PIVector arguments; }; //! \~english Class or struct information //! \~russian Информация о классе или структуре struct PIP_EXPORT ClassInfo { //! \~english Constructs an empty class description. //! \~russian Создает пустое описание класса. ClassInfo() { is_anonymous = false; } //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA MetaMap meta; //! \~english Indicates that the type was declared without a name //! \~russian Показывает, что тип был объявлен без имени bool is_anonymous; //! \~english Declaration kind, for example \c class or \c struct //! \~russian Вид объявления, например \c class или \c struct PIConstChars type; //! \~english Name //! \~russian Имя PIConstChars name; //! \~english Base class names //! \~russian Имена базовых классов PIVector parents; //! \~english Variables //! \~russian Переменные PIVector variables; //! \~english Methods //! \~russian Методы PIVector functions; //! \~english Registered derived class descriptions //! \~russian Зарегистрированные описания производных классов PIVector children_info; }; //! \~english Enumerator information //! \~russian Информация об элементе перечисления struct PIP_EXPORT EnumeratorInfo { //! \~english Constructs one enum member description. //! \~russian Создает описание одного элемента перечисления. EnumeratorInfo(const PIConstChars & n = PIConstChars(), int v = 0) { name = n; value = v; } //! \~english Converts the enumerator to the %PIVariantTypes representation. //! \~russian Преобразует элемент перечисления в представление %PIVariantTypes. PIVariantTypes::Enumerator toPIVariantEnumerator() { return PIVariantTypes::Enumerator(value, name.toString()); } //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA MetaMap meta; //! \~english Name //! \~russian Имя PIConstChars name; //! \~english Value //! \~russian Значение int value; }; //! \~english Enum information //! \~russian Информация о перечислении struct PIP_EXPORT EnumInfo { //! \~english Returns the member name for the value \a value. //! \~russian Возвращает имя элемента для значения \a value. PIString memberName(int value) const; //! \~english Returns the member value for the name \a name. //! \~russian Возвращает значение элемента для имени \a name. int memberValue(const PIString & name) const; //! \~english Converts the enum description to %PIVariantTypes::Enum. //! \~russian Преобразует описание перечисления в %PIVariantTypes::Enum. PIVariantTypes::Enum toPIVariantEnum(); //! \~english Custom PIMETA content //! \~russian Произвольное содержимое PIMETA MetaMap meta; //! \~english Name //! \~russian Имя PIConstChars name; //! \~english Members //! \~russian Элементы PIVector members; }; //! \~english Writes a declaration-like view of \a v to \a s. //! \~russian Записывает в \a s представление \a v в стиле объявления. inline PICout operator<<(PICout s, const PICodeInfo::TypeInfo & v) { if (v.flags[Inline]) s << "inline "; if (v.flags[Virtual]) s << "virtual "; if (v.flags[Mutable]) s << "mutable "; if (v.flags[Volatile]) s << "volatile "; if (v.flags[Static]) s << "static "; if (v.flags[Const]) s << "const "; s << v.type; if (!v.name.isEmpty()) s << " " << v.name; return s; } //! \~english Writes an enum member description to \a s. //! \~russian Записывает описание элемента перечисления в \a s. inline PICout operator<<(PICout s, const PICodeInfo::EnumeratorInfo & v) { s << v.name << " = " << v.value << " Meta" << v.meta; return s; } //! \~english Writes a human-readable class description to \a s. //! \~russian Записывает в \a s человекочитаемое описание класса. inline PICout operator<<(PICout s, const PICodeInfo::ClassInfo & v) { s.saveAndSetControls(0); s << "class " << v.name; if (!v.parents.isEmpty()) { s << ": "; bool first = true; for (const auto & i: v.parents) { if (first) first = false; else s << ", "; s << i; } } s << " Meta" << v.meta << " {\n"; for (const auto & i: v.functions) { s << PICoutManipulators::Tab << i.return_type << " " << i.name << "("; bool fa = true; for (const auto & a: i.arguments) { if (fa) fa = false; else s << ", "; s << a; } s << ") Meta" << i.meta << ";\n"; } if (!v.functions.isEmpty() && !v.variables.isEmpty()) s << "\n"; for (const auto & i: v.variables) { s << PICoutManipulators::Tab << i << " Meta" << i.meta << ";\n"; } s << "}\n"; s.restoreControls(); return s; } //! \~english Writes a human-readable enum description to \a s. //! \~russian Записывает в \a s человекочитаемое описание перечисления. inline PICout operator<<(PICout s, const PICodeInfo::EnumInfo & v) { s.saveAndSetControls(0); s << "enum " << v.name << " Meta" << v.meta << " {\n"; for (const auto & i: v.members) { bool f = true; if (f) f = false; else s << ", "; s << PICoutManipulators::Tab << i << "\n"; } s << "}\n"; s.restoreControls(); return s; } class PIP_EXPORT __Storage__ { __Storage__(); ~__Storage__(); public: static __Storage__ * instance(); PIMap * classesInfo; PIMap * enumsInfo; PIMap * accessValueFunctions; PIMap * accessTypeFunctions; PIMap * accessOffsetFunctions; private: NO_COPY_CLASS(__Storage__) }; class PIP_EXPORT __StorageAccess__ { public: static const PIMap & classes() { return *(__Storage__::instance()->classesInfo); } // namespace PICodeInfo static const PIMap & enums() { return *(__Storage__::instance()->enumsInfo); } static const PIMap & accessValueFunctions() { return *(__Storage__::instance()->accessValueFunctions); } static const PIMap & accessTypeFunctions() { return *(__Storage__::instance()->accessTypeFunctions); } static const PIMap & accessOffsetFunctions() { return *(__Storage__::instance()->accessOffsetFunctions); } }; //! \relatesalso PICodeInfo //! \~english Macro for the global code model registries. //! \~russian Макрос для доступа к глобальным реестрам модели кода. #define PICODEINFO PICodeInfo::__StorageAccess__ class PIP_EXPORT ClassInfoInterface { public: const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::classes()") { return __Storage__::instance()->classesInfo; } }; static ClassInfoInterface classesInfo; class PIP_EXPORT EnumsInfoInterface { public: const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::enums()") { return __Storage__::instance()->enumsInfo; } }; static EnumsInfoInterface enumsInfo; class PIP_EXPORT AccessValueFunctionInterface { public: const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::accessValueFunctions()") { return __Storage__::instance()->accessValueFunctions; } }; static AccessValueFunctionInterface accessValueFunctions; class PIP_EXPORT AccessTypeFunctionInterface { public: const PIMap * operator->() const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()") { return __Storage__::instance()->accessTypeFunctions; } }; static AccessTypeFunctionInterface accessTypeFunctions; STATIC_INITIALIZER_BEGIN NO_UNUSED(classesInfo); NO_UNUSED(enumsInfo); NO_UNUSED(accessValueFunctions); NO_UNUSED(accessTypeFunctions); STATIC_INITIALIZER_END //! \~english Returns a serialized value of \a member_name from an instance of \a class_name. //! \~russian Возвращает сериализованное значение \a member_name из экземпляра \a class_name. inline PIByteArray getMemberValue(const void * p, const char * class_name, const char * member_name) { if (!p || !class_name || !member_name) return PIByteArray(); AccessValueFunction af = PICODEINFO::accessValueFunctions().value(class_name, (AccessValueFunction)0); if (!af) return PIByteArray(); return af(p, member_name); } //! \~english Returns the registered type name of \a member_name in \a class_name. //! \~russian Возвращает зарегистрированное имя типа \a member_name в \a class_name. inline const char * getMemberType(const char * class_name, const char * member_name) { if (!class_name || !member_name) return ""; AccessTypeFunction af = PICODEINFO::accessTypeFunctions().value(class_name, (AccessTypeFunction)0); if (!af) return ""; return af(member_name); } //! \~english Returns \a member_name from \a class_name as %PIVariant when accessors are registered. //! \~russian Возвращает \a member_name из \a class_name как %PIVariant, если зарегистрированы функции доступа. PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name); //! \~english Serializes assignable values into \a ret through the stream operator. //! \~russian Сериализует присваиваемые значения в \a ret через оператор потока. template::value, int>::type = 0> void serialize(PIByteArray & ret, const T & v) { ret << v; } //! \~english Fallback overload for values that cannot be written to the byte-array stream. //! \~russian Резервная перегрузка для значений, которые нельзя записать в поток массива байт. template::value, int>::type = 0> void serialize(PIByteArray & ret, const T & v) {} } // namespace PICodeInfo #endif // PICODEINFO_H