type::Type: introduce 'extends()' method.

This commit is contained in:
lganzzzo 2021-11-04 01:46:35 +02:00
parent 46fe7d68fe
commit eacbc6f631
8 changed files with 94 additions and 23 deletions

View File

@ -38,6 +38,11 @@ public: \
typedef TYPE_EXTEND Z__CLASS_EXTENDED; \
typedef oatpp::data::mapping::type::DTOWrapper<Z__CLASS> Wrapper; \
private: \
\
static const oatpp::Type* getParentType() { \
return oatpp::Object<Z__CLASS_EXTENDED>::Class::getType(); \
} \
\
static const char* Z__CLASS_TYPE_NAME() { \
return #TYPE_NAME; \
} \
@ -46,6 +51,7 @@ private: \
static oatpp::data::mapping::type::BaseObject::Properties map = oatpp::data::mapping::type::BaseObject::Properties(); \
return &map; \
} \
\
public: \
\
template<typename ... Args> \

View File

@ -136,7 +136,7 @@ public:
if(m_ptr) {
if(m_ptr->type != WrapperType::Class::getType()) {
if(!m_ptr->type->extends(WrapperType::Class::getType())) {
throw std::runtime_error("[oatpp::data::mapping::type::Any::retrieve()]: Error. The value type doesn't match.");
}

View File

@ -97,14 +97,22 @@ namespace __class {
}
BaseObject::Properties* DTO::Z__CLASS_EXTEND(BaseObject::Properties* properties, BaseObject::Properties* extensionProperties) {
properties->pushFrontAll(extensionProperties);
return properties;
const mapping::type::Type* DTO::getParentType() {
return nullptr;
}
const char* DTO::Z__CLASS_TYPE_NAME() {
return "DTO";
}
oatpp::data::mapping::type::BaseObject::Properties* DTO::Z__CLASS_GET_FIELDS_MAP() {
static data::mapping::type::BaseObject::Properties map;
return &map;
}
BaseObject::Properties* DTO::Z__CLASS_EXTEND(BaseObject::Properties* properties, BaseObject::Properties* extensionProperties) {
properties->pushFrontAll(extensionProperties);
return properties;
}
}}}}

View File

@ -233,6 +233,7 @@ namespace __class {
Type::Info info;
info.nameQualifier = T::Z__CLASS_TYPE_NAME();
info.polymorphicDispatcher = new PolymorphicDispatcher();
info.parent = T::getParentType();
return new Type(CLASS_ID, info);
}
@ -307,6 +308,9 @@ public:
class DTO : public BaseObject {
template<class T>
friend class __class::Object;
private:
typedef DTO Z__CLASS;
typedef DTO Z__CLASS_EXTENDED;
public:
typedef oatpp::data::mapping::type::Void Void;
typedef oatpp::data::mapping::type::Any Any;
@ -345,10 +349,10 @@ public:
using UnorderedFields = oatpp::data::mapping::type::UnorderedMap<String, Value>;
private:
static BaseObject::Properties* Z__CLASS_EXTEND(BaseObject::Properties* properties, BaseObject::Properties* extensionProperties);
static const mapping::type::Type* getParentType();
static const char* Z__CLASS_TYPE_NAME();
static data::mapping::type::BaseObject::Properties* Z__CLASS_GET_FIELDS_MAP();
static BaseObject::Properties* Z__CLASS_EXTEND(BaseObject::Properties* properties, BaseObject::Properties* extensionProperties);
public:
virtual v_uint64 defaultHashCode() const {

View File

@ -80,6 +80,7 @@ Type::Type(const ClassId& pClassId, const Info& typeInfo)
, params(typeInfo.params)
, polymorphicDispatcher(typeInfo.polymorphicDispatcher)
, interpretationMap(typeInfo.interpretationMap)
, parent(typeInfo.parent)
{}
const Type::AbstractInterpretation* Type::findInterpretation(const std::vector<std::string>& names) const {
@ -92,4 +93,15 @@ const Type::AbstractInterpretation* Type::findInterpretation(const std::vector<s
return nullptr;
}
bool Type::extends(const Type* other) const {
const Type* curr = this;
while(curr != nullptr) {
if(curr == other) {
return true;
}
curr = curr->parent;
}
return false;
}
}}}}

View File

@ -412,6 +412,14 @@ public:
* Map of type Interpretations.
*/
InterpretationMap interpretationMap;
/**
* Parent type. <br>
* Ex.: DTO super-class type. <br>
* **Note:** setting `parent` type also means that child object can be
* statically casted to parent type without any violations.
*/
const Type* parent = nullptr;
};
public:
@ -448,6 +456,14 @@ public:
*/
const InterpretationMap interpretationMap;
/**
* Parent type. <br>
* Ex.: DTO super-class type. <br>
* **Note:** setting `parent` type also means that child object can be
* statically casted to parent type without any violations.
*/
const Type* const parent;
public:
/**
@ -457,6 +473,13 @@ public:
* interpretations found.
*/
const AbstractInterpretation* findInterpretation(const std::vector<std::string>& names) const;
/**
* Check if type extends other type.
* @param other
* @return
*/
bool extends(const Type* other) const;
};

View File

