PLCnext API Documentation  22.9.0.33
TypeName.hxx
1 //
3 // Copyright PHOENIX CONTACT Electronics GmbH
4 //
6 #pragma once
7 #include "Arp/System/Core/Arp.h"
8 #include "Arp/System/Core/Exception.hpp"
9 #include "Arp/System/Core/RuntimeTypeInfo.hpp"
10 #include <typeinfo>
11 
12 namespace Arp
13 {
14 
16 
17 namespace __Internal
18 {
19 
21 struct TypeNameHelper
22 {
23  static String GetNamespace(const String& typeName, bool isCommon)
24  {
25  size_t pos = isCommon ? typeName.FindLastOf('.') : typeName.FindLastOf(':');
26  if (pos == String::NPos)
27  {
28  return String::Empty;
29  }
30  // else
31  return isCommon ? typeName.Substr(0, pos) : typeName.Substr(0, pos - 1);
32  }
33 
34  static String GetClassName(const String& typeName, bool isCommon)
35  {
36  size_t pos = isCommon ? typeName.FindLastOf('.') : typeName.FindLastOf(':');
37  if (pos == String::NPos)
38  {
39  return typeName;
40  }
41  // else
42  return typeName.Substr(pos + 1);
43  }
44 };
45 } // end of namespace Internal
46 
48 
54 template<class T = void>
55 class TypeName
56 {
57  friend class TypeName<void>;
58 
59 public: // construction/destruction
61  TypeName(void);
64  TypeName(const TypeName& arg) = default;
67  TypeName(TypeName&& arg)noexcept = default;
71  TypeName& operator=(const TypeName& arg) = default;
73  ~TypeName(void) = default;
74 
75 public: // operations
78  String GetCommonName(void)const;
82  String GetSafeName(void)const;
85  String GetNamespace(void)const;
88  String GetClassName(void)const;
89 
90 public: // operators
93  operator const String& (void)const;
96  operator const char*(void)const;
100  bool operator==(const TypeName& other);
104  bool operator!=(const TypeName& other);
105 
106 private: // construction
107  TypeName(const char* typeName, bool isCommon = false);
108 
109 private: // methods
110  void AssignTypeName(const char* typeName, bool isCommon);
111 
112 public: // fields
115 
116 private: // fields
117  bool isCommon = false;
118 };
119 
121 // inline methods of class TypeName<T>
122 
123 template<class T>
125 {
126  this->AssignTypeName(typeid(T).name(), false);
127 }
128 
129 template<class T>
130 inline TypeName<T>::TypeName(const char* typeName, bool isCommonArg)
131 {
132  this->AssignTypeName(typeName, isCommonArg);
133 }
134 
135 template<class T>
137 {
138  String result(this->Value);
139  result.ReplaceAll("::", ".");
140  return result;
141 }
142 
143 template<class T>
145 {
146  String result(this->Value);
147 
148  if (this->isCommon)
149  {
150  result.ReplaceAll(".", "_");
151  }
152  else
153  {
154  result.ReplaceAll("::", "_");
155  }
156  return result;
157 }
158 
159 template<class T>
161 {
162  return __Internal::TypeNameHelper::GetNamespace(this->Value, this->isCommon);
163 }
164 
165 template<class T>
167 {
168  return __Internal::TypeNameHelper::GetClassName(this->Value, this->isCommon);
169 }
170 
171 template<class T>
172 inline void TypeName<T>::AssignTypeName(const char* typeName, bool isCommonArg)
173 {
174  this->isCommon = isCommonArg;
175 
176  if (this->isCommon)
177  {
178  this->Value = typeName; // name was demangled yet
179  }
180  else
181  {
182  this->Value = RuntimeTypeInfo::DemangleSymbol(typeName);
183  if (this->Value.IsEmpty())
184  {
185  throw Exception("Demangling of type name '{0}' failed.", typeid(T).name());
186  }
187 
188 
189  // strip any kind of type 'class', 'struct' or 'enum' from begin of string
190  if (Value.Find("class ") == 0)
191  {
192  Value = Value.Substr(6);
193  }
194  else if (Value.Find("struct ") == 0)
195  {
196  Value = Value.Substr(7);
197  }
198  else if (Value.Find("enum ") == 0)
199  {
200  Value = Value.Substr(5);
201  }
202  }
203 }
204 
205 template<class T>
206 inline TypeName<T>::operator const String& ()const
207 {
208  return this->Value;
209 }
210 
211 template<class T>
212 inline TypeName<T>::operator const char*()const
213 {
214  return this->Value.CStr();
215 }
216 
217 template<class T>
218 inline bool TypeName<T>::operator==(const TypeName& other)
219 {
220  return this->Value == other.Value;
221 }
222 
223 template<class T>
224 inline bool TypeName<T>::operator!=(const TypeName& other)
225 {
226  return !(*this == other);
227 }
228 
233 template<class T>
234 inline std::ostream& operator<<(std::ostream& os, const TypeName<T>& typeName)
235 {
236  os << typeName.Value;
237  return os;
238 }
239 
241 // implementation of template specialization TypeName<void>
242 
244 template<>
245 class TypeName<void>
246 {
247 private: // construction/destruction
248  TypeName(void) = delete;
249  TypeName(const TypeName& arg) = delete;
250  TypeName& operator=(const TypeName& arg) = delete;
251  ~TypeName(void) = delete;
252 
253 public: // static factory operations
258  template <class T2>
259  static TypeName<T2> GetFrom(T2& instance)
260  {
261  return GetFrom(&instance);
262  }
263 
268  template <class T2>
269  static TypeName<T2> GetFrom(T2* pInstance)
270  {
271  const char* pResult = typeid(*pInstance).name();
272  pInstance = nullptr;
273  return TypeName<T2>(pResult);
274  }
275 
280  static String GetNamespace(const String& typeName, bool isCommon)
281  {
282  return __Internal::TypeNameHelper::GetNamespace(typeName, isCommon);
283  }
284 
289  static String GetClassName(const String& typeName, bool isCommon)
290  {
291  return __Internal::TypeNameHelper::GetClassName(typeName, isCommon);
292  }
293 };
294 
295 } // 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:289
static TypeName< T2 > GetFrom(T2 *pInstance)
Creates the TypeName from the as argument passed variable pointer.
Definition: TypeName.hxx:269
static String GetNamespace(const String &typeName, bool isCommon)
Extracts the namespace of the given typename.
Definition: TypeName.hxx:280
static TypeName< T2 > GetFrom(T2 &instance)
Creates the TypeName from the as argument passed variable.
Definition: TypeName.hxx:259
This (meta programming) class provides the C++ typename of the as template argument passed type.
Definition: TypeName.hxx:56
String GetNamespace(void) const
Gets the namespace of the as template parameter given type.
Definition: TypeName.hxx:160
TypeName(TypeName &&arg) noexcept=default
The default move constructor.
String Value
The resulting typename.
Definition: TypeName.hxx:114
String GetSafeName(void) const
Gets a safe name of the as template parameter given type.
Definition: TypeName.hxx:144
bool operator!=(const TypeName &other)
Determines if this instance is not equal to other .
Definition: TypeName.hxx:224
String GetCommonName(void) const
Gets the common name of the as template parameter given type according to the CLS.
Definition: TypeName.hxx:136
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:124
String GetClassName(void) const
Gets the classname of the as template parameter given type.
Definition: TypeName.hxx:166
bool operator==(const TypeName &other)
Determines if this instance is equal to other .
Definition: TypeName.hxx:218
std::ostream & operator<<(std::ostream &os, const BasicString< CharType, Alloc > &right)
Streams the right string to the outstream os .
Definition: BasicString.hxx:1708
size_type FindLastOf(const SelfType &chars, size_type offset=NPos) const
Finds the last occurence of any character in chars .
Definition: BasicString.hxx:1240
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
static const SelfType Empty
An emtpy static string instance.
Definition: BasicString.hxx:214
SelfType & ReplaceAll(const SelfType &pattern, const SelfType &replacement)
Replaces a given pattern by a replacement string.
Definition: BasicString.hxx:813
Arp::BasicString< char8 > String
The Arp String class.
Definition: TypeSystem.h:27
Root namespace for the PLCnext API