ALib C++ Library
Library Version: 2510 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;
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{
75 #if ALIB_SINGLE_THREADED
76 (void) doLock;
78 #else
79 # include "ALib.Lang.CIFunctions.H"
80 ALIB_DBG(dbgLock.Dbg.Name= "DbgBoxing";)
81 if( doLock )
82 dbgLock.AcquireRecursive( ALIB_CALLER_PRUNED );
83 else
84 dbgLock.ReleaseRecursive( ALIB_CALLER_PRUNED );
85 # include "ALib.Lang.CIMethods.H"
86 #endif
87}
88} namespace detail {
89#endif // ALIB_DEBUG
90
91#endif // !DOXYGEN
92
93// #################################################################################################
94// struct Functions
95// #################################################################################################
97
98#if (ALIB_MONOMEM && ALIB_CONTAINERS && ALIB_DEBUG)
100{
101 #if ALIB_MONOMEM && ALIB_DEBUG_BOXING
102 debug::DbgKnownCustomFunctions.Reset();
103 debug::DbgKnownVTables .Reset();
104 debug::DbgKnownVTablesArray .Reset();
105 #endif
106 customFunctionMap .Reset();
107}
108#endif
109
110
111void* FunctionTable::getCustom( const std::type_info& rtti ALIB_DBG(, bool isInvocation) ) const
112{
113#if ALIB_MONOMEM && ALIB_CONTAINERS
114 auto it= customFunctionMap.Find( CustomFunctionKey(this, rtti) );
115#else
116 auto it= customFunctionMap.find( CustomFunctionKey(this, rtti) );
117#endif
118 if ( it != customFunctionMap.end() )
119 {
120 ALIB_DBG( if( isInvocation )
121 ++it->second.DbgCntInvocations; )
122 return it->second.Implementation;
123 }
124 return nullptr;
125}
126
127void FunctionTable::setCustom( const std::type_info& rtti, void* impl )
128{
129 #if ALIB_DEBUG_BOXING
130 debug::DbgLockMaps(true);
131 #if ALIB_MONOMEM
132 debug::DbgKnownCustomFunctions.InsertIfNotExistent( &rtti );
133 #else
134 debug::DbgKnownCustomFunctions.emplace( &rtti );
135 #endif
136 debug::DbgLockMaps(false);
137 #endif
138
139 // search existing (replace)
140 #if ALIB_MONOMEM && ALIB_CONTAINERS
141 customFunctionMap.InsertOrAssign( CustomFunctionKey(this, rtti), CustomFunctionMapped(impl) );
142 #else
143 if( customFunctionMap.size() == 0 )
144 customFunctionMap.reserve( 50 );
145 customFunctionMap.insert_or_assign( CustomFunctionKey(this, rtti), CustomFunctionMapped(impl) );
146 #endif
147
148}
149
150} // namespace alib::boxing[::detail]
151
152using namespace detail;
153
154// #################################################################################################
155// Debug Function Lists Implementation
156// (located here due to anonymous function table)
157// #################################################################################################
158#if ALIB_DEBUG_BOXING
159std::vector<detail::VTable*> debug::GetKnownVTables()
160{
161 DbgLockMaps(true);
162
163 std::vector<detail::VTable*> result;
164 #if ALIB_MONOMEM
165 result.reserve( size_t(
166 DbgKnownVTables .Size()
167 + DbgKnownVTablesArray.Size() ) );
168 #else
169 result.reserve( DbgKnownVTables .size()
170 + DbgKnownVTablesArray.size() );
171 #endif
172
173 for( int type= 0 ; type < 2 ; ++type )
174 {
175 auto& map= type == 0 ? DbgKnownVTables
176 : DbgKnownVTablesArray;
177 for( auto it= map.begin() ; it!= map.end() ; ++it )
178 result.emplace_back( it->second );
179 }
180
181 DbgLockMaps(false);
182 return result;
183}
184
185std::vector<std::pair<const std::type_info*,uinteger>> debug::GetKnownFunctionTypes()
186{
187 std::vector<std::pair<const std::type_info*,uinteger>> result;
188 result.emplace_back( &typeid( FHashcode ), detail::DEFAULT_FUNCTIONS.fHashcode ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFHashcode : (std::numeric_limits<uinteger>::max)() );
190 result.emplace_back( &typeid( FClone ), detail::DEFAULT_FUNCTIONS.fClone ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFClone : (std::numeric_limits<uinteger>::max)() ); )
191 result.emplace_back( &typeid( FIsNotNull ), detail::DEFAULT_FUNCTIONS.fIsNotNull ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsNotNull : (std::numeric_limits<uinteger>::max)() );
192 result.emplace_back( &typeid( FEquals ), detail::DEFAULT_FUNCTIONS.fEquals ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFEquals : (std::numeric_limits<uinteger>::max)() );
193 result.emplace_back( &typeid( FIsLess ), detail::DEFAULT_FUNCTIONS.fIsLess ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsLess : (std::numeric_limits<uinteger>::max)() );
194 result.emplace_back( &typeid( FIsTrue ), detail::DEFAULT_FUNCTIONS.fIsTrue ? detail::DEFAULT_FUNCTIONS.DbgCntInvocationsFIsTrue : (std::numeric_limits<uinteger>::max)() );
195
196 debug::DbgLockMaps(true);
197 {
198 for (auto* typeIt : debug::DbgKnownCustomFunctions )
199 {
200 // search corresponding default implementation.
201 auto usage= (std::numeric_limits<uinteger>::max)();
202
203 #if ALIB_MONOMEM
204 auto implIt= customFunctionMap.Find( CustomFunctionKey(&detail::DEFAULT_FUNCTIONS, *typeIt) );
205 #else
206 auto implIt= customFunctionMap.find( CustomFunctionKey(&detail::DEFAULT_FUNCTIONS, *typeIt) );
207 #endif
208 if( implIt != customFunctionMap.end() )
209 usage= implIt->second.DbgCntInvocations;
210
211 result.emplace_back( typeIt, usage );
212 }
213 }
214 debug::DbgLockMaps(false);
215
216 return result;
217}
218
220 std::vector<std::pair<const std::type_info*,uinteger>>& output )
221{
222 output.clear();
223 if(functionTable.fHashcode ) output.emplace_back( &typeid( FHashcode ), functionTable.DbgCntInvocationsFHashcode );
225 if(functionTable.fClone ) output.emplace_back( &typeid( FClone ), functionTable.DbgCntInvocationsFClone ); )
226 if(functionTable.fIsNotNull) output.emplace_back( &typeid( FIsNotNull ), functionTable.DbgCntInvocationsFIsNotNull );
227 if(functionTable.fEquals ) output.emplace_back( &typeid( FEquals ), functionTable.DbgCntInvocationsFEquals );
228 if(functionTable.fIsLess ) output.emplace_back( &typeid( FIsLess ), functionTable.DbgCntInvocationsFIsLess );
229 if(functionTable.fIsTrue ) output.emplace_back( &typeid( FIsTrue ), functionTable.DbgCntInvocationsFIsTrue );
230
231 // add custom function types
232 {
233 for( auto funcIt= customFunctionMap.begin() ; funcIt != customFunctionMap.end() ; ++funcIt )
234 if( funcIt->first.Parent == &functionTable )
235 output.emplace_back( &funcIt->first.Type , funcIt->second.DbgCntInvocations );
236 }
237}
238
239#endif // ALIB_DEBUG_BOXING
240
241}} // namespace [alib::boxing]
242
243
#define IF_ALIB_THREADS(...)
Definition alib.inl:401
#define ALIB_DBG(...)
Definition alib.inl:836
#define IF_ALIB_MONOMEM(...)
Definition alib.inl:361
#define ALIB_CALLER_PRUNED
Definition alib.inl:1007
void SingleThreaded()
Definition assert.cpp:141
ALIB_DLL std::vector< std::pair< const std::type_info *, uinteger > > GetKnownFunctionTypes()
Definition vtable.cpp:185
ALIB_DLL std::vector< detail::VTable * > GetKnownVTables()
Definition vtable.cpp:159
ALIB_DLL void getFunctionTypes(const detail::FunctionTable &input, std::vector< std::pair< const std::type_info *, uinteger > > &output)
Definition vtable.cpp:219
This namespace implements internals of namespace alib::boxing.
Definition vtable.cpp:43
FunctionTable DEFAULT_FUNCTIONS
The default box-functions set.
Definition vtable.cpp:96
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:127
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:111
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:99