Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.7.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TypesUtils.hpp
1#pragma once
2#include <Core/RaCore.hpp>
3#include <Core/Utils/StringUtils.hpp>
4
5#ifndef _WIN32
6# include <cxxabi.h>
7# include <memory>
8#else
9# include <typeinfo>
10#endif
11
12#include <string>
13#include <typeindex>
14
15namespace Ra {
16namespace Core {
17namespace Utils {
18
20template <typename T>
21std::string demangleType() noexcept;
22
24template <typename T>
25std::string demangleType( const T& ) noexcept;
26
28RA_CORE_API std::string demangleType( const std::type_index& typeName ) noexcept;
29
31template <typename T>
32auto simplifiedDemangledType() noexcept -> std::string;
33
35template <typename T>
36auto simplifiedDemangledType( const T& ) noexcept -> std::string;
37
42RA_CORE_API auto simplifiedDemangledType( const std::type_index& typeName ) noexcept -> std::string;
43
44// Check if a type is a container with access to its element type and number
45// adapted from https://stackoverflow.com/questions/13830158/check-if-a-variable-type-is-iterable
46namespace detail {
47
48using std::begin;
49using std::end;
50
51template <typename T>
52auto is_container_impl( int )
53 -> decltype( begin( std::declval<T&>() ) !=
54 end( std::declval<T&>() ), // begin/end and operator !=
55 void(), // Handle evil operator ,
56 std::declval<T&>().empty(),
57 std::declval<T&>().size(),
58 ++std::declval<decltype( begin( std::declval<T&>() ) )&>(), // operator ++
59 void( *begin( std::declval<T&>() ) ), // operator*
60 std::true_type {} );
61
62template <typename T>
63std::false_type is_container_impl( ... );
64
65} // namespace detail
66
67template <typename T>
68using is_container = decltype( detail::is_container_impl<T>( 0 ) );
69
70// -----------------------------------------------------------------
71// ---------------------- inline methods ---------------------------
72
73namespace TypeInternal {
74RA_CORE_API auto makeTypeReadable( const std::string& ) -> std::string;
75}
76
77template <typename T>
78auto simplifiedDemangledType() noexcept -> std::string {
79 static auto demangled_name = []() {
80 std::string demangledType =
81 TypeInternal::makeTypeReadable( Ra::Core::Utils::demangleType<T>() );
82 return demangledType;
83 }();
84 return demangled_name;
85}
86
87template <typename T>
88auto simplifiedDemangledType( const T& ) noexcept -> std::string {
89 return simplifiedDemangledType<T>();
90}
91
92inline auto simplifiedDemangledType( const std::type_index& typeName ) noexcept -> std::string {
93 return TypeInternal::makeTypeReadable( Ra::Core::Utils::demangleType( typeName ) );
94}
95
96// TypeList taken and adapted from
97// https://github.com/AcademySoftwareFoundation/openvdb/blob/master/openvdb/openvdb/TypeList.h
98// Only took small part of TypeList utilities
99
100// forward declarations
101template <typename... Ts>
102struct TypeList;
103
104namespace TypeListInternal {
105
110template <typename ListT, typename... Ts>
112
117template <typename... Ts, typename... OtherTs>
118struct TSAppendImpl<TypeList<Ts...>, OtherTs...> {
119 using type = TypeList<Ts..., OtherTs...>;
120};
121
126template <typename... Ts, typename... OtherTs>
127struct TSAppendImpl<TypeList<Ts...>, TypeList<OtherTs...>> {
128 using type = TypeList<Ts..., OtherTs...>;
129};
130
131} // namespace TypeListInternal
132
133template <typename... Ts>
134struct TypeList {
136 using Self = TypeList;
138 static constexpr size_t Size = sizeof...( Ts );
139
155 template <typename... TypesToAppend>
156 using Append = typename TypeListInternal::TSAppendImpl<Self, TypesToAppend...>::type;
157};
158
159#ifdef _WIN32
160// On windows (since MSVC 2019), typeid( T ).name() (and then typeIndex.name() returns the demangled
161// name
162inline std::string demangleType( const std::type_index& typeIndex ) noexcept {
163 std::string retval = typeIndex.name();
164 removeAllInString( retval, "class " );
165 removeAllInString( retval, "struct " );
166 removeAllInString( retval, "__cdecl" );
167 replaceAllInString( retval, "& __ptr64", "&" );
168 replaceAllInString( retval, ",", ", " );
169 replaceAllInString( retval, " >", ">" );
170 replaceAllInString( retval, "__int64", "long" );
171 replaceAllInString( retval, "const &", "const&" );
172 return retval;
173}
174#else
175// On Linux/macos, use the C++ ABI demangler
176inline std::string demangleType( const std::type_index& typeIndex ) noexcept {
177 int error = 0;
178 std::string retval;
179 char* name = abi::__cxa_demangle( typeIndex.name(), 0, 0, &error );
180 if ( error == 0 ) { retval = name; }
181 else {
182 // error : -1 --> memory allocation failed
183 // error : -2 --> not a valid mangled name
184 // error : other --> __cxa_demangle
185 retval = std::string( "Type demangler error : " ) + std::to_string( error );
186 }
187 std::free( name );
188 removeAllInString( retval, "__1::" ); // or "::__1" ?
189 replaceAllInString( retval, " >", ">" );
190 return retval;
191}
192#endif
193template <typename T>
194std::string demangleType() noexcept {
195 // once per one type
196 static auto demangled_name = demangleType( std::type_index( typeid( T ) ) );
197 return demangled_name;
198}
199
200// calling with instances
201template <typename T>
202std::string demangleType( const T& ) noexcept {
203 return demangleType<T>();
204}
205
206} // namespace Utils
207} // namespace Core
208} // namespace Ra
T begin(T... args)
T declval(T... args)
T end(T... args)
T free(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4
STL namespace.
Append any number of types to a TypeList.
T to_string(T... args)