mirror of
https://github.com/oatpp/oatpp.git
synced 2025-01-18 16:43:57 +08:00
Types. Introduce Any.
This commit is contained in:
parent
2c037d1cc1
commit
0d951e3c56
@ -74,6 +74,8 @@ add_library(oatpp
|
||||
oatpp/core/data/buffer/Processor.hpp
|
||||
oatpp/core/data/mapping/ObjectMapper.cpp
|
||||
oatpp/core/data/mapping/ObjectMapper.hpp
|
||||
oatpp/core/data/mapping/type/Any.cpp
|
||||
oatpp/core/data/mapping/type/Any.hpp
|
||||
oatpp/core/data/mapping/type/List.cpp
|
||||
oatpp/core/data/mapping/type/List.hpp
|
||||
oatpp/core/data/mapping/type/ListMap.cpp
|
||||
|
@ -25,10 +25,17 @@
|
||||
#ifndef oatpp_Types_hpp
|
||||
#define oatpp_Types_hpp
|
||||
|
||||
#include "oatpp/core/data/mapping/type/Any.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Object.hpp"
|
||||
|
||||
namespace oatpp {
|
||||
|
||||
/**
|
||||
* `Any` - container for mapping-enabled types.
|
||||
* &id:oatpp::data::mapping::type::Any;
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Any Any;
|
||||
|
||||
/**
|
||||
* Mapping-Enabled String type. &id:oatpp::data::mapping::type::String; <br>
|
||||
* For `oatpp::String` methods see &id:oatpp::base::StrBuffer;
|
||||
|
96
src/oatpp/core/data/mapping/type/Any.cpp
Normal file
96
src/oatpp/core/data/mapping/type/Any.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "Any.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
const ClassId Any::CLASS_ID("Any");
|
||||
}
|
||||
|
||||
Any::Any()
|
||||
: PolymorphicWrapper(__class::Any::getType())
|
||||
{}
|
||||
|
||||
Any::Any(std::nullptr_t) : Any() {}
|
||||
|
||||
Any::Any(const AbstractObjectWrapper& polymorph)
|
||||
: PolymorphicWrapper(std::make_shared<AnyHandle>(polymorph.getPtr(), polymorph.valueType), __class::Any::getType())
|
||||
{}
|
||||
|
||||
Any::Any(const Any& other)
|
||||
: PolymorphicWrapper(std::make_shared<AnyHandle>(other.m_ptr->ptr, other.m_ptr->type), __class::Any::getType())
|
||||
{}
|
||||
|
||||
Any::Any(Any&& other)
|
||||
: PolymorphicWrapper(std::move(other.m_ptr), __class::Any::getType())
|
||||
{}
|
||||
|
||||
void Any::store(const AbstractObjectWrapper& polymorph) {
|
||||
m_ptr = std::make_shared<AnyHandle>(polymorph.getPtr(), polymorph.valueType);
|
||||
}
|
||||
|
||||
const Type* const Any::getStoredType() {
|
||||
if(m_ptr) {
|
||||
return m_ptr->type;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Any& Any::operator=(std::nullptr_t) {
|
||||
m_ptr.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Any& Any::operator=(const AbstractObjectWrapper& other) {
|
||||
m_ptr = std::make_shared<AnyHandle>(other.getPtr(), other.valueType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Any& Any::operator=(const Any& other) {
|
||||
if(other) {
|
||||
m_ptr = std::make_shared<AnyHandle>(other.m_ptr->ptr, other.m_ptr->type);
|
||||
} else {
|
||||
m_ptr.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Any& Any::operator=(Any&& other) {
|
||||
m_ptr = std::move(other.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Any::operator == (const Any& other) {
|
||||
if(!m_ptr && !other.m_ptr) return true;
|
||||
if(!m_ptr || !other.m_ptr) return false;
|
||||
return m_ptr->ptr.get() == other.m_ptr->ptr.get();
|
||||
}
|
||||
|
||||
bool Any::operator != (const Any& other) {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
}}}}
|
110
src/oatpp/core/data/mapping/type/Any.hpp
Normal file
110
src/oatpp/core/data/mapping/type/Any.hpp
Normal file
@ -0,0 +1,110 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_mapping_type_Any_hpp
|
||||
#define oatpp_data_mapping_type_Any_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "oatpp/core/collection/LinkedList.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class Any {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
static Type *getType() {
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class AnyHandle : public base::Countable {
|
||||
public:
|
||||
|
||||
AnyHandle(const std::shared_ptr<base::Countable>& objPtr, const Type* const objType)
|
||||
: ptr(objPtr)
|
||||
, type(objType)
|
||||
{}
|
||||
|
||||
std::shared_ptr<base::Countable> ptr;
|
||||
const Type* const type;
|
||||
|
||||
};
|
||||
|
||||
class Any : public PolymorphicWrapper<AnyHandle>{
|
||||
public:
|
||||
|
||||
Any();
|
||||
|
||||
Any(std::nullptr_t);
|
||||
Any(const AbstractObjectWrapper& polymorph);
|
||||
|
||||
Any(const Any& other);
|
||||
Any(Any&& other);
|
||||
|
||||
void store(const AbstractObjectWrapper& polymorph);
|
||||
|
||||
const Type* const getStoredType();
|
||||
|
||||
template<class WrapperType>
|
||||
WrapperType retrieve() {
|
||||
|
||||
if(m_ptr) {
|
||||
|
||||
if(m_ptr->type != WrapperType::Class::getType()) {
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::Any::retrieve()]: Error. The value type doesn't match.");
|
||||
}
|
||||
|
||||
return WrapperType(std::static_pointer_cast<typename WrapperType::ObjectType>(m_ptr->ptr), m_ptr->type);
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
Any& operator=(std::nullptr_t);
|
||||
Any& operator=(const AbstractObjectWrapper& other);
|
||||
|
||||
Any& operator=(const Any& other);
|
||||
Any& operator=(Any&& other);
|
||||
|
||||
bool operator == (const Any& other);
|
||||
bool operator != (const Any& other);
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif //oatpp_data_mapping_type_Any_hpp
|
@ -152,7 +152,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolymorphicWrapper& operator=(const PolymorphicWrapper<T>&& other){
|
||||
PolymorphicWrapper& operator=(PolymorphicWrapper<T>&& other){
|
||||
m_ptr = std::move(other.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
@ -258,7 +258,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
ObjectWrapper& operator=(const PolymorphicWrapper<T>&& other){
|
||||
ObjectWrapper& operator=(PolymorphicWrapper<T>&& other){
|
||||
if(this->valueType != other.valueType){
|
||||
OATPP_LOGE("ObjectWrapper", "Invalid class cast");
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::ObjectWrapper]: Invalid class cast");
|
||||
|
@ -15,6 +15,8 @@ add_executable(oatppAllTests
|
||||
oatpp/core/base/memory/PerfTest.hpp
|
||||
oatpp/core/data/buffer/ProcessorTest.cpp
|
||||
oatpp/core/data/buffer/ProcessorTest.hpp
|
||||
oatpp/core/data/mapping/type/AnyTest.cpp
|
||||
oatpp/core/data/mapping/type/AnyTest.hpp
|
||||
oatpp/core/data/mapping/type/TypeTest.cpp
|
||||
oatpp/core/data/mapping/type/TypeTest.hpp
|
||||
oatpp/core/data/share/LazyStringMapTest.cpp
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "oatpp/core/parser/CaretTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/mapping/type/TypeTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/AnyTest.hpp"
|
||||
|
||||
#include "oatpp/core/base/collection/LinkedListTest.hpp"
|
||||
#include "oatpp/core/base/memory/MemoryPoolTest.hpp"
|
||||
#include "oatpp/core/base/memory/PerfTest.hpp"
|
||||
@ -82,6 +84,7 @@ void runTests() {
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::stream::BufferStreamTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::TypeTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::AnyTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::async::LockTest);
|
||||
|
||||
|
171
test/oatpp/core/data/mapping/type/AnyTest.cpp
Normal file
171
test/oatpp/core/data/mapping/type/AnyTest.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "AnyTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/mapping/type/Any.hpp"
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class Dto1 : public oatpp::Object {
|
||||
DTO_INIT(Dto1, Object);
|
||||
};
|
||||
|
||||
class Dto2 : public oatpp::Object {
|
||||
DTO_INIT(Dto2, Object);
|
||||
};
|
||||
|
||||
class Test : public oatpp::Object {
|
||||
|
||||
DTO_INIT(Test, Object);
|
||||
|
||||
DTO_FIELD(oatpp::Any, any);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}
|
||||
|
||||
void AnyTest::onRun() {
|
||||
|
||||
{
|
||||
oatpp::Any any;
|
||||
OATPP_ASSERT(!any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::Any any(nullptr);
|
||||
OATPP_ASSERT(!any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::Any any(oatpp::String("Hello Any!"));
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
auto str = any.retrieve<oatpp::String>();
|
||||
OATPP_ASSERT(str == "Hello Any!");
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::Any any(oatpp::Int32(32));
|
||||
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::Int32::getType());
|
||||
|
||||
any.store(oatpp::String("Hello Any!"));
|
||||
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
|
||||
auto str = any.retrieve<oatpp::String>();
|
||||
OATPP_ASSERT(str == "Hello Any!");
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::Any any(Dto1::createShared());
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == Dto1::ObjectWrapper::Class::getType());
|
||||
|
||||
bool wasError = false;
|
||||
|
||||
try {
|
||||
auto obj = any.retrieve<Dto2::ObjectWrapper>(); // wrong object
|
||||
} catch (std::runtime_error& e) {
|
||||
wasError = true;
|
||||
}
|
||||
|
||||
OATPP_ASSERT(wasError);
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::Any any1(oatpp::String("Hello!"));
|
||||
oatpp::Any any2;
|
||||
|
||||
any2 = any1;
|
||||
|
||||
OATPP_ASSERT(any1);
|
||||
OATPP_ASSERT(any2);
|
||||
|
||||
OATPP_ASSERT(any1.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any2.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
|
||||
OATPP_ASSERT(any1.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
OATPP_ASSERT(any2.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
|
||||
OATPP_ASSERT(any1 == any2);
|
||||
OATPP_ASSERT(any1.getPtr().get() != any2.getPtr().get());
|
||||
|
||||
auto str1 = any1.retrieve<oatpp::String>();
|
||||
auto str2 = any2.retrieve<oatpp::String>();
|
||||
|
||||
OATPP_ASSERT(str1 == str2);
|
||||
OATPP_ASSERT(str1.get() == str2.get() && str1 == "Hello!");
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::Any any1(oatpp::String("Hello!"));
|
||||
oatpp::Any any2;
|
||||
|
||||
any2 = std::move(any1);
|
||||
|
||||
OATPP_ASSERT(!any1);
|
||||
OATPP_ASSERT(any2);
|
||||
|
||||
OATPP_ASSERT(any1.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any2.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
|
||||
OATPP_ASSERT(any1.getStoredType() == nullptr);
|
||||
OATPP_ASSERT(any2.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
|
||||
OATPP_ASSERT(any1 != any2);
|
||||
OATPP_ASSERT(any1.getPtr().get() != any2.getPtr().get());
|
||||
|
||||
auto str1 = any1.retrieve<oatpp::String>();
|
||||
auto str2 = any2.retrieve<oatpp::String>();
|
||||
|
||||
OATPP_ASSERT(str1 != str2);
|
||||
OATPP_ASSERT(str2 == "Hello!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/AnyTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/AnyTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_test_core_data_mapping_type_AnyTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_AnyTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class AnyTest : public UnitTest{
|
||||
public:
|
||||
|
||||
AnyTest():UnitTest("TEST[core::data::mapping::type::AnyTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_AnyTest_hpp */
|
Loading…
Reference in New Issue
Block a user