1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/*!
@file
@author Albert Semenov
@date 10/2009
@module
*/
#ifndef ATTRIBUTE_H_
#define ATTRIBUTE_H_
namespace attribute
{
// класс обертка для удаления данных из статического вектора
template<typename Type>
struct DataHolder
{
~DataHolder()
{
for (typename Type::iterator item = data.begin(); item != data.end(); ++item)
delete (*item).first;
}
Type data;
};
// интерфейс для обертки поля
template<typename OwnerType, typename SetterType>
struct Field
{
virtual ~Field() = default;
virtual bool set(OwnerType* _target, typename SetterType::BaseValueType* _value) = 0;
virtual std::string_view getFieldTypeName() const = 0;
};
// шаблон для обертки поля
template<typename OwnerType, typename FieldType, typename SetterType>
struct FieldHolder : public Field<OwnerType, SetterType>
{
FieldHolder(FieldType* OwnerType::*offset) :
m_offset(offset)
{
}
FieldType* OwnerType::*const m_offset;
bool set(OwnerType* _target, typename SetterType::BaseValueType* _value) override
{
_target->*m_offset = SetterType::template convert<FieldType>(_value);
return _target->*m_offset != nullptr;
}
std::string_view getFieldTypeName() const override
{
return FieldType::getClassTypeName();
}
};
// шаблон для атрибута поля
template<typename OwnerType, typename ValueType, typename SetterType>
struct AttributeField
{
using BindPair = std::pair<Field<OwnerType, SetterType>*, ValueType>;
using VectorBindPair = std::vector<BindPair>;
template<typename FieldType>
AttributeField(FieldType* OwnerType::*_offset, const ValueType& _value)
{
getData().push_back(BindPair(new FieldHolder<OwnerType, FieldType, SetterType>(_offset), _value));
}
static VectorBindPair& getData()
{
static DataHolder<VectorBindPair> data;
return data.data;
}
};
// макрос для инстансирования атрибута поля
#define DECLARE_ATTRIBUTE_FIELD(_name, _type, _setter) \
template<typename OwnerType, typename ValueType = _type, typename SetterType = _setter> \
struct _name : public attribute::AttributeField<OwnerType, ValueType, SetterType> \
{ \
template<typename FieldType> \
_name(FieldType* OwnerType::*_offset, const ValueType& _value) : \
AttributeField<OwnerType, ValueType, SetterType>(_offset, _value) \
{ \
} \
}
// макрос для инстансирования экземпляра атрибута
#define ATTRIBUTE_FIELD(_attribute, _class, _field, _value) \
struct _attribute##_##_field \
{ \
_attribute##_##_field() \
{ \
static attribute::_attribute<_class> bind(&_class::_field, _value); \
} \
} _attribute##_##_field
// шаблон для атрибута класса
template<typename Type, typename ValueType>
struct ClassAttribute
{
ClassAttribute(const ValueType& _value)
{
getData() = _value;
}
static ValueType& getData()
{
static ValueType data;
return data;
}
};
// макрос для инстансирования атрибута класса
#define DECLARE_ATTRIBUTE_CLASS(_name, _type) \
template<typename Type, typename ValueType = _type> \
struct _name : public attribute::ClassAttribute<_name<Type>, ValueType> \
{ \
_name(const ValueType& _value) : \
ClassAttribute<_name<Type>, ValueType>(_value) \
{ \
} \
}
// макрос для инстансирования экземпляра класса
#define ATTRIBUTE_CLASS(_attribute, _class, _value) \
class _class; \
static attribute::_attribute<_class> _attribute##_##_class(_value)
}
#endif // ATTRIBUTE_H_
|