//! \~\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