ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
exception.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 ========================================
15#include <vector>
16#include <algorithm>
17#include <any>
19//============================================== Module ============================================
20#if ALIB_C20_MODULES
21 module ALib.Exceptions;
22 import ALib.Lang;
23 import ALib.Strings;
24 import ALib.Strings.Tokenizer;
25 import ALib.Boxing;
26 import ALib.EnumRecords;
27 import ALib.EnumRecords.Bootstrap;
28# if ALIB_SYSTEM
29 import ALib.System;
30# endif
31# if ALIB_FORMAT
32 import ALib.Format;
33# endif
34 import ALib.Format.Paragraphs;
35# if ALIB_CAMP
36 import ALib.Camp.Base;
37# endif
38#else
39# include "ALib.Lang.H"
40# include "ALib.Strings.H"
42# include "ALib.Boxing.H"
43# include "ALib.EnumRecords.H"
45# include "ALib.System.H"
46# include "ALib.Format.H"
48# include "ALib.Camp.Base.H"
49# include "ALib.Exceptions.H"
50#endif
51//========================================== Implementation ========================================
53
54
55namespace alib::exceptions {
56
58 enumrecords::bootstrap::EnumRecordParser::Get( ERSerializable::EnumElementName );
59 ERSerializable::MinimumRecognitionLength= 0;
61}
62
64 // find pointer to the last entry pointer;
65 detail::ExceptionEntry** tail= &**this;
66 while(*tail != nullptr)
67 tail= &(*tail)->next;
68
69 *tail= GetAllocator()().Alloc<detail::ExceptionEntry>();
70 (*tail)->next= nullptr;
71
72 return &(*tail)->message;
73}
74
75
77 bool hasRecord,
78 ResourcePool* pool,
79 const NString& category ) {
80 message->CloneAll();
81
82 if( hasRecord ) {
83 #if ALIB_DEBUG
84 {
85 auto* tryRecord= boxing::TryRecord<ERException>(message->Type);
86 if( tryRecord == nullptr ) {
87 std::vector<std::pair<integer,const void*>> recordList;
88 for( auto& record : enumrecords::detail::getInternalRecordMap() )
89 if( record.first.RTTI == message->Type.TypeID() )
90 recordList.push_back( std::pair<integer,const void*>(record.first.Element, record.second) );
91 if( recordList.size() == 0) {
92 ALIB_ERROR( "EXCEPT", "No enum records defined for exception enumeration "
93 "type {!Q<>}.", message->Type.TypeID().name() )
94 } else {
95 std::sort( recordList.begin(), recordList.end(),
96 [] (std::pair<integer,const void*>& a, std::pair<integer,const void*>& b )
97 {
98 return a.first < b.first;
99 });
100 std::vector<std::any> args; args.reserve(32);
101 args.emplace_back( "Enum record {} not found for exception enumeration type {}.\n"
102 "The following records have been found:\n" );
103 args.emplace_back( message->Type.Integral() );
104 args.emplace_back( &message->Type.TypeID() );
105
106 for( auto& pair : recordList ) {
107 args.emplace_back( " {}: {}\n" );
108 args.emplace_back( pair.first );
109 args.emplace_back( reinterpret_cast<const ERException*>( pair.second )->EnumElementName );
110 }
111 assert::raise( ALIB_CALLER_PRUNED, 1, "EXCEPT", args );
112 } } }
113 #endif
114 const auto& enumRecord= boxing::GetRecord<ERException>(message->Type);
115 if( pool == nullptr )
116 message->emplace( message->begin(),
117 enumRecord.DescriptionOrItsResourceName );
118 else
119 message->emplace( message->begin(),
120 pool->Get( category,
121 enumRecord.DescriptionOrItsResourceName
122 ALIB_DBG(, true) ) );
123} }
124
125
127 auto* result= **this;
128 while( result->next != nullptr )
129 result= result->next;
130
131 return result->message;
132}
133
134int Exception::Size() const {
135 int result= 1;
136 auto* entry= **this;
137 while( entry->next != nullptr ) {
138 entry= entry->next;
139 ++result;
140 }
141
142 return result;
143}
144
145const Enum& Exception::Type() const {
146 auto* entry= **this;
147 Enum* result= &entry->message.Type;
148 while( (entry= entry->next) != nullptr )
149 if( entry->message.Type.Integral() >= 0 )
150 result= &entry->message.Type;
151
152 return *result;
153}
154
155
156#if ALIB_FORMAT
158 Paragraphs text(target);
159 Tokenizer tknzr;
160 tknzr.TrimChars= A_CHAR( "\r" );
161 String1K buf;
163 Formatter& formatter= *Formatter::Default;
164 formatter.GetArgContainer();
165 size_t entryNo= 1;
166 for ( auto entry= begin(); entry != end(); ++entry ) {
167 text.Add( A_CHAR("{}{}: {!Q<>}"), (entry->Type.Integral() >= 0 ? 'E' : 'I'), entryNo, entry->Type );
168 text.PushIndent( A_CHAR(" ") );
169 try
170 {
171 formatter.FormatArgs( buf.Reset(), *entry );
172 }
173 catch( Exception& e )
174 {
175 #if ALIB_CAMP
176 buf << BASECAMP.GetResource("ExcFmtExc");
177 #else
178 buf << A_CHAR("\nAn exception occurred while formatting another (!) exception:\n" );
179 #endif
180 e.Format( buf );
181 }
182 tknzr.Set( buf, '\n' );
183 while( tknzr.HasNext() )
184 text.Add( tknzr.Next() );
185
186 #if ALIB_DEBUG
187 text.Add( entry->CI );
188 #endif
189
190 text.PopIndent();
191 ++entryNo;
192 }
193
194 return target;
195}
196#endif // ALIB_FORMAT
197
198} // namespace [alib::lang]
199
200
201#if ALIB_CAMP
202namespace alib::system {
203
205 auto* enumRecord= enumrecords::TryRecord( SystemErrors(errNo) );
206 if( enumRecord == nullptr )
207 return Exception( ci, SystemErrors::UNKNOWN, errNo );
208
209 return Exception( ci, SystemErrors(errNo), // as exception
210 SystemErrors(errNo), // boxing the exception's name (!)
211 errNo );
212}
213} // namespace [alib::lang]
214#endif
Exception(Exception &) noexcept=default
Deleted copy constructor. Exceptions must be caught only as references.
ALIB_DLL AString & Format(AString &target) const
ALIB_DLL Message & Back() const
ALIB_DLL Message * allocMessageLink()
Definition exception.cpp:63
ForwardIterator begin()
ALIB_DLL const Enum & Type() const
ALIB_DLL void finalizeMessage(Message *message, bool hasRecord, ResourcePool *pool, const NString &category)
Definition exception.cpp:76
ALIB_DLL int Size() const
static ALIB_DLL SPFormatter Default
ALIB_DLL Paragraphs & PushIndent(uinteger qty, character fillChar=' ')
void Add(boxing::TBoxes< TAllocatorArgs > &args)
ALIB_DLL Paragraphs & PopIndent()
virtual const String & Get(const NString &category, const NString &name, bool dbgAssert)=0
void DbgDisableBufferReplacementWarning()
Definition tastring.inl:244
ALIB_DLL TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:26
void Set(const TString< TChar > &src, TChar delimiter, bool skipEmptyTokens=false)
TLocalString< TChar, 8 > TrimChars
Definition tokenizer.inl:71
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
#define A_CHAR(STR)
#define ALIB_ERROR(domain,...)
Definition alib.inl:1062
#define ALIB_DBG(...)
Definition alib.inl:853
#define ALIB_CALLER_PRUNED
Definition alib.inl:1024
void raise(const CallerInfo &ci, int type, std::string_view domain, const std::span< std::any > &args)
Definition assert.cpp:565
const TRecord * TryRecord(Enum e)
const TRecord & GetRecord(Enum e)
HashMap< MonoAllocator, EnumRecordKey, const void *, EnumRecordKey::Hash, EnumRecordKey::EqualTo > & getInternalRecordMap()
Definition records.cpp:87
const RecordsTraits< TEnum >::Type * TryRecord(TEnum element)
Definition records.inl:214
Exception CreateSystemException(const CallerInfo &ci, int errNo)
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace alib.
camp::Basecamp BASECAMP
The singleton instance of ALib Camp class Basecamp.
Definition basecamp.cpp:81
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2198
format::Paragraphs Paragraphs
Type alias in namespace alib.
resources::ResourcePool ResourcePool
Type alias in namespace alib.
format::Formatter Formatter
Type alias in namespace alib.
boxing::Enum Enum
Type alias in namespace alib.
Definition enum.inl:192
LocalString< 1024 > String1K
Type alias name for TLocalString<character,1024>.
exceptions::Exception Exception
Type alias in namespace alib.
lang::CallerInfo CallerInfo
Type alias in namespace alib.
integer Integral() const
Definition enum.inl:86
const std::type_info & TypeID() const
Definition box.inl:780
String EnumElementName
The name of the enum element.
Definition records.inl:430
static ALIB_DLL void Get(String &result, bool isLastField=false)
ExceptionEntry * next
A pointer to the next message.
Definition exception.inl:20