ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
dbgboxing.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 !DOXYGEN
10# include "alib/boxing/boxing.hpp"
11#endif // !DOXYGEN
12
13#if ALIB_DEBUG_BOXING
14
15#if !DOXYGEN
18# if ALIB_THREADS
20# endif
21# if ALIB_CAMP
24# endif
25# if ALIB_MONOMEM
28# else
29# include <unordered_map>
30# include <unordered_set>
31# endif
32#endif // !DOXYGEN
33
34#include <algorithm>
35
37
38namespace alib { namespace boxing { namespace detail {
39
40#if !DOXYGEN
41
42#if ALIB_MONOMEM
49#else
50 extern std::unordered_set<TypeFunctors::Key , TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownCustomFunctions;
51 std::unordered_set<TypeFunctors::Key , TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownCustomFunctions;
52 extern std::unordered_map<TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTables;
53 std::unordered_map<TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTables;
54 extern std::unordered_map<TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTablesArray;
55 std::unordered_map<TypeFunctors::Key, detail::VTable*, TypeFunctors::Hash, TypeFunctors::EqualTo> DbgKnownVTablesArray;
56#endif
57
58
59 IF_ALIB_THREADS( namespace { RecursiveLock dbgLock; } )
60
61 extern ALIB_API
62 void DbgLockMaps( bool doLock );
63 void DbgLockMaps( bool doLock )
64 {
65 #if !ALIB_THREADS
66 (void) doLock;
68 #else
69 ALIB_DBG(dbgLock.Dbg.Name= "DbgBoxing";)
70 if( doLock )
71 dbgLock.AcquireRecursive( ALIB_CALLER_PRUNED );
72 else
73 dbgLock.ReleaseRecursive( ALIB_CALLER_PRUNED );
74 #endif
75 }
76
77#endif
78
80{
81 vtable->DbgProduction= productionType;
82 DbgLockMaps(true);
83 if( !vtable->IsArray() )
84 {
85 #if ALIB_MONOMEM
87 DbgKnownVTables.InsertUnique( std::make_pair( &vtable->Type, vtable ) );
88 #else
89 if ( DbgKnownVTables.find( &vtable->Type ) != DbgKnownVTables.end() )
90 {
91 ALIB_ERROR( "BOXING", "Double instantiation of VTable of Type: \"",
92 DbgTypeDemangler( vtable->Type ).Get(), "\"" )
93 DbgLockMaps(false);
94 return;
95 }
96
97 DbgKnownVTables.insert(std::make_pair( &vtable->Type, vtable ) );
98 #endif
99 }
100 else
101 {
102 #if ALIB_MONOMEM
104 DbgKnownVTablesArray.InsertUnique(std::make_pair( &vtable->ElementType, vtable ) );
105 #else
106 if ( DbgKnownVTablesArray.find( &vtable->ElementType ) != DbgKnownVTablesArray.end() )
107 {
108 ALIB_ERROR( "BOXING", "Double instantiation of VTable of Type: \"",
109 DbgTypeDemangler( vtable->ElementType ).Get(), "[]\"" )
110 DbgLockMaps(false);
111 return;
112 }
113
114 DbgKnownVTablesArray.insert(std::make_pair( &vtable->ElementType, vtable ) );
115 #endif
116 }
117 DbgLockMaps(false);
118}
119
120} // namespace alib::boxing[::detail]
121
122
123#if ALIB_STRINGS
124
125// #############################################################################################
126// Type Name
127// #############################################################################################
129{
130 for( auto& search: RemovableNamespaces )
131 {
132 integer idx;
133 while( (idx= string.IndexOf(search, startIndex) ) >= 0 )
134 string.Delete( idx, search.Length() );
135 }
136 return string;
137}
138
139std::vector<alib::String> DbgBoxing::RemovableNamespaces
140{
141 A_CHAR( "alib::boxing::" ),
142 A_CHAR( "alib::" ),
143};
144
145void DbgBoxing::typeName( const detail::VTable* vtable, AString& result )
146{
147 auto startLength= result.Length();
148 if( !vtable->IsArray() )
149 result << vtable->Type;
150 else
151 result << vtable->ElementType << "[]";
152
153 // MSC adds "class "
154 if( result.StartsWith( A_CHAR("class ") ) )
155 result.DeleteStart( 6 );
156
157 removeNamespaces(result, startLength);
158}
159
160#endif // ALIB_STRINGS
161
162#if ALIB_CAMP
163
164// #############################################################################################
165// Type Info
166// #############################################################################################
167
169 const detail::VTable* vtable,
170 const String& indent,
171 bool srcIsPointer,
172 bool isValueTypeCustomized,
173 bool isPointerTypeCustomized,
174 bool fitsToPlaceholder,
175 bool copyConstructible,
176 bool triviallyDestructible,
177 bool isUnboxable )
178{
179 target <<indent << "Mapping: " << ( vtable->Mapping == detail::VTable::MappingType::Pointer
180 ? "Pointer"
182 ? "Value"
184 ? "Enum"
185 : "Array"
186 ) << NEW_LINE;
188 {
189 target << indent << "Mapped Type: "; typeName(vtable, target ); target << " (Enumeration)" << NEW_LINE;
190 target << indent << "Customized: Not customizable (always boxed as enum value type)" << NEW_LINE;
191 }
192 else
193 {
194 bool valueBoxing = vtable->Mapping == detail::VTable::MappingType::Value;
195 bool pointerBoxing= vtable->Mapping == detail::VTable::MappingType::Pointer;
196 bool arrayBoxing = vtable->IsArray();
197 bool srcIsValue = !srcIsPointer;
198
199 target << indent << "Mapped Type: "; typeName(vtable, target ); target << NEW_LINE;
200
201 target <<indent << "Customized T: " << isValueTypeCustomized << NEW_LINE;
202 target <<indent << "Customized T*: " << isPointerTypeCustomized << NEW_LINE;
203 target <<indent << "Is Unboxable: "
204 <<( isUnboxable
205 ? ( srcIsValue && valueBoxing && isValueTypeCustomized
206 ? "Yes (By customization)"
207
208 : srcIsValue && valueBoxing && !isValueTypeCustomized
209 ? "Yes (Value fits in placeholder and is copy constructible)"
210
211 : srcIsPointer && pointerBoxing && isPointerTypeCustomized
212 ? "Yes (By customization)"
213
214 : srcIsPointer && pointerBoxing && !isPointerTypeCustomized && (!copyConstructible || !triviallyDestructible)
215 ? "Yes (Value would not be copy-constructible or trivially destructible)"
216
217 : srcIsPointer && pointerBoxing && !isPointerTypeCustomized && !fitsToPlaceholder
218 ? "Yes (Value would not fit to placeholder)"
219
220 : srcIsValue && arrayBoxing && isValueTypeCustomized
221 ? "Yes (Custom unboxing from array type)"
222
223 : srcIsValue && arrayBoxing && isPointerTypeCustomized
224 ? "Yes (Unboxing from array type, customized with pointer type)"
225
226 : srcIsPointer && arrayBoxing && isPointerTypeCustomized
227 ? "Yes (Custom unboxing from array type)"
228
229 : srcIsPointer && arrayBoxing && isValueTypeCustomized
230 ? "Yes (Unboxing from array type, customized with value type)"
231
232 : "INTERNAL ERROR IN DBG METHDO: CASE NOT MATCHED (E1)"
233 )
234 : (
235 srcIsValue && isValueTypeCustomized
236 ? "Forbidden (By customization)"
237
238 : srcIsValue && pointerBoxing && isPointerTypeCustomized
239 ? "Not as value (Pointer type is customized)"
240
241 : srcIsValue && pointerBoxing && !isPointerTypeCustomized && (!copyConstructible || !triviallyDestructible)
242 ? "Not as value (Not copy-constructible or trivially destructible)"
243
244 : srcIsValue && pointerBoxing && !isPointerTypeCustomized && !fitsToPlaceholder
245 ? "Not as value (Does not fit to placeholder)"
246
247 : srcIsPointer && isPointerTypeCustomized
248 ? "Forbidden (By customization)"
249
250 : srcIsPointer && valueBoxing && isValueTypeCustomized
251 ? "Not as pointer (Value type is customized)"
252
253 : srcIsPointer && valueBoxing && !isValueTypeCustomized
254 ? "Not as pointer (Value fits in placeholder and is copy constructible and trivially destructible)"
255
256 : "INTERNAL ERROR IN DBG METHOd: CASE NOT MATCHED (E2)"
257 )
258 ) << NEW_LINE;
259 } // not enum
260
261 target << indent << "VTable Type: " << ( vtable->DbgProduction == detail::VTable::DbgFactoryType::Unregistered
262 ? "INTERNAL ERROR IN DBG METHOD: STATIC VTABLE NOT REGISTERED"
264 ? "Dynamic Singleton"
265 : "Static Singleton (Specialized T_VTableFactory)"
266 )
267 << NEW_LINE;
268
269 target << indent << "Usage Counter: " << vtable->DbgCntUsage << NEW_LINE;
270
271 ALIB_ASSERT_ERROR( target.IndexOf( A_CHAR("INTERNAL ERROR") ) < 0,
272 "BOXING", "Error occurred describing type" )
273
274 auto functions= GetSpecificFunctionTypes(vtable);
276 detail::DbgStringTable<uinteger> tmpStrings( la );
277 String256 headline; headline << '\n' << indent << "Associated Specialized Functions:";
278 String256 indent2; indent2 << indent << indent;
279 dumpFunctions( functions, target, headline, indent2, tmpStrings );
280}
281
282
283// #############################################################################################
284// Dump Type Lists (conversion for type lists)
285// #############################################################################################
286AString DbgBoxing::DumpFunctions( const std::vector<std::pair<const std::type_info*,uinteger>>& input,
287 const String& headline,
288 const String& indent )
289{
290 AString result;
292 detail::DbgStringTable<uinteger> tmpStrings( la );
293
294 // repeat twice to get auto-tabs adjusted
296 Formatter& formatter= *Formatter::Default;
297 formatter.Reset();
298 for( int theSakeOfAutoTabs= 0 ; theSakeOfAutoTabs < 2 ; ++theSakeOfAutoTabs )
299 {
300 result.Reset();
301 dumpFunctions( input, result, headline, indent, tmpStrings );
302 }
303
304 return result;
305}
306
307void DbgBoxing::dumpFunctions( const std::vector<std::pair<const std::type_info*,uinteger>>& input,
308 AString& output,
309 const String& headline,
310 const String& indent,
312{
313 String512 buffer;
314 tmpStrings.clear();
315 for( auto& type : input )
316 tmpStrings.Add( removeNamespaces(buffer.Reset() << *type.first, 0), type.second );
317
318 std::sort( tmpStrings.begin(), tmpStrings.end(),
319 [] (std::tuple<String, uinteger>& a,
320 std::tuple<String, uinteger>& b )
321 {
322 return std::get<0>(a).template CompareTo<CHK, lang::Case::Ignore>( std::get<0>(b) ) < 0;
323 }
324 );
325
326 if ( headline.IsNotEmpty() )
327 output << headline << NEW_LINE;
328
329 Formatter& formatter= *Formatter::Default;
330 BoxesMA& args= formatter.Reset();
331 args.Add( indent, "{} {!ATab5}{:>2})\n", nullptr, '(', nullptr );
332 for( auto& nameAndUse : tmpStrings )
333 {
334 args[2]= std::get<0>(nameAndUse);
335 args[4]= std::get<1>(nameAndUse) != (std::numeric_limits<uinteger>::max)()
336 ? Box( std::get<1>(nameAndUse) )
337 : Box( "No default implementation" );
338 formatter.FormatArgs( output, args );
339 }
340 output << NEW_LINE;
341}
342
343
344// #############################################################################################
345// Dump
346// #############################################################################################
347
348AString DbgBoxing::DumpVTables( bool staticVtables, bool includeFunctions )
349{
350 AString result;
351 LocalAllocator8K allocator;
352
353 // repeat twice to get auto-tabs adjusted
355 Formatter& formatter= *Formatter::Default;
356 formatter.Reset();
357
358 for( int theSakeOfAutoTabs= 0 ; theSakeOfAutoTabs < 2 ; ++theSakeOfAutoTabs )
359 {
360 result .Reset();
361 allocator .Reset();
362 detail::DbgStringTable<const detail::VTable*> vtableNames( allocator );
363 dumpVTables( result, vtableNames, staticVtables , includeFunctions );
364 }
365
366 return result;
367}
368
369
372 bool staticVtables,
373 bool includeFunctions )
374{
375 // dump vtables and their interfaces
376 result << ( staticVtables ? A_CHAR("Mapped types with static VTables")
377 : A_CHAR("Mapped types with dynamic VTables") );
378 if( includeFunctions )
379 result << A_CHAR(" and their associated specialized functions");
380
381 (result << ':' << NEW_LINE) .InsertChars('-', 77) << NEW_LINE;
382
383 // Get vtables and add names to string array
384 vtableNames.clear();
385 String1K temp;
386 detail::DbgLockMaps(true);
387 for( int i= 0 ; i < 2; ++i )
388 for( auto& it : ( i == 0 ? detail::DbgKnownVTables : detail::DbgKnownVTablesArray) )
389 {
390 if( (it.second->DbgProduction == (staticVtables ? detail::VTable::DbgFactoryType::Static
392 || it.second->DbgProduction == detail::VTable::DbgFactoryType::Unregistered )
393 {
394
395 temp.Reset();
396
397 temp << Format::Field( String64("(") << it.second->DbgCntUsage<< ") ", 6, lang::Alignment::Left );
398 typeName( it.second, temp );
399 if( it.second->DbgProduction == detail::VTable::DbgFactoryType::Unregistered )
400 temp << " ATTENTION: Unregistered customized VTable!!! This is an Error";
401
402 vtableNames.Add( temp, it.second );
403 }
404 }
405 detail::DbgLockMaps(false);
406
407 std::sort( vtableNames.begin(), vtableNames.end(),
410 {
411 // skip the prepended usage number
412 Substring lhs= std::get<0>(a); lhs.TrimStart().ConsumeToken(' '); lhs.TrimStart();
413 Substring rhs= std::get<0>(b); rhs.TrimStart().ConsumeToken(' '); rhs.TrimStart();
414 return lhs.CompareTo<CHK, lang::Case::Ignore>( rhs ) < 0;
415 }
416 );
417
419 detail::DbgStringTable<uinteger> tempStrings( la );
420 std::vector<std::pair<const std::type_info*,uinteger>> tempFunctions;
421 for( auto& vtable: vtableNames )
422 {
423 result << std::get<0>(vtable) << NEW_LINE;
424 if( includeFunctions )
425 {
426 getFunctionTypes(std::get<1>(vtable)->Functions, tempFunctions );
427 dumpFunctions( tempFunctions, result, NULL_STRING, A_CHAR(" "), tempStrings );
428 }
429 }
430}
431
433{
434 AString result;
435
436 // Get vtables and add names to string array
438
439 // repeat twice to get auto-tabs adjusted
442 for( int theSakeOfAutoTabs= 0 ; theSakeOfAutoTabs < 2 ; ++theSakeOfAutoTabs )
443 {
444 result .Reset();
445 la.Reset();
447 detail::DbgStringTable<uinteger> tempStrings( la);
448
449 dumpVTables( result, vtableNames, true , true ); result.NewLine();
450 dumpVTables( result, vtableNames, false, true ); result.NewLine();
451
452 auto knownFunctions= GetKnownFunctionTypes();
453 (result << "Known Function Declarators And Usage Of Default Implementation:"
454 << NEW_LINE) .InsertChars('-', 77) << NEW_LINE;
455 dumpFunctions( knownFunctions, result, NULL_STRING, A_CHAR(" "), tempStrings );
456
457 #if ALIB_DEBUG_CONTAINERS
458 (result << NEW_LINE << "Metrics Of Custom Function Implementation HashMap: "
459 << NEW_LINE) .InsertChars('-', 77) << NEW_LINE;
460 DumpCustomFunctionHashMapMetrics( result, false );
461 result << NEW_LINE;
462 #endif
463 }
464
465 return result;
466}
467
468
469#endif // ALIB_CAMP
470
471}} // namespace [alib::boxing]
472
474
475#endif // ALIB_DEBUG_BOXING
TBoxes & Add()
Definition boxes.inl:74
static ALIB_API threads::RecursiveLock DefaultLock
static ALIB_API SPFormatter Default
Formatter & FormatArgs(AString &target)
virtual BoxesMA & Reset()
ALIB_API void Reset(Snapshot snapshot=Snapshot())
TAString & DeleteStart(integer regionLength)
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:896
constexpr bool IsNotEmpty() const
Definition string.hpp:389
constexpr integer Length() const
Definition string.hpp:326
bool StartsWith(const TString &needle) const
Definition string.hpp:820
#define IF_ALIB_THREADS(...)
Definition alib.hpp:352
#define A_CHAR(STR)
#define ALIB_API
Definition alib.hpp:639
#define ALIB_ERROR(...)
Definition alib.hpp:1267
#define ALIB_LOCK_RECURSIVE_WITH(lock)
Definition owner.hpp:457
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:1271
#define ALIB_DBG(...)
Definition alib.hpp:390
#define ALIB_CALLER_PRUNED
Definition alib.hpp:1170
void DbgRegisterVTable(detail::VTable *vtable, detail::VTable::DbgFactoryType productionType)
Definition dbgboxing.cpp:79
@ Left
Chooses left alignment.
ALIB_API MonoAllocator GLOBAL_ALLOCATOR
ALIB_API RecursiveLock GLOBAL_ALLOCATOR_LOCK
Definition alib.cpp:69
LocalString< 64 > String64
Type alias name for TLocalString<character,64>.
containers::HashSet< TAllocator, T, THash, TEqual, THashCaching, TRecycling > HashSet
Type alias in namespace alib. See type definition alib::containers::HashSet.
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.hpp:580
threads::RecursiveLock RecursiveLock
Type alias in namespace alib.
constexpr String NULL_STRING
A nulled string of the default character type.
Definition string.hpp:2549
boxing::Box Box
Type alias in namespace alib.
void DbgAssertSingleThreaded()
Definition alib.cpp:267
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:273
containers::HashMap< TAllocator, TKey, TMapped, THash, TEqual, THashCaching, TRecycling > HashMap
Type alias in namespace alib.
static ALIB_API void dumpVTables(AString &target, detail::DbgStringTable< const detail::VTable * > &vtableNames, bool staticVtables, bool includeFunctions)
static ALIB_API AString & removeNamespaces(AString &string, integer startIndex)
static ALIB_API std::vector< std::pair< const std::type_info *, uinteger > > GetKnownFunctionTypes()
Definition vtable.cpp:201
static std::vector< std::pair< const std::type_info *, uinteger > > GetSpecificFunctionTypes(const detail::VTable *vtable)
static ALIB_API alib::AString DumpFunctions(const std::vector< std::pair< const std::type_info *, uinteger > > &input, const String &headline=EMPTY_STRING, const String &indent=EMPTY_STRING)
static ALIB_API void DumpCustomFunctionHashMapMetrics(AString &target, bool detailedBucketList)
Definition vtable.cpp:261
static ALIB_API void typeInfo(AString &target, const detail::VTable *vtable, const String &indent, bool srcIsPointer, bool isValueTypeCustomized, bool isPointerTypeCustomized, bool fitsToPlaceholder, bool copyConstructible, bool triviallyDestructible, bool isUnboxable)
static ALIB_API void dumpFunctions(const std::vector< std::pair< const std::type_info *, uinteger > > &input, AString &output, const String &headline, const String &indent, detail::DbgStringTable< uinteger > &tmpStrings)
static ALIB_API void getFunctionTypes(const detail::FunctionTable &input, std::vector< std::pair< const std::type_info *, uinteger > > &output)
Definition vtable.cpp:237
static ALIB_API void typeName(const detail::VTable *vtable, AString &result)
static ALIB_API AString DumpAll()
static ALIB_API std::vector< String > RemovableNamespaces
See method removeNamespaces. Pre-initialized with "alib::".
static ALIB_API AString DumpVTables(bool staticVtables, bool includeFunctions=false)
String & Add(const String &src, TArgs &&... args)
Definition dbgboxing.hpp:74
std::tuple< String, TAssociatedTypes... > ElementType
Shortcut to the std::tuple-type that instantiations of this template class store.
Definition dbgboxing.hpp:50
DbgFactoryType DbgProduction
Debug information.
Definition vtable.inl:226
const std::type_info & Type
Definition vtable.inl:193
@ Static
A static VTable is in place.
@ Dynamic
The VTable is created dynamically from templated type VTableTT.
const MappingType Mapping
Definition vtable.inl:202
@ Enum
Enum type boxing.
Definition vtable.inl:188
@ Pointer
Pointer boxing.
Definition vtable.inl:187
const std::type_info & ElementType
Definition vtable.inl:197