392 lines
11 KiB
C++
392 lines
11 KiB
C++
/*! \file picodeinfo.h
|
||
* \ingroup Code
|
||
* \~\brief
|
||
* \~english C++ code info structs. See \ref code_model.
|
||
* \~russian Структуры для C++ кода. Подробнее \ref code_model.
|
||
*/
|
||
/*
|
||
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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
|
||
#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.
|
||
namespace PICodeInfo {
|
||
|
||
|
||
//! \~english
|
||
//! Type modifiers
|
||
//! \~russian
|
||
//! Модификаторы типа
|
||
enum TypeFlag {
|
||
NoFlag,
|
||
Const /** const */ = 0x01,
|
||
Static /** static */ = 0x02,
|
||
Mutable /** mutable */ = 0x04,
|
||
Volatile /** volatile */ = 0x08,
|
||
Inline /** inline */ = 0x10,
|
||
Virtual /** virtual */ = 0x20,
|
||
Extern /** extern */ = 0x40
|
||
};
|
||
|
||
typedef PIFlags<PICodeInfo::TypeFlag> TypeFlags;
|
||
typedef PIMap<PIString, PIString> MetaMap;
|
||
typedef PIByteArray (*AccessValueFunction)(const void *, const char *);
|
||
typedef const char * (*AccessTypeFunction)(const char *);
|
||
|
||
|
||
//! \~english Type information
|
||
//! \~russian Информация о типе
|
||
struct PIP_EXPORT TypeInfo {
|
||
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 if variable if 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<PICodeInfo::TypeInfo> arguments;
|
||
};
|
||
|
||
|
||
//! \~english Class or struct information
|
||
//! \~russian Информация о классе или структуре
|
||
struct PIP_EXPORT ClassInfo {
|
||
ClassInfo() { has_name = true; }
|
||
|
||
//! \~english Custom PIMETA content
|
||
//! \~russian Произвольное содержимое PIMETA
|
||
MetaMap meta;
|
||
|
||
//! \~english Has name or not
|
||
//! \~russian Имеет или нет имя
|
||
bool has_name;
|
||
|
||
//! \~english Type
|
||
//! \~russian Тип
|
||
PIConstChars type;
|
||
|
||
//! \~english Name
|
||
//! \~russian Имя
|
||
PIConstChars name;
|
||
|
||
//! \~english Parent names
|
||
//! \~russian Имена родителей
|
||
PIVector<PIConstChars> parents;
|
||
|
||
//! \~english Variables
|
||
//! \~russian Переменные
|
||
PIVector<PICodeInfo::TypeInfo> variables;
|
||
|
||
//! \~english Methods
|
||
//! \~russian Методы
|
||
PIVector<PICodeInfo::FunctionInfo> functions;
|
||
|
||
//! \~english Subclass list
|
||
//! \~russian Список наследников
|
||
PIVector<PICodeInfo::ClassInfo *> children_info;
|
||
};
|
||
|
||
|
||
//! \~english Enumerator information
|
||
//! \~russian Информация об элементе перечисления
|
||
struct PIP_EXPORT EnumeratorInfo {
|
||
EnumeratorInfo(const PIConstChars & n = PIConstChars(), int v = 0) {
|
||
name = n;
|
||
value = v;
|
||
}
|
||
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 member name with value "value"
|
||
//! \~russian Возвращает имя элемента со значением "value"
|
||
PIString memberName(int value) const;
|
||
|
||
//! \~english Returns member value with name "name"
|
||
//! \~russian Возвращает значение элемента с именем "name"
|
||
int memberValue(const PIString & name) const;
|
||
|
||
//! \~english Returns as 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<PICodeInfo::EnumeratorInfo> members;
|
||
};
|
||
|
||
|
||
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;
|
||
}
|
||
|
||
inline PICout operator<<(PICout s, const PICodeInfo::EnumeratorInfo & v) {
|
||
s << v.name << " = " << v.value << " Meta" << v.meta;
|
||
return 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;
|
||
}
|
||
|
||
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<PIConstChars, PICodeInfo::ClassInfo *> * classesInfo;
|
||
PIMap<PIConstChars, PICodeInfo::EnumInfo *> * enumsInfo;
|
||
PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * accessValueFunctions;
|
||
PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * accessTypeFunctions;
|
||
|
||
private:
|
||
NO_COPY_CLASS(__Storage__)
|
||
};
|
||
|
||
class PIP_EXPORT __StorageAccess__ {
|
||
public:
|
||
//! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name
|
||
//! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени
|
||
static const PIMap<PIConstChars, PICodeInfo::ClassInfo *> & classes() { return *(__Storage__::instance()->classesInfo); }
|
||
|
||
//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name
|
||
//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени
|
||
static const PIMap<PIConstChars, PICodeInfo::EnumInfo *> & enums() { return *(__Storage__::instance()->enumsInfo); }
|
||
|
||
static const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> & accessValueFunctions() {
|
||
return *(__Storage__::instance()->accessValueFunctions);
|
||
}
|
||
|
||
static const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> & accessTypeFunctions() {
|
||
return *(__Storage__::instance()->accessTypeFunctions);
|
||
}
|
||
};
|
||
|
||
#define PICODEINFO PICodeInfo::__StorageAccess__
|
||
|
||
|
||
class PIP_EXPORT ClassInfoInterface {
|
||
public:
|
||
const PIMap<PIConstChars, PICodeInfo::ClassInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::classes()") {
|
||
return __Storage__::instance()->classesInfo;
|
||
}
|
||
};
|
||
static ClassInfoInterface classesInfo;
|
||
|
||
|
||
class PIP_EXPORT EnumsInfoInterface {
|
||
public:
|
||
const PIMap<PIConstChars, PICodeInfo::EnumInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::enums()") {
|
||
return __Storage__::instance()->enumsInfo;
|
||
}
|
||
};
|
||
static EnumsInfoInterface enumsInfo;
|
||
|
||
|
||
class PIP_EXPORT AccessValueFunctionInterface {
|
||
public:
|
||
const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * operator->() const DEPRECATEDM("use PICODEINFO::accessValueFunctions()") {
|
||
return __Storage__::instance()->accessValueFunctions;
|
||
}
|
||
};
|
||
static AccessValueFunctionInterface accessValueFunctions;
|
||
|
||
|
||
class PIP_EXPORT AccessTypeFunctionInterface {
|
||
public:
|
||
const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * 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
|
||
|
||
|
||
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);
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name);
|
||
|
||
|
||
template<typename T, typename std::enable_if<std::is_assignable<T &, const T &>::value, int>::type = 0>
|
||
void serialize(PIByteArray & ret, const T & v) {
|
||
ret << v;
|
||
}
|
||
|
||
template<typename T, typename std::enable_if<!std::is_assignable<T &, const T &>::value, int>::type = 0>
|
||
void serialize(PIByteArray & ret, const T & v) {}
|
||
|
||
} // namespace PICodeInfo
|
||
|
||
|
||
#endif // PICODEINFO_H
|