/*! \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 .
*/
#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 TypeFlags;
typedef PIMap MetaMap;
typedef PIByteArray (*AccessValueFunction)(const void *, const char *);
typedef const char * (*AccessTypeFunction)(const char *);
typedef int (*AccessOffsetFunction)(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 arguments;
};
//! \~english Class or struct information
//! \~russian Информация о классе или структуре
struct PIP_EXPORT ClassInfo {
ClassInfo() { is_anonymous = false; }
//! \~english Custom PIMETA content
//! \~russian Произвольное содержимое PIMETA
MetaMap meta;
//! \~english Anonymous or not
//! \~russian Анонимный или нет
bool is_anonymous;
//! \~english Type
//! \~russian Тип
PIConstChars type;
//! \~english Name
//! \~russian Имя
PIConstChars name;
//! \~english Parent names
//! \~russian Имена родителей
PIVector parents;
//! \~english Variables
//! \~russian Переменные
PIVector variables;
//! \~english Methods
//! \~russian Методы
PIVector functions;
//! \~english Subclass list
//! \~russian Список наследников
PIVector 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 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 * classesInfo;
PIMap * enumsInfo;
PIMap * accessValueFunctions;
PIMap * accessTypeFunctions;
PIMap * accessOffsetFunctions;
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 & classes(){return *(__Storage__::instance()->classesInfo);
} // namespace PICodeInfo
//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name
//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени
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);
}
}
;
#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
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::value, int>::type = 0>
void serialize(PIByteArray & ret, const T & v) {
ret << v;
}
template::value, int>::type = 0>
void serialize(PIByteArray & ret, const T & v) {}
} // namespace PICodeInfo
#endif // PICODEINFO_H