ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
vtable.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !defined(ALIB_DOX)
10#ifndef HPP_ALIB_BOXING_BOXING
11# include "alib/boxing/boxing.hpp"
12#endif
13
14#if !defined(HPP_ALIB_COMPATIBILITY_STD_TYPEINFO)
16#endif
17
18#if ALIB_DEBUG
19# if !defined (HPP_ALIB_BOXING_DBGBOXING)
21# endif
22#endif
23
24#endif // !defined(ALIB_DOX)
25
26#if ALIB_MONOMEM
27# if !defined(HPP_ALIB_MONOMEM_HASHMAP)
29# endif
30# if !defined(HPP_ALIB_MONOMEM_HASHSET)
32# endif
33#else
34# if !defined(_GLIBCXX_UNORDERED_MAP) && !defined(_UNORDERED_MAP_)
35# include <unordered_map>
36# endif
37# if !defined(_GLIBCXX_UNORDERED_SET) && !defined(_UNORDERED_SET_)
38# include <unordered_set>
39# endif
40#endif
41
42
43
44namespace alib { namespace boxing { namespace detail {
45
46#if !defined(ALIB_DOX)
47
48#if ALIB_MONOMEM
49 extern HashSet <TypeFunctors::Key, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownCustomFunctions;
50 extern HashMap <TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTables;
51 extern HashMap <TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTablesArray;
52#else
53 extern std::unordered_set<TypeFunctors::Key, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownCustomFunctions;
54 extern std::unordered_map<TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTables;
55 extern std::unordered_map<TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTablesArray;
56#endif
57
58extern ALIB_API void DbgLockMaps( bool doLock );
59
60
61// #################################################################################################
62// Custom function hash map implementation
63// #################################################################################################
64namespace
65{
66 struct CustomFunctionKey
67 {
68 const FunctionTable* Parent;
69 const std::type_info& Type;
70
71 CustomFunctionKey( const FunctionTable* parent, const std::type_info& type )
72 : Parent(parent)
73 , Type (type )
74 {}
75 };
76
77 struct CustomFunctionMapped
78 {
79 void* Implementation;
80ALIB_DBG(uinteger DbgCntInvocations; )
81
82 CustomFunctionMapped( void* implementation )
83 : Implementation (implementation)
84ALIB_DBG(,DbgCntInvocations (0 ) )
85 {}
86 };
87
88
89 struct CustomFunctionHash
90 {
91 std::size_t operator()(const CustomFunctionKey& key) const
92 {
93 size_t result= reinterpret_cast<size_t>(key.Parent)
94 ^ key.Type.hash_code();
95 result^= (result << 21 );
96 result^= (result >> 11);
97 return result;
98 }
99
100 };
101
102 struct CustomFunctionEqualTo
103 {
104 bool operator()(const CustomFunctionKey& lhs, const CustomFunctionKey& rhs) const
105 {
106 return lhs.Parent == rhs.Parent
107 && lhs.Type == rhs.Type;
108 }
109 };
110
111 #if ALIB_MONOMEM
112 HashMap < CustomFunctionKey, CustomFunctionMapped,
113 CustomFunctionHash,
114 CustomFunctionEqualTo > customFunctionMap( &monomem::GlobalAllocator );
115 #else
116 std::unordered_map< CustomFunctionKey, CustomFunctionMapped,
117 CustomFunctionHash,
118 CustomFunctionEqualTo > customFunctionMap;
119 #endif
120
121}// anonymous namespace
122
123#endif
124
125// #################################################################################################
126// struct Functions
127// #################################################################################################
129
130
131
132void* FunctionTable::getCustom( const std::type_info& rtti ALIB_DBG(, bool isInvocation) ) const
133{
134#if ALIB_MONOMEM
135 auto it= customFunctionMap.Find( CustomFunctionKey(this, rtti) );
136#else
137 auto it= customFunctionMap.find( CustomFunctionKey(this, rtti) );
138#endif
139 if ( it != customFunctionMap.end() )
140 {
141 ALIB_DBG( if( isInvocation )
142 ++it->second.DbgCntInvocations; )
143 return it->second.Implementation;
144 }
145 return nullptr;
146}
147
148void FunctionTable::setCustom( const std::type_info& rtti, void* impl )
149{
150 #if ALIB_DEBUG_BOXING
151 detail::DbgLockMaps(true);
152 #if ALIB_MONOMEM
153 DbgKnownCustomFunctions.InsertIfNotExistent( &rtti );
154 #else
155 DbgKnownCustomFunctions.emplace( &rtti );
156 #endif
157 detail::DbgLockMaps(false);
158 #endif
159
160 // search existing (replace)
161 #if ALIB_MONOMEM
162 customFunctionMap.InsertOrAssign( CustomFunctionKey(this, rtti), CustomFunctionMapped(impl) );
163 #else
164 if( customFunctionMap.size() == 0 )
165 customFunctionMap.reserve( 50 );
166 customFunctionMap.insert_or_assign( CustomFunctionKey(this, rtti), CustomFunctionMapped(impl) );
167 #endif
168
169}
170
171} // namespace alib::boxing[::detail]
172
173using namespace detail;
174
175// #################################################################################################
176// DBGBoxing Function Lists Implementation
177// (located here due to anonymous function table)
178// #################################################################################################
179#if ALIB_DEBUG_BOXING
180std::vector<detail::VTable*> DbgBoxing::GetKnownVTables()
181{
182 DbgLockMaps(true);
183
184 std::vector<detail::VTable*> result;
185 #if ALIB_MONOMEM
186 result.reserve( static_cast<size_t>(
187 DbgKnownVTables .Size()
188 + DbgKnownVTablesArray.Size() ) );
189 #else
190 result.reserve( DbgKnownVTables .size()
191 + DbgKnownVTablesArray.size() );
192 #endif
193
194 for( int type= 0 ; type < 2 ; ++type )
195 {
196 auto& map= type == 0 ? DbgKnownVTables
197 : DbgKnownVTablesArray;
198 for( auto it= map.begin() ; it!= map.end() ; ++it )
199 result.emplace_back( it->second );
200 }
201
202 DbgLockMaps(false);
203 return result;
204}
205
206std::vector<std::pair<const std::type_info*,uinteger>> DbgBoxing::GetKnownFunctionTypes()
207{
208 std::vector<std::pair<const std::type_info*,uinteger>> result;
209 result.emplace_back( &typeid( FHashcode ), detail::DEFAULT_FUNCTIONS.fHashcode ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFHashcode : (std::numeric_limits<uinteger>::max)() );
211 result.emplace_back( &typeid( FClone ), detail::DEFAULT_FUNCTIONS.fClone ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFClone : (std::numeric_limits<uinteger>::max)() ); )
212 result.emplace_back( &typeid( FIsNotNull ), detail::DEFAULT_FUNCTIONS.fIsNotNull ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsNotNull : (std::numeric_limits<uinteger>::max)() );
213 result.emplace_back( &typeid( FEquals ), detail::DEFAULT_FUNCTIONS.fEquals ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFEquals : (std::numeric_limits<uinteger>::max)() );
214 result.emplace_back( &typeid( FIsLess ), detail::DEFAULT_FUNCTIONS.fIsLess ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsLess : (std::numeric_limits<uinteger>::max)() );
215 result.emplace_back( &typeid( FIsTrue ), detail::DEFAULT_FUNCTIONS.fIsTrue ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsTrue : (std::numeric_limits<uinteger>::max)() );
217 result.emplace_back( &typeid( FAppend<character>), detail::DEFAULT_FUNCTIONS.fAppend ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFAppend : (std::numeric_limits<uinteger>::max)() ); )
218
219 detail::DbgLockMaps(true);
220 {
221 for (auto* typeIt : detail::DbgKnownCustomFunctions )
222 {
223 // search corresponding default implementation.
224 auto usage= (std::numeric_limits<uinteger>::max)();
225
226 #if ALIB_MONOMEM
227 auto implIt= customFunctionMap.Find( CustomFunctionKey(&detail::DEFAULT_FUNCTIONS, *typeIt) );
228 #else
229 auto implIt= customFunctionMap.find( CustomFunctionKey(&detail::DEFAULT_FUNCTIONS, *typeIt) );
230 #endif
231 if( implIt != customFunctionMap.end() )
232 usage= implIt->second.DbgCntInvocations;
233
234 result.emplace_back( typeIt, usage );
235 }
236 }
237 detail::DbgLockMaps(false);
238
239 return result;
240}
241
243 std::vector<std::pair<const std::type_info*,uinteger>>& output )
244{
245 output.clear();
246 if(functionTable.fHashcode ) output.emplace_back( &typeid( FHashcode ), functionTable.DbgCntInvocationsFHashcode );
248 if(functionTable.fClone ) output.emplace_back( &typeid( FClone ), functionTable.DbgCntInvocationsFClone ); )
249 if(functionTable.fIsNotNull) output.emplace_back( &typeid( FIsNotNull ), functionTable.DbgCntInvocationsFIsNotNull );
250 if(functionTable.fEquals ) output.emplace_back( &typeid( FEquals ), functionTable.DbgCntInvocationsFEquals );
251 if(functionTable.fIsLess ) output.emplace_back( &typeid( FIsLess ), functionTable.DbgCntInvocationsFIsLess );
252 if(functionTable.fIsTrue ) output.emplace_back( &typeid( FIsTrue ), functionTable.DbgCntInvocationsFIsTrue );
254 if(functionTable.fAppend ) output.emplace_back( &typeid( FAppend<character>), functionTable.DbgCntInvocationsFAppend ); )
255
256 // add custom function types
257 {
258 for( auto funcIt= customFunctionMap.begin() ; funcIt != customFunctionMap.end() ; ++funcIt )
259 if( funcIt->first.Parent == &functionTable )
260 output.emplace_back( &funcIt->first.Type , funcIt->second.DbgCntInvocations );
261 }
262}
263
264
265#if ALIB_MONOMEM && ALIB_DEBUG_MONOMEM
266void DbgBoxing::DumpCustomFunctionHashMapMetrics( AString& target, bool detailedBucketList )
267{
268 target << monomem::DbgDumpDistribution( customFunctionMap, detailedBucketList );
269}
270#endif
271
272
273#endif // ALIB_DEBUG_BOXING
274
275
276}} // namespace [alib::boxing]
277
278
279
280// #################################################################################################
281// Static VTables for fundamentals
282// #################################################################################################
283
284ALIB_BOXING_VTABLE_DEFINE( void* , vt_voidP )
285ALIB_BOXING_VTABLE_DEFINE( Boxes*, vt_boxes )
286ALIB_BOXING_VTABLE_DEFINE_ARRAYTYPE( Box , vt_boxarray )
287
288DOX_MARKER([DOX_ALIB_BOXING_OPTIMIZE_DEFINE_1])
289ALIB_BOXING_VTABLE_DEFINE( bool, vt_bool )
290DOX_MARKER([DOX_ALIB_BOXING_OPTIMIZE_DEFINE_1])
291
292
293#if !ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS
294
295 ALIB_BOXING_VTABLE_DEFINE( integer , vt_integer )
296 ALIB_BOXING_VTABLE_DEFINE( uinteger , vt_uinteger)
297
298#else
299 ALIB_BOXING_VTABLE_DEFINE( int8_t , vt_int8_t)
300 ALIB_BOXING_VTABLE_DEFINE( uint8_t , vt_uint8_t)
301 ALIB_BOXING_VTABLE_DEFINE( int16_t , vt_int16_t)
302 ALIB_BOXING_VTABLE_DEFINE( uint16_t , vt_uint16_t)
303 ALIB_BOXING_VTABLE_DEFINE( int32_t , vt_int32_t)
304 ALIB_BOXING_VTABLE_DEFINE( uint32_t , vt_uint32_t)
305 ALIB_BOXING_VTABLE_DEFINE( intGap_t , vt_intGap_t)
306 ALIB_BOXING_VTABLE_DEFINE( uintGap_t , vt_uintGap_t)
307
308 #if ALIB_SIZEOF_INTEGER == 8
309 ALIB_BOXING_VTABLE_DEFINE( int64_t , vt_int64_t)
310 ALIB_BOXING_VTABLE_DEFINE( uint64_t , vt_uint64_t)
311 #endif
312
313#endif
314
315 ALIB_BOXING_VTABLE_DEFINE( double, vt_double )
316#if ALIB_SIZEOF_LONGDOUBLE_REPORTED <= 2 * ALIB_SIZEOF_INTEGER
317 ALIB_BOXING_VTABLE_DEFINE( long double, vt_long_double )
318#endif
319#if ALIB_FEAT_BOXING_BIJECTIVE_FLOATS
320 ALIB_BOXING_VTABLE_DEFINE( float , vt_float )
321#endif
322
323#if !ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS
324 ALIB_BOXING_VTABLE_DEFINE( wchar , vt_wchar )
325#else
326 ALIB_BOXING_VTABLE_DEFINE( char , vt_char )
327 ALIB_BOXING_VTABLE_DEFINE( wchar_t , vt_wchar_t )
328 ALIB_BOXING_VTABLE_DEFINE( char16_t , vt_char16_t )
329 ALIB_BOXING_VTABLE_DEFINE( char32_t , vt_char32_t )
330#endif
331
332DOX_MARKER([DOX_ALIB_BOXING_OPTIMIZE_DEFINE_2])
333ALIB_BOXING_VTABLE_DEFINE_ARRAYTYPE( char, vt_arr_char )
334DOX_MARKER([DOX_ALIB_BOXING_OPTIMIZE_DEFINE_2])
335ALIB_BOXING_VTABLE_DEFINE_ARRAYTYPE( wchar_t , vt_arr_wchar_t )
336ALIB_BOXING_VTABLE_DEFINE_ARRAYTYPE( char16_t , vt_arr_char16_t)
337ALIB_BOXING_VTABLE_DEFINE_ARRAYTYPE( char32_t , vt_arr_char32_t)
338
339// #################################################################################################
340// Static VTables for standard types
341// #################################################################################################
342ALIB_BOXING_VTABLE_DEFINE( std::type_info* , vt_std_type_info )
343
344// #################################################################################################
345// Static VTables for low-level ALib types
346// #################################################################################################
347// CodeMarker_CommonEnums
361ALIB_BOXING_VTABLE_DEFINE( alib::lang::Reach , vt_alib_Recursive )
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
Definition vtable.inl:490
#define ALIB_IF_STRINGS(...)
Definition alib.hpp:287
#define ALIB_API
Definition alib.hpp:538
#define ALIB_IF_MONOMEM(...)
Definition alib.hpp:271
#define ALIB_BOXING_VTABLE_DEFINE_ARRAYTYPE(TMapped, Identifier)
Definition vtable.inl:500
#define ALIB_DBG(...)
Definition alib.hpp:457
FunctionTable DEFAULT_FUNCTIONS
Definition vtable.cpp:128
const alib::boxing::Box & Type
AString DbgDumpDistribution(const THashtable &hashtable, bool detailedBucketList)
MonoAllocator GlobalAllocator(8 *1024)
Definition alib.cpp:57
monomem::HashMap< TKey, TMapped, THash, TEqual, THashCaching, TRecycling > HashMap
Type alias in namespace alib. See type definition alib::monomem::HashMap.
Definition hashmap.hpp:104
static ALIB_API std::vector< std::pair< const std::type_info *, uinteger > > GetKnownFunctionTypes()
Definition vtable.cpp:206
static ALIB_API void DumpCustomFunctionHashMapMetrics(AString &target, bool detailedBucketList)
Definition vtable.cpp:266
static ALIB_API void getFunctionTypes(const detail::FunctionTable &input, std::vector< std::pair< const std::type_info *, uinteger > > &output)
Definition vtable.cpp:242
static ALIB_API std::vector< detail::VTable * > GetKnownVTables()
Definition vtable.cpp:180
uinteger DbgCntInvocationsFHashcode
Debug-compilation counter for the number of invocations.
Definition vtable.inl:45
uinteger DbgCntInvocationsFIsNotNull
Debug-compilation counter for the number of invocations.
Definition vtable.inl:46
FIsLess::Signature fIsLess
Entry for built-in function FIsLess .
Definition vtable.inl:36
ALIB_API void * getCustom(const std::type_info &rtti, bool isInvocation) const
Definition vtable.cpp:132
uinteger DbgCntInvocationsFIsLess
Debug-compilation counter for the number of invocations.
Definition vtable.inl:48
uinteger DbgCntInvocationsFClone
Debug-compilation counter for the number of invocations.
Definition vtable.inl:51
uinteger DbgCntInvocationsFAppend
Debug-compilation counter for the number of invocations.
Definition vtable.inl:54
uinteger DbgCntInvocationsFIsTrue
Debug-compilation counter for the number of invocations.
Definition vtable.inl:49
ALIB_API void setCustom(const std::type_info &rtti, void *implementation)
Definition vtable.cpp:148
uinteger DbgCntInvocationsFEquals
Debug-compilation counter for the number of invocations.
Definition vtable.inl:47
FClone::Signature fClone
Entry for built-in function FClone .
Definition vtable.inl:39
FHashcode::Signature fHashcode
Entry for built-in function FHashcode .
Definition vtable.inl:33
FIsTrue::Signature fIsTrue
Entry for built-in function FIsTrue .
Definition vtable.inl:37
FAppend< character >::Signature fAppend
Entry for built-in function FAppend .
Definition vtable.inl:42
FEquals::Signature fEquals
Entry for built-in function FEquals .
Definition vtable.inl:35
FIsNotNull::Signature fIsNotNull
Entry for built-in function FIsNotNull .
Definition vtable.inl:34