From 18eafd9f0d4144c1be6388e2e504624436c8ce47 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 20 Nov 2017 21:09:16 +0100
Subject: [PATCH] make to_string of type handle incomplete type

---
 alib2common/src/core/components/setComponents.hpp |  8 +++-----
 alib2std/src/extensions/typeinfo.hpp              |  9 ++++++++-
 alib2std/test-src/extensions/TypeTraitsTest.cpp   | 11 +++++++++++
 alib2std/test-src/extensions/TypeTraitsTest.h     | 10 ++++++----
 4 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/alib2common/src/core/components/setComponents.hpp b/alib2common/src/core/components/setComponents.hpp
index 9ed8756684..1746248c0c 100644
--- a/alib2common/src/core/components/setComponents.hpp
+++ b/alib2common/src/core/components/setComponents.hpp
@@ -80,9 +80,8 @@ class SetComponent {
 		SetConstraint < Derived, ComponentType, ComponentName >::valid ( static_cast < const Derived & > ( * this ), element );
 
 		if ( ! SetConstraint < Derived, ComponentType, ComponentName >::available ( static_cast < const Derived & > ( * this ), element ) ) {
-			std::string elementTypeName ( ext::to_string < ComponentName * > ( ) );
-			elementTypeName.back ( ) = ' ';
-			throw exception::CommonException ( elementTypeName + "element " + ext::to_string ( element ) + " is not available." );
+			std::string elementTypeName ( ext::to_string < ComponentName > ( ) );
+			throw exception::CommonException ( elementTypeName + " element " + ext::to_string ( element ) + " is not available." );
 		}
 	}
 
@@ -92,8 +91,7 @@ class SetComponent {
 	 */
 	void checkRemove ( const ComponentType & element ) {
 		if ( SetConstraint < Derived, ComponentType, ComponentName >::used ( static_cast < const Derived & > ( * this ), element ) ) {
-			std::string elementTypeName ( ext::to_string < ComponentName * > ( ) );
-			elementTypeName.back ( ) = ' ';
+			std::string elementTypeName ( ext::to_string < ComponentName > ( ) );
 			throw exception::CommonException ( elementTypeName + "element " + ext::to_string ( element ) + " is used." );
 		}
 	}
diff --git a/alib2std/src/extensions/typeinfo.hpp b/alib2std/src/extensions/typeinfo.hpp
index 87788250fd..e9dfc7e806 100644
--- a/alib2std/src/extensions/typeinfo.hpp
+++ b/alib2std/src/extensions/typeinfo.hpp
@@ -17,7 +17,14 @@
 
 namespace ext {
 
-template < class T >
+template < class T, typename std::enable_if < std::is_class < T >::value >::type * = nullptr >
+std::string to_string ( ) {
+	std::string res = ext::to_string ( ext::type_index ( typeid ( T * ) ) ); // handle even incomplete class types
+	res.pop_back ( ); // to erase extra pointer
+	return res;
+}
+
+template < class T, typename std::enable_if < ! std::is_class < T >::value >::type * = nullptr >
 std::string to_string ( ) {
 	return ext::to_string ( ext::type_index ( typeid ( T ) ) );
 }
diff --git a/alib2std/test-src/extensions/TypeTraitsTest.cpp b/alib2std/test-src/extensions/TypeTraitsTest.cpp
index 378172ede6..2d6c796e0c 100644
--- a/alib2std/test-src/extensions/TypeTraitsTest.cpp
+++ b/alib2std/test-src/extensions/TypeTraitsTest.cpp
@@ -20,3 +20,14 @@ void TypeTraitsTest::testTypeInPack() {
 
 	CPPUNIT_ASSERT( ( ext::is_in< std::pair < int, int >, void, ext::pair < int, int > >::value ) == false );
 }
+
+class Foo {
+};
+
+class Bar;
+
+void TypeTraitsTest::testTypeNames() {
+	CPPUNIT_ASSERT ( ext::to_string < Foo > ( ) == "Foo" );
+	CPPUNIT_ASSERT ( ext::to_string < Bar > ( ) == "Bar" );
+	CPPUNIT_ASSERT ( ext::to_string < int > ( ) == "int" );
+}
diff --git a/alib2std/test-src/extensions/TypeTraitsTest.h b/alib2std/test-src/extensions/TypeTraitsTest.h
index 84a41ae0e7..d5c68afb69 100644
--- a/alib2std/test-src/extensions/TypeTraitsTest.h
+++ b/alib2std/test-src/extensions/TypeTraitsTest.h
@@ -8,6 +8,7 @@ class TypeTraitsTest : public CppUnit::TestFixture
   CPPUNIT_TEST_SUITE( TypeTraitsTest );
   CPPUNIT_TEST( testAccessPackElement );
   CPPUNIT_TEST( testTypeInPack );
+  CPPUNIT_TEST( testTypeNames );
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -60,11 +61,12 @@ struct test2 {
 };
 
 public:
-  void setUp();
-  void tearDown();
+	void setUp();
+	void tearDown();
 
-  void testAccessPackElement();
-  void testTypeInPack();
+	void testAccessPackElement();
+	void testTypeInPack();
+	void testTypeNames();
 };
 
 #endif  // TYPE_TRAITS_TEST_H_
-- 
GitLab