ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
boxing_format_debug.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 ======================================
17#if ALIB_DEBUG_BOXING
18# include <vector>
19# include <algorithm>
20#endif
21// =========================================== Module ==========================================
22#if ALIB_C20_MODULES
23 module ALib.Format;
24# if ALIB_DEBUG_BOXING
25# include "ALib.Lang.H"
26# include "ALib.Monomem.H"
27# if ALIB_DEBUG_CONTAINERS
29# endif
30# endif
31#else
32# if ALIB_DEBUG_BOXING
33# include "ALib.Lang.H"
34# include "ALib.Monomem.H"
35# if ALIB_DEBUG_CONTAINERS
37# endif
38# include "ALib.Format.H"
39# endif
40#endif
41
42// ====================================== Implementation =======================================
43#if ALIB_DEBUG_BOXING
45namespace alib::boxing::debug {
46
47void typeInfo( AString& target,
48 const detail::VTable* vtable,
49 const String& indent,
50 bool srcIsPointer,
51 bool srcIsStringType,
52 bool srcIsUnboxableStringType,
53 bool isValueTypeCustomized,
54 bool isPointerTypeCustomized,
55 bool fitsToPlaceholder,
56 bool copyConstructible,
57 bool triviallyDestructible,
58 bool isUnboxable )
59{
60 target <<indent << "Mapping: " << ( vtable->Mapping == detail::VTable::MappingType::Pointer
61 ? "Pointer"
63 ? "Value"
65 ? "Enum"
66 : "Array"
67 ) << NEW_LINE;
69 {
70 target << indent << "Mapped Type: "; typeName(vtable, target ); target << " (Enumeration)" << NEW_LINE;
71 target << indent << "Customized: Not customizable (always boxed as enum value type)" << NEW_LINE;
72 }
73 else
74 {
75 bool valueBoxing = vtable->Mapping == detail::VTable::MappingType::Value;
76 bool pointerBoxing= vtable->Mapping == detail::VTable::MappingType::Pointer;
77 bool arrayBoxing = vtable->IsArray();
78 bool srcIsValue = !srcIsPointer;
79
80 target << indent << "Mapped Type: "; typeName(vtable, target ); target << NEW_LINE;
81
82 target <<indent << "Customized T: " << isValueTypeCustomized << NEW_LINE;
83 target <<indent << "Customized T*: " << isPointerTypeCustomized << NEW_LINE;
84 target <<indent << "Is Unboxable: "
85 <<( isUnboxable
86 ? ( srcIsValue && valueBoxing && isValueTypeCustomized
87 ? "Yes (By customization)"
88
89 : srcIsValue && valueBoxing && !isValueTypeCustomized
90 ? "Yes (Value fits in placeholder and is copy-constructible)"
91
92 : srcIsPointer && pointerBoxing && isPointerTypeCustomized
93 ? "Yes (By customization)"
94
95 : srcIsPointer && pointerBoxing && !isPointerTypeCustomized && (!copyConstructible || !triviallyDestructible)
96 ? "Yes (Value would not be copy-constructible or trivially destructible)"
97
98 : srcIsPointer && pointerBoxing && !isPointerTypeCustomized && !fitsToPlaceholder
99 ? "Yes (Value would not fit to placeholder)"
100
101 : srcIsValue && arrayBoxing && isValueTypeCustomized
102 ? "Yes (Custom unboxing from array type)"
103
104 : srcIsValue && arrayBoxing && isPointerTypeCustomized
105 ? "Yes (Unboxing from array type, customized with pointer type)"
106
107 : srcIsPointer && arrayBoxing && isPointerTypeCustomized
108 ? "Yes (Custom unboxing from array type)"
109
110 : srcIsPointer && arrayBoxing && isValueTypeCustomized
111 ? "Yes (Unboxing from array type, customized with value type)"
112
113 : srcIsUnboxableStringType
114 ? "Yes (Unboxing from character array type)"
115
116 : "INTERNAL ERROR IN DBG METHDO: CASE NOT MATCHED (E1)"
117 )
118 : (
119 srcIsValue && isValueTypeCustomized
120 ? "Forbidden (By customization)"
121
122 : srcIsValue && pointerBoxing && isPointerTypeCustomized
123 ? "Not as value (Pointer type is customized)"
124
125 : srcIsValue && pointerBoxing && !isPointerTypeCustomized && (!copyConstructible || !triviallyDestructible)
126 ? "Not as value (Not copy-constructible or trivially destructible)"
127
128 : srcIsValue && pointerBoxing && !isPointerTypeCustomized && !fitsToPlaceholder
129 ? "Not as value (Does not fit to placeholder)"
130
131 : srcIsPointer && isPointerTypeCustomized
132 ? "Forbidden (By customization)"
133
134 : srcIsPointer && valueBoxing && isValueTypeCustomized
135 ? "Not as pointer (Value type is customized)"
136
137 : srcIsPointer && valueBoxing && !isValueTypeCustomized
138 ? "Not as pointer (Value fits in placeholder and is copy-constructible and trivially destructible)"
139
140 : arrayBoxing
141 ? "Arrays cannot be unboxed"
142
143 : srcIsStringType
144 ? "No (String type is not marked for implicit construction from character array type)"
145
146 : "INTERNAL ERROR IN DBG METHOd: CASE NOT MATCHED (E2)"
147 )
148 ) << NEW_LINE;
149 } // not enum
150
151 target << indent << "VTable Type: " << ( vtable->DbgProduction == detail::VTable::DbgFactoryType::Unregistered
152 ? "STATIC VTABLE NOT REGISTERED"
154 ? "Dynamic Singleton"
155 : "Static Singleton (Specialized VTableOptimizationTraits)"
156 )
157 << NEW_LINE;
158
159 target << indent << "Usage Counter: " << vtable->DbgCntUsage << NEW_LINE;
160
161 ALIB_ASSERT_ERROR( target.IndexOf( A_CHAR("INTERNAL ERROR") ) < 0, "BOXING",
162 "An internal error occurred while describing type. Description follows:\n"
163 , target)
164
165 ALIB_ASSERT_WARNING( target.IndexOf( A_CHAR("STATIC VTABLE NOT REGISTERED") ) < 0, "BOXING",
166 "An warning occurred while describing type. Description follows:\n"
167 , target)
168 auto functions= GetSpecificFunctionTypes(vtable);
170 DbgStringTable<uinteger> tmpStrings( la );
171 String256 headline; headline << '\n' << indent << "Associated Specialized Functions:";
172 String256 indent2; indent2 << indent << indent;
173 dumpFunctions( functions, target, headline, indent2, tmpStrings );
174}
175
176
177// #############################################################################################
178// Dump Type Lists (conversion for type lists)
179// #############################################################################################
180AString DumpFunctions( const std::vector<std::pair<const std::type_info*,uinteger>>& input,
181 const String& headline,
182 const String& indent )
183{
184 AString result;
186 DbgStringTable<uinteger> tmpStrings( la );
187
188 // repeat twice to get auto-tabs adjusted
190 Formatter& formatter= *Formatter::Default;
191 formatter.Reset();
192 for( int theSakeOfAutoTabs= 0 ; theSakeOfAutoTabs < 2 ; ++theSakeOfAutoTabs )
193 {
194 result.Reset();
195 dumpFunctions( input, result, headline, indent, tmpStrings );
196 }
197
198 return result;
199}
200
201void dumpFunctions( const std::vector<std::pair<const std::type_info*,uinteger>>& input,
202 AString& output,
203 const String& headline,
204 const String& indent,
205 DbgStringTable<uinteger>& tmpStrings )
206{
207 String512 buffer;
208 tmpStrings.clear();
209 for( auto& type : input )
210 tmpStrings.Add( removeNamespaces(buffer.Reset() << *type.first, 0), type.second );
211
212 std::sort( tmpStrings.begin(), tmpStrings.end(),
213 [] (std::tuple<String, uinteger>& a,
214 std::tuple<String, uinteger>& b )
215 {
216 return std::get<0>(a).template CompareTo<CHK, lang::Case::Ignore>( std::get<0>(b) ) < 0;
217 }
218 );
219
220 if ( headline.IsNotEmpty() )
221 output << headline << NEW_LINE;
222
223 Formatter& formatter= *Formatter::Default;
224 auto& args= formatter.Reset();
225 args.Add( indent, "{} {!ATab5}{:>2})\n", nullptr, '(', nullptr );
226 for( auto& nameAndUse : tmpStrings )
227 {
228 args[2]= std::get<0>(nameAndUse);
229 args[4]= std::get<1>(nameAndUse) != (std::numeric_limits<uinteger>::max)()
230 ? Box( std::get<1>(nameAndUse) )
231 : Box( "No default implementation" );
232 formatter.FormatArgs( output, args );
233 }
234 output << NEW_LINE;
235}
236
237AString DumpVTables( bool staticVtables, bool includeFunctions )
238{
239 AString result;
240 LocalAllocator8K allocator;
241
242 // repeat twice to get auto-tabs adjusted
244 Formatter& formatter= *Formatter::Default;
245 formatter.Reset();
246
247 for( int theSakeOfAutoTabs= 0 ; theSakeOfAutoTabs < 2 ; ++theSakeOfAutoTabs )
248 {
249 result .Reset();
250 allocator .Reset();
251 DbgStringTable<const detail::VTable*> vtableNames( allocator );
252 dumpVTables( result, vtableNames, staticVtables , includeFunctions );
253 }
254
255 return result;
256}
257
258
259void dumpVTables( AString& result,
261 bool staticVtables,
262 bool includeFunctions )
263{
264 // dump vtables and their interfaces
265 result << ( staticVtables ? A_CHAR("Mapped types with static VTables")
266 : A_CHAR("Mapped types with dynamic VTables") );
267 if( includeFunctions )
268 result << A_CHAR(" and their associated specialized functions");
269
270 (result << ':' << NEW_LINE) .InsertChars('-', 77) << NEW_LINE;
271
272 // Get vtables and add names to string array
273 vtableNames.clear();
274 String1K temp;
275 DbgLockMaps(true);
276 for( int i= 0 ; i < 2; ++i )
277 for( auto& it : ( i == 0 ? DbgKnownVTables : DbgKnownVTablesArray) )
278 {
279 if( (it.second->DbgProduction == (staticVtables ? detail::VTable::DbgFactoryType::Static
281 || it.second->DbgProduction == detail::VTable::DbgFactoryType::Unregistered )
282 {
283
284 temp.Reset();
285
286 temp << Field( String64("(") << it.second->DbgCntUsage<< ") ", 6, lang::Alignment::Left );
287 typeName( it.second, temp );
288 if( it.second->DbgProduction == detail::VTable::DbgFactoryType::Unregistered )
289 temp << " ATTENTION: Unregistered customized VTable!!! This is an Error";
290
291 vtableNames.Add( temp, it.second );
292 }
293 }
294 DbgLockMaps(false);
295
296 std::sort( vtableNames.begin(), vtableNames.end(),
299 {
300 // skip the prepended usage number
301 Substring lhs= std::get<0>(a); lhs.TrimStart().ConsumeToken(' '); lhs.TrimStart();
302 Substring rhs= std::get<0>(b); rhs.TrimStart().ConsumeToken(' '); rhs.TrimStart();
303 return lhs.CompareTo<CHK, lang::Case::Ignore>( rhs ) < 0;
304 }
305 );
306
308 DbgStringTable<uinteger> tempStrings( la );
309 std::vector<std::pair<const std::type_info*,uinteger>> tempFunctions;
310 for( auto& vtable: vtableNames )
311 {
312 result << std::get<0>(vtable) << NEW_LINE;
313 if( includeFunctions )
314 {
315 getFunctionTypes(std::get<1>(vtable)->Functions, tempFunctions );
316 dumpFunctions( tempFunctions, result, NULL_STRING, A_CHAR(" "), tempStrings );
317 }
318 }
319}
320
321
323{
324 AString result;
325
326 // Get vtables and add names to string array
328
329 // repeat twice to get auto-tabs adjusted
331 Formatter::Default->Reset();
332 for( int theSakeOfAutoTabs= 0 ; theSakeOfAutoTabs < 2 ; ++theSakeOfAutoTabs )
333 {
334 result .Reset();
335 la.Reset();
337 DbgStringTable<uinteger> tempStrings( la);
338
339 dumpVTables( result, vtableNames, true , true ); result.NewLine();
340 dumpVTables( result, vtableNames, false, true ); result.NewLine();
341
342 auto knownFunctions= GetKnownFunctionTypes();
343 (result << "Known Function Declarators And Usage Of Default Implementation:"
344 << NEW_LINE) .InsertChars('-', 77) << NEW_LINE;
345 dumpFunctions( knownFunctions, result, NULL_STRING, A_CHAR(" "), tempStrings );
346
347 #if ALIB_DEBUG_CONTAINERS
348 (result << NEW_LINE << "Metrics Of Custom Function Implementation HashMap: "
349 << NEW_LINE) .InsertChars('-', 77) << NEW_LINE;
350 DumpCustomFunctionHashMapMetrics( result, false );
351 result << NEW_LINE;
352 #endif
353 }
354
355 return result;
356}
357
358#if ALIB_DEBUG_CONTAINERS
359void DumpCustomFunctionHashMapMetrics( AString& target, bool detailedBucketList ) {
360 target << containers::DbgDumpDistribution( detail::customFunctionMap, detailedBucketList );
361}
362#endif
363} // namespace [alib::boxing::debug]
364
365# include "ALib.Lang.CIMethods.H"
366#endif // ALIB_DEBUG_BOXING
static ALIB_DLL threads::RecursiveLock DefaultLock
static ALIB_DLL SPFormatter Default
ALIB_DLL void Reset(Snapshot snapshot=Snapshot())
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.inl:844
constexpr bool IsNotEmpty() const
Definition string.inl:371
#define A_CHAR(STR)
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1050
#define ALIB_LOCK_RECURSIVE_WITH(lock)
Definition alib.inl:1323
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
void dumpVTables(AString &result, DbgStringTable< const detail::VTable * > &vtableNames, bool staticVtables, bool includeFunctions)
ALIB_DLL std::vector< std::pair< const std::type_info *, uinteger > > GetKnownFunctionTypes()
Definition vtable.cpp:185
AString & removeNamespaces(AString &string, integer startIndex)
void typeName(const detail::VTable *vtable, AString &result)
AString DumpFunctions(const std::vector< std::pair< const std::type_info *, uinteger > > &input, const String &headline, const String &indent)
void typeInfo(AString &target, const detail::VTable *vtable, const String &indent, bool srcIsPointer, bool srcIsStringType, bool srcIsUnboxableStringType, bool isValueTypeCustomized, bool isPointerTypeCustomized, bool fitsToPlaceholder, bool copyConstructible, bool triviallyDestructible, bool isUnboxable)
AString DumpVTables(bool staticVtables, bool includeFunctions)
void dumpFunctions(const std::vector< std::pair< const std::type_info *, uinteger > > &input, AString &output, const String &headline, const String &indent, DbgStringTable< uinteger > &tmpStrings)
ALIB_DLL void getFunctionTypes(const detail::FunctionTable &input, std::vector< std::pair< const std::type_info *, uinteger > > &output)
Definition vtable.cpp:219
std::vector< std::pair< const std::type_info *, uinteger > > GetSpecificFunctionTypes(const detail::VTable *vtable)
void DumpCustomFunctionHashMapMetrics(AString &target, bool detailedBucketList)
AString DbgDumpDistribution(const THashtable &hashtable, bool detailedBucketList)
@ Left
Chooses left alignment.
monomem::TLocalAllocator< 8 > LocalAllocator8K
Type alias in namespace alib. Allocates 8kB of stack memory.
LocalString< 512 > String512
Type alias name for TLocalString<character,512>.
constexpr String NULL_STRING
A nulled string of the default character type.
Definition string.inl:2463
LocalString< 256 > String256
Type alias name for TLocalString<character,256>.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
LocalString< 64 > String64
Type alias name for TLocalString<character,64>.
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.inl:644
strings::TField< character > Field
Type alias in namespace alib.
format::Formatter Formatter
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
Definition box.inl:1216
LocalString< 1024 > String1K
Type alias name for TLocalString<character,1024>.
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
std::tuple< String, TAssociatedTypes... > ElementType
Shortcut to the std::tuple-type that instantiations of this template class store.
String & Add(const String &src, TArgs &&... args)
The custom function hash.
Definition vtable.inl:227
DbgFactoryType DbgProduction
Debug information.
Definition vtable.inl:274
const MappingType Mapping
Definition vtable.inl:250
@ Pointer
Pointer boxing.
Definition vtable.inl:235
@ Enum
Enum type boxing.
Definition vtable.inl:236
@ Static
A static VTable is in place.
Definition vtable.inl:268