ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
vtable.cpp
1//##################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6//##################################################################################################
7#include "alib_precompile.hpp"
8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14//========================================= Global Fragment ========================================
16#if ALIB_MONOMEM && ALIB_CONTAINERS
18#endif
19#if ALIB_DEBUG && (!ALIB_MONOMEM || !ALIB_CONTAINERS )
20# include <unordered_map>
21# include <unordered_set>
22#endif
23#if ALIB_DEBUG_BOXING
24# include <vector>
25#endif
26
27//============================================== Module ============================================
28#if ALIB_C20_MODULES
29 module ALib.Boxing;
30# if ALIB_DEBUG && ALIB_MONOMEM && ALIB_CONTAINERS
31 import ALib.Monomem;
32 import ALib.Containers.HashTable;
33# endif
34
35#else
36# include "ALib.Boxing.H"
37# if ALIB_DEBUG && ALIB_MONOMEM && ALIB_CONTAINERS
39# include "ALib.Monomem.H"
40# endif
41#endif
42//========================================== Implementation ========================================
43namespace alib { namespace boxing { namespace detail {
44
45//##################################################################################################
46// Custom function hash map implementation
47//##################################################################################################
48#if !DOXYGEN
49#if ALIB_MONOMEM && ALIB_CONTAINERS
51 CustomFunctionKey, CustomFunctionMapped,
52 CustomFunctionHash,
53 CustomFunctionEqualTo > customFunctionMap(monomem::GLOBAL_ALLOCATOR);
54#else
55std::unordered_map< CustomFunctionKey, CustomFunctionMapped,
56 CustomFunctionHash,
57 CustomFunctionEqualTo > customFunctionMap;
58#endif
59
60#if ALIB_DEBUG
61} namespace debug {
62#if ALIB_MONOMEM && ALIB_CONTAINERS
66#else
67 std::unordered_set< lang::TypeFunctors::Key , lang::TypeFunctors::Hash, lang::TypeFunctors::EqualTo> DbgKnownCustomFunctions;
68 std::unordered_map< lang::TypeFunctors::Key, detail::VTable*, lang::TypeFunctors::Hash, lang::TypeFunctors::EqualTo> DbgKnownVTables;
69 std::unordered_map< lang::TypeFunctors::Key, detail::VTable*, lang::TypeFunctors::Hash, lang::TypeFunctors::EqualTo> DbgKnownVTablesArray;
70#endif
71
72IF_ALIB_THREADS( namespace { RecursiveLock dbgLock; } )
73void DbgLockMaps( bool doLock ) {
74 #if ALIB_SINGLE_THREADED
75 (void) doLock;
77 #else
78 # include "ALib.Lang.CIFunctions.H"
79 ALIB_DBG(dbgLock.Dbg.Name= "DbgBoxing";)
80 if( doLock )
81 dbgLock.AcquireRecursive( ALIB_CALLER_PRUNED );
82 else
83 dbgLock.ReleaseRecursive( ALIB_CALLER_PRUNED );
84 # include "ALib.Lang.CIMethods.H"
85 #endif
86}
87} namespace detail {
88#endif // ALIB_DEBUG
89
90#endif // !DOXYGEN
91
92//##################################################################################################
93// struct Functions
94//##################################################################################################
96
97#if (ALIB_MONOMEM && ALIB_CONTAINERS && ALIB_DEBUG)
99 #if ALIB_MONOMEM && ALIB_DEBUG_BOXING
100 debug::DbgKnownCustomFunctions.Reset();
101 debug::DbgKnownVTables .Reset();
102 debug::DbgKnownVTablesArray .Reset();
103 #endif
104 customFunctionMap .Reset();
105}
106#endif
107
108
109void* FunctionTable::getCustom( const std::type_info& rtti ALIB_DBG(, bool isInvocation) ) const {
110#if ALIB_MONOMEM && ALIB_CONTAINERS
111 auto it= customFunctionMap.Find( CustomFunctionKey(this, rtti) );
112#else
113 auto it= customFunctionMap.find( CustomFunctionKey(this, rtti) );
114#endif
115 if ( it != customFunctionMap.end() ) {
116 ALIB_DBG( if( isInvocation )
117 ++it->second.DbgCntInvocations; )
118 return it->second.Implementation;
119 }
120 return nullptr;
121}
122
123void FunctionTable::setCustom( const std::type_info& rtti, void* impl ) {
124 #if ALIB_DEBUG_BOXING
125 debug::DbgLockMaps(true);
126 #if ALIB_MONOMEM
127 debug::DbgKnownCustomFunctions.InsertIfNotExistent( &rtti );
128 #else
129 debug::DbgKnownCustomFunctions.emplace( &rtti );
130 #endif
131 debug::DbgLockMaps(false);
132 #endif
133
134 // search existing (replace)
135 #if ALIB_MONOMEM && ALIB_CONTAINERS
136 customFunctionMap.InsertOrAssign( CustomFunctionKey(this, rtti), CustomFunctionMapped(impl) );
137 #else
138 if( customFunctionMap.size() == 0 )
139 customFunctionMap.reserve( 50 );
140 customFunctionMap.insert_or_assign( CustomFunctionKey(this, rtti), CustomFunctionMapped(impl) );
141 #endif
142
143}
144
145} // namespace alib::boxing[::detail]
146
147using namespace detail;
148
149//##################################################################################################
150// Debug Function Lists Implementation
151// (located here due to anonymous function table)
152//##################################################################################################
153#if ALIB_DEBUG_BOXING
154std::vector<detail::VTable*> debug::GetKnownVTables()
155{
156 DbgLockMaps(true);
157
158 std::vector<detail::VTable*> result;
159 #if ALIB_MONOMEM
160 result.reserve( size_t(
161 DbgKnownVTables .Size()
162 + DbgKnownVTablesArray.Size() ) );
163 #else
164 result.reserve( DbgKnownVTables .size()
165 + DbgKnownVTablesArray.size() );
166 #endif
167
168 for( int type= 0 ; type < 2 ; ++type )
169 {
170 auto& map= type == 0 ? DbgKnownVTables
171 : DbgKnownVTablesArray;
172 for( auto it= map.begin() ; it!= map.end() ; ++it )
173 result.emplace_back( it->second );
174 }
175
176 DbgLockMaps(false);
177 return result;
178}
179
180std::vector<std::pair<const std::type_info*,uinteger>> debug::GetKnownFunctionTypes()
181{
182 std::vector<std::pair<const std::type_info*,uinteger>> result;
183 result.emplace_back( &typeid( FHashcode ), detail::DEFAULT_FUNCTIONS.fHashcode ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFHashcode : (std::numeric_limits<uinteger>::max)() );
185 result.emplace_back( &typeid( FClone ), detail::DEFAULT_FUNCTIONS.fClone ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFClone : (std::numeric_limits<uinteger>::max)() ); )
186 result.emplace_back( &typeid( FIsNotNull ), detail::DEFAULT_FUNCTIONS.fIsNotNull ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsNotNull : (std::numeric_limits<uinteger>::max)() );
187 result.emplace_back( &typeid( FEquals ), detail::DEFAULT_FUNCTIONS.fEquals ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFEquals : (std::numeric_limits<uinteger>::max)() );
188 result.emplace_back( &typeid( FIsLess ), detail::DEFAULT_FUNCTIONS.fIsLess ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsLess : (std::numeric_limits<uinteger>::max)() );
189 result.emplace_back( &typeid( FIsTrue ), detail::DEFAULT_FUNCTIONS.fIsTrue ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsTrue : (std::numeric_limits<uinteger>::max)() );
190
191 debug::DbgLockMaps(true);
192 {
193 for (auto* typeIt : debug::DbgKnownCustomFunctions )
194 {
195 // search corresponding default implementation.
196 auto usage= (std::numeric_limits<uinteger>::max)();
197
198 #if ALIB_MONOMEM
199 auto implIt= customFunctionMap.Find( CustomFunctionKey(&detail::DEFAULT_FUNCTIONS, *typeIt) );
200 #else
201 auto implIt= customFunctionMap.find( CustomFunctionKey(&detail::DEFAULT_FUNCTIONS, *typeIt) );
202 #endif
203 if( implIt != customFunctionMap.end() )
204 usage= implIt->second.DbgCntInvocations;
205
206 result.emplace_back( typeIt, usage );
207 }
208 }
209 debug::DbgLockMaps(false);
210
211 return result;
212}
213
215 std::vector<std::pair<const std::type_info*,uinteger>>& output )
216{
217 output.clear();
218 if(functionTable.fHashcode ) output.emplace_back( &typeid( FHashcode ), functionTable.DbgCntInvocationsFHashcode );
220 if(functionTable.fClone ) output.emplace_back( &typeid( FClone ), functionTable.DbgCntInvocationsFClone ); )
221 if(functionTable.fIsNotNull) output.emplace_back( &typeid( FIsNotNull ), functionTable.DbgCntInvocationsFIsNotNull );
222 if(functionTable.fEquals ) output.emplace_back( &typeid( FEquals ), functionTable.DbgCntInvocationsFEquals );
223 if(functionTable.fIsLess ) output.emplace_back( &typeid( FIsLess ), functionTable.DbgCntInvocationsFIsLess );
224 if(functionTable.fIsTrue ) output.emplace_back( &typeid( FIsTrue ), functionTable.DbgCntInvocationsFIsTrue );
225
226 // add custom function types
227 {
228 for( auto funcIt= customFunctionMap.begin() ; funcIt != customFunctionMap.end() ; ++funcIt )
229 if( funcIt->first.Parent == &functionTable )
230 output.emplace_back( &funcIt->first.Type , funcIt->second.DbgCntInvocations );
231 }
232}
233
234#endif // ALIB_DEBUG_BOXING
235
236}} // namespace [alib::boxing]
#define IF_ALIB_THREADS(...)
Definition alib.inl:401
#define ALIB_DBG(...)
Definition alib.inl:853
#define IF_ALIB_MONOMEM(...)
Definition alib.inl:361
#define ALIB_CALLER_PRUNED
Definition alib.inl:1024
void SingleThreaded()
Definition assert.cpp:141
ALIB_DLL std::vector< std::pair< const std::type_info *, uinteger > > GetKnownFunctionTypes()
Definition vtable.cpp:180
ALIB_DLL std::vector< detail::VTable * > GetKnownVTables()
Definition vtable.cpp:154
ALIB_DLL void getFunctionTypes(const detail::FunctionTable &input, std::vector< std::pair< const std::type_info *, uinteger > > &output)
Definition vtable.cpp:214
This namespace implements internals of namespace alib::boxing.
Definition vtable.cpp:43
FunctionTable DEFAULT_FUNCTIONS
The default box-functions set.
Definition vtable.cpp:95
ALIB_DLL TMonoAllocator< lang::HeapAllocator > GLOBAL_ALLOCATOR
containers::HashSet< TAllocator, T, THash, TEqual, THashCaching, TRecycling > HashSet
Type alias in namespace alib. See type definition alib::containers::HashSet.
containers::HashMap< TAllocator, TKey, TMapped, THash, TEqual, THashCaching, TRecycling > HashMap
Type alias in namespace alib.
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
threads::RecursiveLock RecursiveLock
Type alias in namespace alib.
ALIB_DLL void setCustom(const std::type_info &rtti, void *implementation)
Definition vtable.cpp:123
uinteger DbgCntInvocationsFHashcode
Debug-compilation counter for the number of invocations.
Definition vtable.inl:37
uinteger DbgCntInvocationsFIsTrue
Debug-compilation counter for the number of invocations.
Definition vtable.inl:41
FIsNotNull::Signature fIsNotNull
Entry for built-in function FIsNotNull.
Definition vtable.inl:25
uinteger DbgCntInvocationsFIsLess
Debug-compilation counter for the number of invocations.
Definition vtable.inl:40
FIsTrue::Signature fIsTrue
Entry for built-in function FIsTrue.
Definition vtable.inl:28
FIsLess::Signature fIsLess
Entry for built-in function FIsLess.
Definition vtable.inl:27
ALIB_DLL void * getCustom(const std::type_info &rtti, bool isInvocation) const
Definition vtable.cpp:109
FEquals::Signature fEquals
Entry for built-in function FEquals.
Definition vtable.inl:26
uinteger DbgCntInvocationsFIsNotNull
Debug-compilation counter for the number of invocations.
Definition vtable.inl:38
uinteger DbgCntInvocationsFEquals
Debug-compilation counter for the number of invocations.
Definition vtable.inl:39
FClone::Signature fClone
Entry for built-in function FClone.
Definition vtable.inl:30
uinteger DbgCntInvocationsFClone
Debug-compilation counter for the number of invocations.
Definition vtable.inl:43
FHashcode::Signature fHashcode
Entry for built-in function FHashcode.
Definition vtable.inl:24
static ALIB_DLL void Shutdown()
Needs to be called only in debug versions to shut down internal hashtables cleanly.
Definition vtable.cpp:98