Merge pull request #507 from oatpp/better_types

Better types
This commit is contained in:
Leonid Stryzhevskyi 2021-11-05 03:06:18 +02:00 committed by GitHub
commit fbf26c9c3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 331 additions and 116 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

@ -43,9 +43,6 @@
namespace oatpp { namespace base {
std::shared_ptr<Logger> Environment::m_logger;
std::unordered_map<std::string, std::unordered_map<std::string, void*>> Environment::m_components;
v_atomicCounter Environment::m_objectsCount(0);
v_atomicCounter Environment::m_objectsCreated(0);
@ -54,6 +51,18 @@ thread_local v_counter Environment::m_threadLocalObjectsCount = 0;
thread_local v_counter Environment::m_threadLocalObjectsCreated = 0;
#endif
std::mutex& Environment::getComponentsMutex() {
static std::mutex componentsMutex;
return componentsMutex;
}
std::unordered_map<std::string, std::unordered_map<std::string, void*>>& Environment::getComponents() {
static std::unordered_map<std::string, std::unordered_map<std::string, void*>> components;
return components;
}
std::shared_ptr<Logger> Environment::m_logger;
DefaultLogger::DefaultLogger(const Config& config)
: m_config(config)
{}
@ -196,15 +205,21 @@ void Environment::init(const std::shared_ptr<Logger>& logger) {
m_threadLocalObjectsCreated = 0;
#endif
if(m_components.size() > 0) {
throw std::runtime_error("[oatpp::base::Environment::init()]: Error. Invalid state. Components were created before call to Environment::init()");
{
std::lock_guard<std::mutex> lock(getComponentsMutex());
if (getComponents().size() > 0) {
throw std::runtime_error("[oatpp::base::Environment::init()]: Error. "
"Invalid state. Components were created before call to Environment::init()");
}
}
}
void Environment::destroy(){
if(m_components.size() > 0) {
throw std::runtime_error("[oatpp::base::Environment::destroy()]: Error. Invalid state. Leaking components");
if(getComponents().size() > 0) {
std::lock_guard<std::mutex> lock(getComponentsMutex());
throw std::runtime_error("[oatpp::base::Environment::destroy()]: Error. "
"Invalid state. Leaking components");
}
m_logger.reset();
@ -364,7 +379,8 @@ void Environment::vlogFormatted(v_uint32 priority, const std::string& tag, const
}
void Environment::registerComponent(const std::string& typeName, const std::string& componentName, void* component) {
auto& bucket = m_components[typeName];
std::lock_guard<std::mutex> lock(getComponentsMutex());
auto& bucket = getComponents()[typeName];
auto it = bucket.find(componentName);
if(it != bucket.end()){
throw std::runtime_error("[oatpp::base::Environment::registerComponent()]: Error. Component with given name already exists: name='" + componentName + "'");
@ -373,8 +389,10 @@ void Environment::registerComponent(const std::string& typeName, const std::stri
}
void Environment::unregisterComponent(const std::string& typeName, const std::string& componentName) {
auto bucketIt = m_components.find(typeName);
if(bucketIt == m_components.end() || bucketIt->second.size() == 0) {
std::lock_guard<std::mutex> lock(getComponentsMutex());
auto& components = getComponents();
auto bucketIt = getComponents().find(typeName);
if(bucketIt == components.end() || bucketIt->second.size() == 0) {
throw std::runtime_error("[oatpp::base::Environment::unregisterComponent()]: Error. Component of given type doesn't exist: type='" + typeName + "'");
}
auto& bucket = bucketIt->second;
@ -384,13 +402,15 @@ void Environment::unregisterComponent(const std::string& typeName, const std::st
}
bucket.erase(componentIt);
if(bucket.size() == 0) {
m_components.erase(bucketIt);
components.erase(bucketIt);
}
}
void* Environment::getComponent(const std::string& typeName) {
auto bucketIt = m_components.find(typeName);
if(bucketIt == m_components.end() || bucketIt->second.size() == 0) {
std::lock_guard<std::mutex> lock(getComponentsMutex());
auto& components = getComponents();
auto bucketIt = components.find(typeName);
if(bucketIt == components.end() || bucketIt->second.size() == 0) {
throw std::runtime_error("[oatpp::base::Environment::getComponent()]: Error. Component of given type doesn't exist: type='" + typeName + "'");
}
auto bucket = bucketIt->second;
@ -401,8 +421,10 @@ void* Environment::getComponent(const std::string& typeName) {
}
void* Environment::getComponent(const std::string& typeName, const std::string& componentName) {
auto bucketIt = m_components.find(typeName);
if(bucketIt == m_components.end() || bucketIt->second.size() == 0) {
std::lock_guard<std::mutex> lock(getComponentsMutex());
auto& components = getComponents();
auto bucketIt = components.find(typeName);
if(bucketIt == components.end() || bucketIt->second.size() == 0) {
throw std::runtime_error("[oatpp::base::Environment::getComponent()]: Error. Component of given type doesn't exist: type='" + typeName + "'");
}
auto bucket = bucketIt->second;

View File

@ -293,12 +293,14 @@ private:
static thread_local v_counter m_threadLocalObjectsCount;
static thread_local v_counter m_threadLocalObjectsCreated;
#endif
private:
static std::mutex& getComponentsMutex();
static std::unordered_map<std::string, std::unordered_map<std::string, void*>>& getComponents();
private:
static std::shared_ptr<Logger> m_logger;
static void checkTypes();
private:
static std::unordered_map<std::string, std::unordered_map<std::string, void*>> m_components;
public:
/**

View File

@ -46,7 +46,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type *getType() {
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -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

@ -622,8 +622,10 @@ namespace __class {
private:
static Type createType() {
Type type(__class::AbstractEnum::CLASS_ID, type::EnumMeta<T>::getInfo()->nameQualifier, new PolymorphicDispatcher());
return type;
Type::Info info;
info.nameQualifier = type::EnumMeta<T>::getInfo()->nameQualifier;
info.polymorphicDispatcher = new PolymorphicDispatcher();
return Type(__class::AbstractEnum::CLASS_ID, info);
}
public:

View File

@ -141,9 +141,10 @@ namespace __class {
private:
static Type createType() {
Type type(__class::AbstractList::CLASS_ID, nullptr, new PolymorphicDispatcher());
type.params.push_back(T::Class::getType());
return type;
Type::Info info;
info.params.push_back(T::Class::getType());
info.polymorphicDispatcher = new PolymorphicDispatcher();
return Type(__class::AbstractList::CLASS_ID, info);
}
public:

View File

@ -97,9 +97,12 @@ 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() {
@ -107,4 +110,9 @@ oatpp::data::mapping::type::BaseObject::Properties* DTO::Z__CLASS_GET_FIELDS_MAP
return &map;
}
BaseObject::Properties* DTO::Z__CLASS_EXTEND(BaseObject::Properties* properties, BaseObject::Properties* extensionProperties) {
properties->pushFrontAll(extensionProperties);
return properties;
}
}}}}

View File

@ -219,9 +219,22 @@ namespace __class {
private:
static type::BaseObject::Properties* initProperties() {
T obj; // initializer;
/* initializer */
T obj;
/* init parent properties */
auto parentType = Object<typename T::Z__CLASS_EXTENDED>::getType();
if(parentType->parent != nullptr) {
auto dispatcher = static_cast<const AbstractObject::PolymorphicDispatcher*>(parentType->polymorphicDispatcher);
dispatcher->getProperties();
}
/* extend parent properties */
T::Z__CLASS_EXTEND(T::Z__CLASS::Z__CLASS_GET_FIELDS_MAP(), T::Z__CLASS_EXTENDED::Z__CLASS_GET_FIELDS_MAP());
return T::Z__CLASS::Z__CLASS_GET_FIELDS_MAP();
}
static const BaseObject::Properties* propertiesGetter() {
@ -229,6 +242,14 @@ namespace __class {
return properties;
}
static Type* createType() {
Type::Info info;
info.nameQualifier = T::Z__CLASS_TYPE_NAME();
info.polymorphicDispatcher = new PolymorphicDispatcher();
info.parent = T::getParentType();
return new Type(CLASS_ID, info);
}
public:
/**
@ -236,7 +257,7 @@ namespace __class {
* @return - &id:oatpp::data::mapping::type::Type;
*/
static Type* getType() {
static Type* type = new Type(CLASS_ID, T::Z__CLASS_TYPE_NAME(), new PolymorphicDispatcher());
static Type* type = createType();
return type;
}
@ -300,6 +321,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;
@ -338,10 +362,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

@ -168,10 +168,11 @@ public:
private:
static Type createType() {
Type type(__class::AbstractPairList::CLASS_ID, nullptr, new PolymorphicDispatcher());
type.params.push_back(Key::Class::getType());
type.params.push_back(Value::Class::getType());
return type;
Type::Info info;
info.params.push_back(Key::Class::getType());
info.params.push_back(Value::Class::getType());
info.polymorphicDispatcher = new PolymorphicDispatcher();
return Type(__class::AbstractPairList::CLASS_ID, info);
}
public:

View File

@ -537,7 +537,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -548,7 +548,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -559,7 +559,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -570,7 +570,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -581,7 +581,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -592,7 +592,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -603,7 +603,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -614,7 +614,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -625,7 +625,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -636,7 +636,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -647,7 +647,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -658,7 +658,7 @@ namespace __class {
static const ClassId CLASS_ID;
static Type* getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}

View File

@ -31,7 +31,7 @@ namespace __class {
const ClassId Void::CLASS_ID("Void");
Type* Void::getType(){
static Type type(CLASS_ID, nullptr);
static Type type(CLASS_ID);
return &type;
}
@ -40,28 +40,47 @@ namespace __class {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ClassId
std::atomic_int ClassId::ID_COUNTER(0);
std::mutex& ClassId::getClassMutex() {
static std::mutex classMutex;
return classMutex;
}
std::vector<const char*>& ClassId::getClassNames() {
static std::vector<const char*> classNames;
return classNames;
}
v_int32 ClassId::registerClassName(const char* name) {
std::lock_guard<std::mutex> lock(getClassMutex());
getClassNames().push_back(name);
return getClassNames().size() - 1;
}
ClassId::ClassId(const char* pName)
: name(pName)
, id(ID_COUNTER ++)
, id(registerClassName(pName))
{}
int ClassId::getClassCount() {
return ID_COUNTER;
std::lock_guard<std::mutex> lock(getClassMutex());
return getClassNames().size();
}
std::vector<const char*> ClassId::getRegisteredClassNames() {
std::lock_guard<std::mutex> lock(getClassMutex());
return std::vector<const char*>(getClassNames());
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Type
Type::Type(const ClassId& pClassId,
const char* pNameQualifier,
void* pPolymorphicDispatcher,
InterpretationMap&& pInterpretationMap)
Type::Type(const ClassId& pClassId, const Info& typeInfo)
: classId(pClassId)
, nameQualifier(pNameQualifier)
, polymorphicDispatcher(pPolymorphicDispatcher)
, interpretationMap(pInterpretationMap)
, nameQualifier(typeInfo.nameQualifier)
, params(typeInfo.params)
, polymorphicDispatcher(typeInfo.polymorphicDispatcher)
, interpretationMap(typeInfo.interpretationMap)
, parent(typeInfo.parent)
{}
const Type::AbstractInterpretation* Type::findInterpretation(const std::vector<std::string>& names) const {
@ -74,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

@ -42,13 +42,21 @@ class Type; // FWD
*/
class ClassId {
private:
static std::atomic_int ID_COUNTER;
static std::mutex& getClassMutex();
static std::vector<const char*>& getClassNames();
static v_int32 registerClassName(const char* name);
public:
/**
* Get count of all type classes created.
* @return
*/
static int getClassCount();
/**
* Get registered class names.
* @return
*/
static std::vector<const char*> getRegisteredClassNames();
public:
/**
@ -67,6 +75,17 @@ public:
* *Note: class type IDs are integer values incremented continuously from [0 to `getClassCount()`]*
*/
const v_int32 id;
public:
inline bool operator == (const ClassId& other) const {
return id == other.id;
}
inline bool operator != (const ClassId& other) const {
return id != other.id;
}
};
@ -362,19 +381,55 @@ public:
typedef std::unordered_map<std::string, const AbstractInterpretation*> InterpretationMap;
public:
/**
* Type info.
*/
struct Info {
/**
* Default constructor.
*/
Info() {}
/**
* Type name qualifier.
*/
const char* nameQualifier = nullptr;
/**
* List of type parameters - for templated types.
*/
std::vector<const Type*> params;
/**
* PolymorphicDispatcher is responsible for forwarding polymorphic calls to a correct object of type `Type`.
*/
void* polymorphicDispatcher = nullptr;
/**
* 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:
/**
* Constructor.
* @param pClassId - type class id.
* @param pNameQualifier - type name qualifier.
* @param pPolymorphicDispatcher - is an object to forward polymorphic calls to a correct object of type `Type`.
* @param pInterpretationMap - Map of type Interpretations.
* @param typeInfo - type creation info. &l:Type::Info;.
*/
Type(const ClassId& pClassId,
const char* pNameQualifier,
void* pPolymorphicDispatcher = nullptr,
InterpretationMap&& pInterpretationMap = InterpretationMap{});
Type(const ClassId& pClassId, const Info& typeInfo = Info());
/**
* type class id.
@ -389,7 +444,7 @@ public:
/**
* List of type parameters - for templated types.
*/
std::list<const Type*> params;
const std::vector<const Type*> params;
/**
* PolymorphicDispatcher - is an object to forward polymorphic calls to a correct object of type `Type`.
@ -401,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:
/**
@ -411,6 +474,13 @@ public:
*/
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;
};
#define OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(WRAPPER_NAME, OBJECT_TYPE, OBJECT_CLASS) \
@ -460,6 +530,18 @@ public: \
namespace std {
template<>
struct hash<oatpp::data::mapping::type::ClassId> {
typedef oatpp::data::mapping::type::ClassId argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
return v.id;
}
};
template<>
struct hash<oatpp::data::mapping::type::Void> {

View File

@ -141,10 +141,11 @@ namespace __class {
private:
static Type createType() {
Type type(__class::AbstractUnorderedMap::CLASS_ID, nullptr, new PolymorphicDispatcher());
type.params.push_back(Key::Class::getType());
type.params.push_back(Value::Class::getType());
return type;
Type::Info info;
info.params.push_back(Key::Class::getType());
info.params.push_back(Value::Class::getType());
info.polymorphicDispatcher = new PolymorphicDispatcher();
return Type(__class::AbstractUnorderedMap::CLASS_ID, info);
}
public:

View File

@ -143,9 +143,10 @@ public:
private:
static Type createType() {
Type type(__class::AbstractUnorderedSet::CLASS_ID, nullptr, new PolymorphicDispatcher());
type.params.push_back(T::Class::getType());
return type;
Type::Info info;
info.params.push_back(T::Class::getType());
info.polymorphicDispatcher = new PolymorphicDispatcher();
return Type(__class::AbstractUnorderedSet::CLASS_ID, info);
}
public:

View File

@ -139,9 +139,10 @@ namespace __class {
private:
static Type createType() {
Type type(__class::AbstractVector::CLASS_ID, nullptr, new PolymorphicDispatcher());
type.params.push_back(T::Class::getType());
return type;
Type::Info info;
info.params.push_back(T::Class::getType());
info.polymorphicDispatcher = new PolymorphicDispatcher();
return Type(__class::AbstractVector::CLASS_ID, info);
}
public:

View File

@ -67,11 +67,10 @@ Deserializer::Deserializer(const std::shared_ptr<Config>& config)
void Deserializer::setDeserializerMethod(const data::mapping::type::ClassId& classId, DeserializerMethod method) {
const v_uint32 id = classId.id;
if(id < m_methods.size()) {
m_methods[id] = method;
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Deserializer::setDeserializerMethod()]: Error. Unknown classId");
if(id >= m_methods.size()) {
m_methods.resize(id + 1, nullptr);
}
m_methods[id] = method;
}
void Deserializer::skipScope(oatpp::parser::Caret& caret, v_char8 charOpen, v_char8 charClose){

View File

@ -68,11 +68,10 @@ Serializer::Serializer(const std::shared_ptr<Config>& config)
void Serializer::setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method) {
const v_uint32 id = classId.id;
if(id < m_methods.size()) {
m_methods[id] = method;
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::setSerializerMethod()]: Error. Unknown classId");
if(id >= m_methods.size()) {
m_methods.resize(id + 1, nullptr);
}
m_methods[id] = method;
}
void Serializer::serializeString(data::stream::ConsistentOutputStream* stream, const char* data, v_buff_size size, v_uint32 escapeFlags) {

View File

@ -79,6 +79,14 @@ void runTests() {
OATPP_LOGD("Tests", "action size=%d", sizeof(oatpp::async::Action));
OATPP_LOGD("Tests", "class count=%d", oatpp::data::mapping::type::ClassId::getClassCount());
auto names = oatpp::data::mapping::type::ClassId::getRegisteredClassNames();
v_int32 i = 0;
for(auto& name : names) {
OATPP_LOGD("CLASS", "%d --> '%s'", i, name);
i ++;
}
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
OATPP_RUN_TEST(oatpp::test::base::LoggerTest);

View File

@ -88,18 +88,23 @@ namespace __class {
};
private:
static oatpp::Type* createType() {
oatpp::Type::Info info;
info.interpretationMap = {
{"test", new Inter()}
};
return new Type(CLASS_ID, info);
}
public:
static const oatpp::ClassId CLASS_ID;
static oatpp::Type* getType(){
static Type type(
CLASS_ID, nullptr, nullptr,
{
{"test", new Inter()}
}
);
return &type;
static Type* type = createType();
return type;
}
};
@ -137,18 +142,23 @@ namespace __class {
};
private:
static oatpp::Type* createType() {
oatpp::Type::Info info;
info.interpretationMap = {
{"test", new Inter()}
};
return new oatpp::Type(CLASS_ID, info);
}
public:
static const oatpp::ClassId CLASS_ID;
static oatpp::Type* getType(){
static Type type(
CLASS_ID, nullptr, nullptr,
{
{"test", new Inter()}
}
);
return &type;
static Type* type = createType();
return type;
}
};

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()))
}