From 6646e4cf87ca3b7df099be500aca34d2726e814b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Tr=C3=A1vn=C3=AD=C4=8Dek?= <jan.travnicek@fit.cvut.cz>
Date: Mon, 24 Jan 2022 17:09:57 +0100
Subject: [PATCH] abstraction: make sure an object made unique does not
 participate in denormalization

---
 alib2abstraction/src/core/type_details.cpp | 4 ++++
 alib2abstraction/src/core/type_details.hpp | 2 ++
 alib2abstraction/src/object/Object.cpp     | 2 ++
 alib2str/src/core/stringApi.cpp            | 4 ++--
 alib2xml/src/core/xmlApi.cpp               | 4 ++--
 5 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/alib2abstraction/src/core/type_details.cpp b/alib2abstraction/src/core/type_details.cpp
index 81a6ef713d..8d6bd65dca 100644
--- a/alib2abstraction/src/core/type_details.cpp
+++ b/alib2abstraction/src/core/type_details.cpp
@@ -33,6 +33,10 @@ bool type_details::compatible_with ( const type_details & other ) const {
 	return m_type_details->compatible_with ( * other.m_type_details );
 }
 
+bool type_details::compatible_with ( const type_details_base & other ) const {
+	return m_type_details->compatible_with ( other );
+}
+
 std::ostream & operator << ( std::ostream & os, const type_details & arg ) {
 	return os << ( * arg.m_type_details );
 }
diff --git a/alib2abstraction/src/core/type_details.hpp b/alib2abstraction/src/core/type_details.hpp
index cdfc9036d4..83dc2079f5 100644
--- a/alib2abstraction/src/core/type_details.hpp
+++ b/alib2abstraction/src/core/type_details.hpp
@@ -45,6 +45,8 @@ public:
 
 	bool compatible_with ( const type_details & other ) const;
 
+	bool compatible_with ( const type_details_base & other ) const;
+
 	friend std::ostream & operator << ( std::ostream & os, const type_details & arg );
 
 	std::strong_ordering operator <=> ( const type_details & other ) const;
diff --git a/alib2abstraction/src/object/Object.cpp b/alib2abstraction/src/object/Object.cpp
index 03cb15af31..5bb91f9de4 100644
--- a/alib2abstraction/src/object/Object.cpp
+++ b/alib2abstraction/src/object/Object.cpp
@@ -119,6 +119,8 @@ object::Object type_util < object::Object >::normalize ( object::Object && arg )
 }
 
 std::unique_ptr < type_details_base > type_util < object::Object >::type ( const object::Object & arg ) {
+	if ( arg.getId ( ) > 0 ) // Denormalization of an object that is incremented to its actual type would drop the id
+		return std::make_unique < type_details_type > ( "object::Object" );
 	return arg.getType ( );
 }
 
diff --git a/alib2str/src/core/stringApi.cpp b/alib2str/src/core/stringApi.cpp
index 98eead5e03..c931504bdd 100644
--- a/alib2str/src/core/stringApi.cpp
+++ b/alib2str/src/core/stringApi.cpp
@@ -80,8 +80,8 @@ bool stringApi < object::Object >::first ( ext::istream & input ) {
 }
 
 void stringApi < object::Object >::compose ( ext::ostream & output, const object::Object & data ) {
-	core::type_details type = core::type_details::get ( data );
-	auto callback = std::find_if ( composeFunctions ( ).begin ( ), composeFunctions ( ).end ( ), [ & ] ( const std::pair < const core::type_details, std::unique_ptr < GroupWriter > > & entry ) { return entry.first.compatible_with ( type ); } );
+	std::unique_ptr < core::type_details_base > type = data.getType ( );
+	auto callback = std::find_if ( composeFunctions ( ).begin ( ), composeFunctions ( ).end ( ), [ & ] ( const std::pair < const core::type_details, std::unique_ptr < GroupWriter > > & entry ) { return entry.first.compatible_with ( * type ); } );
 
 	if ( callback == composeFunctions ( ).end ( ) ) throw exception::CommonException ( "Compose callback for " + ext::to_string ( type ) + " tag not registered." );
 
diff --git a/alib2xml/src/core/xmlApi.cpp b/alib2xml/src/core/xmlApi.cpp
index 4473eb5e86..8fb14a015c 100644
--- a/alib2xml/src/core/xmlApi.cpp
+++ b/alib2xml/src/core/xmlApi.cpp
@@ -150,8 +150,8 @@ void xmlApi < object::Object >::composeUnique ( xmlApiOutputContext & output, co
 }
 
 void xmlApi < object::Object >::composeObject ( xmlApiOutputContext & output, const object::Object & data ) {
-	core::type_details type = core::type_details::get ( data );
-	auto callback = std::find_if ( composeFunctions ( ).begin ( ), composeFunctions ( ).end ( ), [ & ] ( const std::pair < const core::type_details, std::unique_ptr < GroupComposer > > & entry ) { return entry.first.compatible_with ( type ); } );
+	std::unique_ptr < core::type_details_base > type = data.getType ( );
+	auto callback = std::find_if ( composeFunctions ( ).begin ( ), composeFunctions ( ).end ( ), [ & ] ( const std::pair < const core::type_details, std::unique_ptr < GroupComposer > > & entry ) { return entry.first.compatible_with ( * type ); } );
 
 	if ( callback == composeFunctions ( ).end ( ) )
 		throw exception::CommonException ( "Compose callback for " + ext::to_string ( type ) + " tag not registered." );
-- 
GitLab