Tree: TreeMap - fix assignment operators

This commit is contained in:
Leonid Stryzhevskyi 2024-05-01 02:44:48 +03:00
parent 8137eba15e
commit 77ca525d2c
5 changed files with 107 additions and 64 deletions

View File

@ -31,11 +31,41 @@ namespace oatpp { namespace data { namespace mapping {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TreeMap
TreeMap::TreeMap(const TreeMap& other) {
operator=(other);
}
TreeMap::TreeMap(TreeMap&& other) noexcept {
operator=(std::forward<TreeMap>(other));
}
TreeMap& TreeMap::operator = (const TreeMap& other) {
m_map = other.m_map;
m_order.resize(other.m_order.size());
for(v_uint64 i = 0; i < other.m_order.size(); i ++) {
auto& po = other.m_order[i];
auto& pt = m_order[i];
pt.first = po.first;
pt.second = &m_map.at(po.first.lock());
}
return *this;
}
TreeMap& TreeMap::operator = (TreeMap&& other) noexcept {
m_map = std::move(other.m_map);
m_order = std::move(other.m_order);
for(auto& p : m_order) {
p.second = &m_map.at(p.first.lock());
}
return *this;
}
Tree& TreeMap::operator [] (const oatpp::String& key) {
auto it = m_map.find(key);
if(it == m_map.end()) {
auto& result = m_map[key];
m_order.push_back(key);
m_order.emplace_back(key.getPtr(), &result);
return result;
}
return it->second;
@ -50,13 +80,13 @@ const Tree& TreeMap::operator [] (const oatpp::String& key) const {
}
std::pair<oatpp::String, std::reference_wrapper<Tree>> TreeMap::operator [] (v_uint64 index) {
auto& key = m_order.at(index);
return {key, m_map[key]};
auto& item = m_order.at(index);
return {item.first.lock(), *item.second};
}
std::pair<oatpp::String, std::reference_wrapper<const Tree>> TreeMap::operator [] (v_uint64 index) const {
auto& key = m_order.at(index);
return {key, m_map.at(key)};
auto& item = m_order.at(index);
return {item.first.lock(), *item.second};
}
v_uint64 TreeMap::size() const {

View File

@ -36,32 +36,31 @@ public:
enum class Type : v_int32 {
UNDEFINED = -1,
UNDEFINED = 0,
NULL_VALUE = 1,
NULL_VALUE = 0,
INTEGER = 2,
FLOAT = 3,
INTEGER = 1,
FLOAT = 2,
BOOL = 4,
BOOL = 3,
INT_8 = 5,
UINT_8 = 6,
INT_16 = 7,
UINT_16 = 8,
INT_32 = 9,
UINT_32 = 10,
INT_64 = 11,
UINT_64 = 12,
INT_8 = 4,
UINT_8 = 5,
INT_16 = 6,
UINT_16 = 7,
INT_32 = 8,
UINT_32 = 9,
INT_64 = 10,
UINT_64 = 11,
FLOAT_32 = 13,
FLOAT_64 = 14,
FLOAT_32 = 12,
FLOAT_64 = 13,
STRING = 15,
STRING = 14,
VECTOR = 15,
MAP = 16,
PAIRS = 17
VECTOR = 16,
MAP = 17,
PAIRS = 18
};
@ -240,9 +239,17 @@ public:
class TreeMap {
private:
std::unordered_map<oatpp::String, Tree> m_map;
std::vector<oatpp::String> m_order;
std::vector<std::pair<std::weak_ptr<std::string>, Tree*>> m_order;
public:
TreeMap() = default;
TreeMap(const TreeMap& other);
TreeMap(TreeMap&& other) noexcept;
TreeMap& operator = (const TreeMap& other);
TreeMap& operator = (TreeMap&& other) noexcept;
Tree& operator [] (const oatpp::String& key);
const Tree& operator [] (const oatpp::String& key) const;

View File

@ -124,6 +124,7 @@ const Type* TreeToObjectMapper::guessType(const Tree& node) {
case Tree::Type::STRING: return String::Class::getType();
case Tree::Type::VECTOR: return Vector<oatpp::Any>::Class::getType();
case Tree::Type::MAP: return Fields<oatpp::Any>::Class::getType();
case Tree::Type::PAIRS: return Fields<oatpp::Any>::Class::getType();
default: return nullptr;
@ -136,14 +137,14 @@ oatpp::Void TreeToObjectMapper::mapString(const TreeToObjectMapper* mapper, Mapp
(void) mapper;
(void) type;
if(state.tree->isNull()){
return oatpp::Void(String::Class::getType());
}
if(state.tree->getType() == Tree::Type::STRING) {
return state.tree->getString();
}
if(state.tree->isNull()){
return oatpp::Void(String::Class::getType());
}
state.errorStack.emplace_back("[oatpp::data::TreeToObjectMapper::mapString()]: Node is NOT a STRING");
return nullptr;
@ -200,11 +201,10 @@ oatpp::Void TreeToObjectMapper::mapEnum(const TreeToObjectMapper* mapper, Mappin
oatpp::Void TreeToObjectMapper::mapCollection(const TreeToObjectMapper* mapper, MappingState& state, const Type* const type) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
if(state.tree->getType() != Tree::Type::VECTOR) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
state.errorStack.emplace_back("[oatpp::data::TreeToObjectMapper::mapCollection()]: Node is NOT a VECTOR.");
return nullptr;
}
@ -218,12 +218,12 @@ oatpp::Void TreeToObjectMapper::mapCollection(const TreeToObjectMapper* mapper,
v_int64 index = 0;
MappingState nestedState;
nestedState.config = state.config;
for(const auto& node : vector) {
MappingState nestedState;
nestedState.tree = &node;
nestedState.config = state.config;
auto item = mapper->map(nestedState, itemType);
if(!nestedState.errorStack.empty()) {
@ -244,11 +244,10 @@ oatpp::Void TreeToObjectMapper::mapCollection(const TreeToObjectMapper* mapper,
oatpp::Void TreeToObjectMapper::mapMap(const TreeToObjectMapper* mapper, MappingState& state, const Type* const type) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
if(state.tree->getType() != Tree::Type::MAP) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
state.errorStack.emplace_back("[oatpp::data::TreeToObjectMapper::mapMap()]: Node is NOT a MAP.");
return nullptr;
}
@ -266,13 +265,14 @@ oatpp::Void TreeToObjectMapper::mapMap(const TreeToObjectMapper* mapper, Mapping
const auto& treeMap = state.tree->getMap();
auto treeMapSize = treeMap.size();
MappingState nestedState;
nestedState.config = state.config;
for(v_uint64 i = 0; i < treeMapSize; i ++) {
const auto& node = treeMap[i];
MappingState nestedState;
nestedState.tree = &node.second.get();
nestedState.config = state.config;
auto item = mapper->map(nestedState, valueType);
@ -292,11 +292,10 @@ oatpp::Void TreeToObjectMapper::mapMap(const TreeToObjectMapper* mapper, Mapping
oatpp::Void TreeToObjectMapper::mapObject(const TreeToObjectMapper* mapper, MappingState& state, const Type* const type) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
if(state.tree->getType() != Tree::Type::MAP) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
state.errorStack.emplace_back("[oatpp::data::TreeToObjectMapper::mapObject()]: Node is NOT a MAP.");
return nullptr;
}

View File

@ -57,14 +57,14 @@ public:
static oatpp::Void mapPrimitive(const TreeToObjectMapper* mapper, MappingState& state, const Type* const type){
(void) mapper;
(void) type;
if(state.tree->isPrimitive()) {
return T(state.tree->operator typename T::UnderlyingType());
}
if(state.tree->isNull()) {
return oatpp::Void(T::Class::getType());
}
if(!state.tree->isPrimitive()) {
state.errorStack.emplace_back("[oatpp::data::TreeToObjectMapper::mapPrimitive()]: Value is NOT a Primitive type");
return nullptr;
}
return T(state.tree->operator typename T::UnderlyingType());
state.errorStack.emplace_back("[oatpp::data::TreeToObjectMapper::mapPrimitive()]: Value is NOT a Primitive type");
return nullptr;
}
static const Type* guessType(const Tree& node);

View File

@ -84,18 +84,24 @@ void runTests() {
OATPP_LOGD("Tests", "oatpp::String size=%lu", sizeof(oatpp::String))
OATPP_LOGD("Tests", "std::string size=%lu", sizeof(std::string))
OATPP_LOGD("Tests", "Vector size=%lu", sizeof(std::vector<int>))
OATPP_LOGD("Tests", "Map size=%lu", sizeof(std::unordered_map<oatpp::String, oatpp::String>))
OATPP_LOGD("Tests", "Tree size=%lu", sizeof(oatpp::data::mapping::Tree))
OATPP_LOGD("Tests", "coroutine handle size=%lu", sizeof(oatpp::async::CoroutineHandle))
OATPP_LOGD("Tests", "coroutine size=%lu", sizeof(oatpp::async::AbstractCoroutine))
OATPP_LOGD("Tests", "action size=%lu", sizeof(oatpp::async::Action))
OATPP_LOGD("Tests", "class count=%d", oatpp::data::mapping::type::ClassId::getClassCount())
//return;
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_LOGD("Tests", "coroutine handle size=%lu", sizeof(oatpp::async::CoroutineHandle))
// OATPP_LOGD("Tests", "coroutine size=%lu", sizeof(oatpp::async::AbstractCoroutine))
// OATPP_LOGD("Tests", "action size=%lu", 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::LoggerTest);
OATPP_RUN_TEST(oatpp::base::CommandLineArgumentsTest);
@ -109,7 +115,7 @@ void runTests() {
OATPP_RUN_TEST(oatpp::data::stream::BufferStreamTest);
*/
//OATPP_RUN_TEST(oatpp::data::mapping::TreeTest);
OATPP_RUN_TEST(oatpp::data::mapping::TreeTest);
OATPP_RUN_TEST(oatpp::data::mapping::TreeToObjectMapperTest);
@ -148,9 +154,10 @@ void runTests() {
OATPP_RUN_TEST(oatpp::json::UnorderedSetTest);
OATPP_RUN_TEST(oatpp::json::DeserializerTest);
OATPP_RUN_TEST(oatpp::json::DTOMapperPerfTest);
/*
OATPP_RUN_TEST(oatpp::json::DTOMapperTest);
/*
OATPP_RUN_TEST(oatpp::test::encoding::Base64Test);
OATPP_RUN_TEST(oatpp::test::encoding::UnicodeTest);
OATPP_RUN_TEST(oatpp::test::encoding::UrlTest);