PLCnext API Documentation 23.0.2.9
TypeName.hxx
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Core/Exception.hpp"
9#include "Arp/System/Core/RuntimeTypeInfo.hpp"
10#include <typeinfo>
11
12namespace Arp
13{
14
16
17namespace __Internal
18{
19
21struct TypeNameHelper
22{
23 static size_t FindNamespaceEndPosition(const String& typeName, bool isCommon)
24 {
25 char separator = isCommon ? '.' : ':';
26
27 size_t lastPos = typeName.FindFirstOf('<'); // template class?
28 if (lastPos == String::NPos)
29 {
30 return typeName.FindLastOf(separator);
31 }
32 // else
33 return typeName.FindLastOf(separator, lastPos);
34 }
35
36 static String GetNamespace(const String& typeName, bool isCommon)
37 {
38 size_t pos = FindNamespaceEndPosition(typeName, isCommon);
39 if (pos == String::NPos)
40 {
41 return String::Empty;
42 }
43 // else
44 return isCommon ? typeName.Substr(0, pos) : typeName.Substr(0, pos - 1);
45 }
46
47 static String GetClassName(const String& typeName, bool isCommon)
48 {
49 size_t pos = FindNamespaceEndPosition(typeName, isCommon);
50 if (pos == String::NPos)
51 {
52 return typeName; // no namespace present
53 }
54 // else
55 return typeName.Substr(pos + 1);
56 }
57};
58} // end of namespace Internal
65template<class T = void>
67{
68 friend class TypeName<void>;
69
70public: // construction/destruction
72 TypeName(void);
75 TypeName(const TypeName& arg) = default;
78 TypeName(TypeName&& arg)noexcept = default;
82 TypeName& operator=(const TypeName& arg) = default;
84 ~TypeName(void) = default;
85
86public: // operations
89 String GetCommonName(void)const;
93 String GetSafeName(void)const;
96 String GetNamespace(void)const;
99 String GetClassName(void)const;
100
101public: // operators
104 operator const String& (void)const;
107 operator const char*(void)const;
111 bool operator==(const TypeName& other);
115 bool operator!=(const TypeName& other);
116
117private: // construction
118 TypeName(const char* typeName, bool isCommon = false);
119
120private: // methods
121 void AssignTypeName(const char* typeName, bool isCommon);
122
123public: // fields
126
127private: // fields
128 bool isCommon = false;
129};
130
132// inline methods of class TypeName<T>
133
134template<class T>
136{
137 this->AssignTypeName(typeid(T).name(), false);
138}
139
140template<class T>
141inline TypeName<T>::TypeName(const char* typeName, bool isCommonArg)
142{
143 this->AssignTypeName(typeName, isCommonArg);
144}
145
146template<class T>
148{
149 String result(this->Value);
150 result.ReplaceAll("::", ".");
151 return result;
152}
153
154template<class T>
156{
157 String result(this->Value);
158
159 if (this->isCommon)
160 {
161 result.ReplaceAll(".", "_");
162 }
163 else
164 {
165 result.ReplaceAll("::", "_");
166 }
167 result.ReplaceAll("<", "$");
168 result.ReplaceAll(">", "$");
169
170 return result;
171}
172
173template<class T>
175{
176 return __Internal::TypeNameHelper::GetNamespace(this->Value, this->isCommon);
177}
178
179template<class T>
181{
182 return __Internal::TypeNameHelper::GetClassName(this->Value, this->isCommon);
183}
184
185template<class T>
186inline void TypeName<T>::AssignTypeName(const char* typeName, bool isCommonArg)
187{
188 this->isCommon = isCommonArg;
189
190 if (this->isCommon)
191 {
192 this->Value = typeName; // name was demangled yet
193 }
194 else
195 {
196 this->Value = RuntimeTypeInfo::DemangleSymbol(typeName);
197 if (this->Value.IsEmpty())
198 {
199 throw Exception("Demangling of type name '{0}' failed.", typeid(T).name());
200 }
201
202
203 // remove any kind of type 'class', 'struct' or 'enum' from begin of string
204 Value.ReplaceAll("class ", String::Empty);
205 Value.ReplaceAll("struct ", String::Empty);
206 Value.ReplaceAll("enum ", String::Empty);
207 }
208}
209
210template<class T>
211inline TypeName<T>::operator const String& ()const
212{
213 return this->Value;
214}
215
216template<class T>
217inline TypeName<T>::operator const char*()const
218{
219 return this->Value.CStr();
220}
221
222template<class T>
223inline bool TypeName<T>::operator==(const TypeName& other)
224{
225 return this->Value == other.Value;
226}
227
228template<class T>
229inline bool TypeName<T>::operator!=(const TypeName& other)
230{
231 return !(*this == other);
232}
233
238template<class T>
239inline std::ostream& operator<<(std::ostream& os, const TypeName<T>& typeName)
240{
241 os << typeName.Value;
242 return os;
243}
244
246// implementation of template specialization TypeName<void>
247
249template<>
250class TypeName<void>
251{
252private: // construction/destruction
253 TypeName(void) = delete;
254 TypeName(const TypeName& arg) = delete;
255 TypeName& operator=(const TypeName& arg) = delete;
256 ~TypeName(void) = delete;
257
258public: // static factory operations
263 template <class T2>
264 static TypeName<T2> GetFrom(T2& instance)
265 {
266 return GetFrom(&instance);
267 }
268
273 template <class T2>
274 static TypeName<T2> GetFrom(T2* pInstance)
275 {
276 const char* pResult = typeid(*pInstance).name();
277 pInstance = nullptr;
278 return TypeName<T2>(pResult);
279 }
280
285 static String GetNamespace(const String& typeName, bool isCommon)
286 {
287 return __Internal::TypeNameHelper::GetNamespace(typeName, isCommon);
288 }
289
294 static String GetClassName(const String& typeName, bool isCommon)
295 {
296 return __Internal::TypeNameHelper::GetClassName(typeName, isCommon);
297 }
298};
299
300} // end of namespace Arp
static String DemangleSymbol(const char *symbolName)
Demangles a symbol
static String GetClassName(const String &typeName, bool isCommon)
Extracts the classname of the given typename.
Definition: TypeName.hxx:294
static TypeName< T2 > GetFrom(T2 *pInstance)
Creates the TypeName from the as argument passed variable pointer.
Definition: TypeName.hxx:274
static String GetNamespace(const String &typeName, bool isCommon)
Extracts the namespace of the given typename.
Definition: TypeName.hxx:285
static TypeName< T2 > GetFrom(T2 &instance)
Creates the TypeName from the as argument passed variable.
Definition: TypeName.hxx:264
This (meta programming) class provides the C++ typename of the as template argument passed type.
Definition: TypeName.hxx:67
String GetNamespace(void) const
Gets the namespace of the as template parameter given type.
Definition: TypeName.hxx:174
TypeName(TypeName &&arg) noexcept=default
The default move constructor.
String Value
The resulting typename.
Definition: TypeName.hxx:125
String GetSafeName(void) const
Gets a safe name of the as template parameter given type.
Definition: TypeName.hxx:155
bool operator!=(const TypeName &other)
Determines if this instance is not equal to other .
Definition: TypeName.hxx:229
String GetCommonName(void) const
Gets the common name of the as template parameter given type according to the CLS.
Definition: TypeName.hxx:147
TypeName & operator=(const TypeName &arg)=default
The default assignment operator.
~TypeName(void)=default
The default destructor..
TypeName(const TypeName &arg)=default
The default copy constructor.
TypeName(void)
Constructs a CommonTypeName instance and determines the typename of the of T.
Definition: TypeName.hxx:135
String GetClassName(void) const
Gets the classname of the as template parameter given type.
Definition: TypeName.hxx:180
bool operator==(const TypeName &other)
Determines if this instance is equal to other .
Definition: TypeName.hxx:223
SelfType Substr(size_type offset=0, size_type count=NPos) const
Gets a substring of this string.
Definition: BasicString.hxx:1531
static const size_type NPos
This position value is returned when find operations do not match, or is used as default value for an...
Definition: BasicString.hxx:210
std::ostream & operator<<(std::ostream &os, const BasicString< CharType, Alloc > &right)
Streams the right string to the outstream os .
Definition: BasicString.hxx:1708
SelfType & ReplaceAll(const SelfType &pattern, const SelfType &replacement)
Replaces a given pattern by a replacement string.
Definition: BasicString.hxx:813
static const SelfType Empty
An emtpy static string instance.
Definition: BasicString.hxx:214
Arp::BasicString< char8 > String
The Arp String class.
Definition: TypeSystem.h:27
Root namespace for the PLCnext API