@ -311,10 +311,24 @@ void ObjectTest::onRun() {
}
{
OATPP_LOGI(TAG, "Test 9...");
auto dto = DtoD::createShared();
OATPP_ASSERT(dto->a.getValueType() == oatpp::Int32::Class::getType());
OATPP_ASSERT(dto->a);
OATPP_ASSERT(dto->a == 64);
OATPP_LOGI(TAG, "OK");
}
{
OATPP_LOGI(TAG, "Test 10...");
OATPP_ASSERT(oatpp::Object<DtoA>::Class::getType()->extends(oatpp::Object<oatpp::DTO>::Class::getType()))
OATPP_ASSERT(oatpp::Object<DtoA>::Class::getType()->extends(oatpp::Object<DtoA>::Class::getType()))
OATPP_ASSERT(oatpp::Object<DtoB>::Class::getType()->extends(oatpp::Object<DtoA>::Class::getType()))
OATPP_ASSERT(oatpp::Object<DtoB>::Class::getType()->extends(oatpp::Object<oatpp::DTO>::Class::getType()))
OATPP_ASSERT(oatpp::Object<DtoC>::Class::getType()->extends(oatpp::Object<DtoA>::Class::getType()))
OATPP_ASSERT(oatpp::Object<DtoD>::Class::getType()->extends(oatpp::Object<DtoA>::Class::getType()))
OATPP_ASSERT(!oatpp::Object<DtoC>::Class::getType()->extends(oatpp::Object<DtoB>::Class::getType()))
OATPP_LOGI(TAG, "OK");
}
}

View File

@ -69,52 +69,56 @@ void TypeTest::onRun() {
auto obj = TestDto::createShared();
OATPP_LOGV(TAG, "type: '%s'", obj->field_string.getValueType()->classId.name);
OATPP_ASSERT(obj->field_string.getValueType()->classId.id == oatpp::data::mapping::type::__class::String::CLASS_ID.id);
OATPP_ASSERT(obj->field_string.getValueType()->classId == oatpp::data::mapping::type::__class::String::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_int8.getValueType()->classId.name);
OATPP_ASSERT(obj->field_int8.getValueType()->classId.id == oatpp::data::mapping::type::__class::Int8::CLASS_ID.id);
OATPP_ASSERT(obj->field_int8.getValueType()->classId == oatpp::data::mapping::type::__class::Int8::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_int16.getValueType()->classId.name);
OATPP_ASSERT(obj->field_int16.getValueType()->classId.id == oatpp::data::mapping::type::__class::Int16::CLASS_ID.id);
OATPP_ASSERT(obj->field_int16.getValueType()->classId == oatpp::data::mapping::type::__class::Int16::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_int32.getValueType()->classId.name);
OATPP_ASSERT(obj->field_int32.getValueType()->classId.id == oatpp::data::mapping::type::__class::Int32::CLASS_ID.id);
OATPP_ASSERT(obj->field_int32.getValueType()->classId == oatpp::data::mapping::type::__class::Int32::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_int64.getValueType()->classId.name);
OATPP_ASSERT(obj->field_int64.getValueType()->classId.id == oatpp::data::mapping::type::__class::Int64::CLASS_ID.id);
OATPP_ASSERT(obj->field_int64.getValueType()->classId == oatpp::data::mapping::type::__class::Int64::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_float32.getValueType()->classId.name);
OATPP_ASSERT(obj->field_float32.getValueType()->classId.id == oatpp::data::mapping::type::__class::Float32::CLASS_ID.id);
OATPP_ASSERT(obj->field_float32.getValueType()->classId == oatpp::data::mapping::type::__class::Float32::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_float64.getValueType()->classId.name);
OATPP_ASSERT(obj->field_float64.getValueType()->classId.id == oatpp::data::mapping::type::__class::Float64::CLASS_ID.id);
OATPP_ASSERT(obj->field_float64.getValueType()->classId == oatpp::data::mapping::type::__class::Float64::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_boolean.getValueType()->classId.name);
OATPP_ASSERT(obj->field_boolean.getValueType()->classId.id == oatpp::data::mapping::type::__class::Boolean::CLASS_ID.id);
OATPP_ASSERT(obj->field_boolean.getValueType()->classId == oatpp::data::mapping::type::__class::Boolean::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_string.getValueType()->classId.name);
OATPP_ASSERT(obj->field_list_string.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
OATPP_ASSERT(obj->field_list_string.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_int32.getValueType()->classId.name);
OATPP_ASSERT(obj->field_list_int32.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
OATPP_ASSERT(obj->field_list_int32.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_int64.getValueType()->classId.name);
OATPP_ASSERT(obj->field_list_int64.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
OATPP_ASSERT(obj->field_list_int64.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_float32.getValueType()->classId.name);
OATPP_ASSERT(obj->field_list_float32.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
OATPP_ASSERT(obj->field_list_float32.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_float64.getValueType()->classId.name);
OATPP_ASSERT(obj->field_list_float64.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
OATPP_ASSERT(obj->field_list_float64.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_boolean.getValueType()->classId.name);
OATPP_ASSERT(obj->field_list_boolean.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
OATPP_ASSERT(obj->field_list_boolean.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->field_map_string_string.getValueType()->classId.name);
OATPP_ASSERT(obj->field_map_string_string.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id);
OATPP_ASSERT(obj->field_map_string_string.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID);
OATPP_LOGV(TAG, "type: '%s'", obj->obj1.getValueType()->classId.name);
OATPP_ASSERT(obj->obj1.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id);
OATPP_ASSERT(obj->obj1.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID);
OATPP_ASSERT(oatpp::String::Class::getType()->extends(oatpp::String::Class::getType()))
OATPP_ASSERT(oatpp::Int32::Class::getType()->extends(oatpp::Int32::Class::getType()))
OATPP_ASSERT(!oatpp::String::Class::getType()->extends(oatpp::Int32::Class::getType()))
}