ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
appendables.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 !defined(ALIB_DOX)
10#if !defined (HPP_ALIB_STRINGS_LOCALSTRING)
12#endif
13
14#if !defined (HPP_ALIB_STRINGS_FORMAT)
16#endif
17
18#if !defined (HPP_ALIB_STRINGS_DETAIL_NUMBERCONVERSION)
20#endif
21
22#if ALIB_DEBUG && !defined (HPP_ALIB_LANG_DBGTYPEDEMANGLER)
24#endif
25#endif // !defined(ALIB_DOX)
26
27
28namespace alib { namespace strings {
29
30#if defined(ALIB_DOX)
31/**
32 * \attention
33 * This is a non-existing namespace! It is exclusively defined for the
34 * \https{documentation parser,https://www.doxygen.nl}.
35 *
36 * In this <b>"documentation namespace"</b>, you will find specializations of functor
37 * \alib{strings;T_Append} which in reality are implemented in parent
38 * namespace \ref alib::strings (as required by C++ language syntax).<br>
39 * The rational for tricking the documentation to this pseude-namespace, is to twofold:
40 * On the one hand to keep namespace \b %alib::strings clean and on the other to have
41 * an overview of all specializations in one place.
42 */
43namespace APPENDABLES {
44#endif
45
46// #################################################################################################
47// Integrals
48// #################################################################################################
49template<typename TChar>
51{
52 target.template _<false>( b ? "true" : "false" );
53}
54
55template<typename TChar>
57{
58 target.EnsureRemainingCapacity(28);// 20 digits, grouping symbol, sign and what have you
59 integer length= target.Length();
60 length= detail::WriteDecSigned ( value, target.VBuffer(), length, 0, TNumberFormat<TChar>::Computational );
61 target.SetLength( length );
62}
63
64template<typename TChar>
66{
67 target.EnsureRemainingCapacity(28);// 20 digits, grouping symbol, sign and what have you
68 integer length= target.Length();
69 length= detail::WriteDecUnsigned ( value, target.VBuffer(), length, 0, TNumberFormat<TChar>::Computational );
70 target.SetLength( length );
71}
72
73
74template<typename TChar>
76{
77 target.EnsureRemainingCapacity(48); // float: 2x15 + '.' + ',' + sign + fear
78 integer length= target.Length();
79 length= detail::WriteFloat( value, target.VBuffer(), length, 0, TNumberFormat<TChar>::Computational );
80 target.SetLength( length );
81}
82
98
99
100// #################################################################################################
101// std::type_info
102// #################################################################################################
103#if ALIB_DEBUG
104 template<typename TChar>
105 void T_Append<std::type_info, TChar>::operator()( TAString<TChar>& target, const std::type_info& type )
106 {
107 target.template _<false>( lang::DbgTypeDemangler( type ).Get() );
108 }
109 template void T_Append<std::type_info , nchar>::operator()( TAString<nchar>&, const std::type_info& );
110 template void T_Append<std::type_info , wchar>::operator()( TAString<wchar>&, const std::type_info& );
111 template void T_Append<std::type_info , xchar>::operator()( TAString<xchar>&, const std::type_info& );
112#endif
113
114// #################################################################################################
115// TFormat::Tab()
116// #################################################################################################
117template<typename TChar>
118void T_Append<typename TFormat<TChar>::Tab, TChar>::operator()( TAString<TChar>& target, const typename TFormat<TChar>::Tab& tab)
119{
120 integer reference= tab.reference;
121 if (reference < 0 )
122 {
123 // search backwards
124 reference= target.template LastIndexOfAny<lang::Inclusion::Include>( TT_StringConstants<TChar>::NewLine(), target.Length() -1 );
125 if ( reference < 0 )
126 reference= 0;
127 else
128 {
129 // if new line has more than one character (windows) we have to now search the first
130 // character that is not in newline
131 reference= target.template IndexOfAny<lang::Inclusion::Exclude, false>( TT_StringConstants<TChar>::NewLine(), reference );
132 if (reference < 0 )
133 reference= target.Length();
134
135 }
136 }
137 integer length= target.Length();
138 integer qtyChars= tab.minPad > 0 ? tab.minPad : 0;
139
140 if ( tab.tabSize > 1 )
141 qtyChars+= (tab.tabSize - ( (length + qtyChars - reference) % tab.tabSize ) ) % tab.tabSize;
142
143 if ( qtyChars > 0 )
144 target.template InsertChars<false>( tab.tabChar, qtyChars );
145}
146
147
148// #################################################################################################
149// TFormat::Field()
150// #################################################################################################
151template<typename TChar>
152void T_Append<typename TFormat<TChar>::Field, TChar>::operator()( TAString<TChar>& target, const typename TFormat<TChar>::Field& field)
153{
154
155#if ALIB_BOXING
156 TString<TChar> theContent;
157
158 // buffer used for conversion (if none string)
159 TLocalString<TChar, 256> noneStringArgBuf;
160 noneStringArgBuf.DbgDisableBufferReplacementWarning();
161
162 // string type box given?
163 if( !field.theContent.template IsType<void>() && field.theContent.template IsType<TString<TChar>>() )
164 theContent= field.theContent.template Unbox<TString<TChar>>();
165 else
166 {
167 // write box into local buffer
168 noneStringArgBuf << field.theContent;
169 theContent= noneStringArgBuf;
170 }
171
172#else
173 TString<TChar> theContent= field.theContent;
174#endif
175
176 integer padSize= field.fieldWidth
177 - theContent.WStringLength();
178
179 // check pad field.width
180 if (padSize <= 0 || field.alignment == lang::Alignment::Left )
181 {
182 target.template _ <false>( theContent );
183 if (padSize > 0 ) target.template InsertChars<false>( field.padChar, padSize );
184 return;
185 }
186
187 // align Right
188 if ( field.alignment == lang::Alignment::Right )
189 {
190 if( padSize > 0 )
191 target.template InsertChars<false>( field.padChar, padSize );
192 target.template Append<false>( theContent );
193 return;
194 }
195
196 // align Center
197 integer leftPadding= padSize / 2;
198 if( leftPadding > 0 )
199 target.template InsertChars<false> ( field.padChar, leftPadding );
200 target.template Append<false> ( theContent );
201 if( padSize > leftPadding ) target.template InsertChars<false> ( field.padChar, padSize - leftPadding );
202}
203
204// #################################################################################################
205// TFormat::Escape()
206// #################################################################################################
207template<typename TChar>
208void T_Append<typename TFormat<TChar>::Escape, TChar>::operator()( TAString<TChar>& target, const typename TFormat<TChar>::Escape& escape)
209{
210 if( target.AdjustRegion( const_cast<typename TFormat<TChar>::Escape&>(escape).startIdx,
211 const_cast<typename TFormat<TChar>::Escape&>(escape).length ) )
212 return;
213
214 integer regionEnd= escape.startIdx + escape.length;
215
216 //
217 // To escape sequences
218 //
219 if (escape.pSwitch == lang::Switch::On)
220 {
221 for( integer idx= escape.startIdx; idx < regionEnd ; ++idx )
222 {
223 TChar c= target.CharAt(idx);
224
225 TChar resultChar= '\0';
226 switch(c)
227 {
228 case '\\' : resultChar= '\\'; break;
229 case '\r' : resultChar= 'r' ; break;
230 case '\n' : resultChar= 'n' ; break;
231 case '\t' : resultChar= 't' ; break;
232 case '\a' : resultChar= 'a' ; break;
233 case '\b' : resultChar= 'b' ; break;
234 case '\v' : resultChar= 'v' ; break;
235 case '\f' : resultChar= 'f' ; break;
236 // case '\e' : resultChar= 'e' ; break; Not C++ standard
237 case '"' : resultChar= '"' ; break;
238
239 default : break;
240 }
241
242 if( resultChar != '\0')
243 {
244 target.template InsertChars<false>('\\', 1, idx);
245 target[++idx]= resultChar;
246 ++regionEnd;
247 }
248 }
249 }
250
251 //
252 // Un-escape escape sequences
253 //
254 else
255 {
256 --regionEnd; // we can go 1 over it!
257 for( integer idx= escape.startIdx; idx < regionEnd ; ++idx )
258 {
259 TChar c= target.CharAt(idx);
260 if( c != '\\' )
261 continue;
262
263 c= target.CharAt(idx + 1);
264
265 TChar resultChar= '\0';
266 switch(c)
267 {
268 case '\\' : resultChar= '\\'; break;
269 case 'r' : resultChar= '\r' ; break;
270 case 'n' : resultChar= '\n' ; break;
271 case 't' : resultChar= '\t' ; break;
272 case 'a' : resultChar= '\a' ; break;
273 case 'b' : resultChar= '\b' ; break;
274 case 'v' : resultChar= '\v' ; break;
275 case 'f' : resultChar= '\f' ; break;
276 // case 'e' : resultChar= '\e' ; break; Not C++ standard
277 case '"' : resultChar= '"' ; break;
278
279 default : break;
280 }
281
282 if( resultChar != '\0')
283 {
284 target.Delete( idx, 1);
285 target[idx]= resultChar;
286 --regionEnd;
287 }
288 }
289 }
290}
291
292// #################################################################################################
293// TFormat Integers
294// #################################################################################################
295template<typename TChar>
296void T_Append<TFormat<TChar>, TChar>::operator()( TAString<TChar>& target, const TFormat<TChar>& fmt )
297{
298 const TNumberFormat<TChar>* nf= fmt.nf;
299 if( nf == nullptr )
301
302 target.EnsureRemainingCapacity( fmt.valueType== 3 ? 48 //float: 2x15 + '.' + ',' + sign + fear
303 : 28 //int: 20 digits, grouping symbol, sign and what have you
304 );
305
306 integer length= target.Length();
307
308 length=
309 fmt.valueType == 1 ? detail::WriteDecSigned ( fmt.v.value , target.VBuffer(), length, fmt.width , *nf ) :
310 fmt.valueType == 2 ? detail::WriteDecUnsigned( static_cast<uint64_t>(fmt.v.value) , target.VBuffer(), length, fmt.width , *nf ) :
311 detail::WriteFloat ( fmt.v.fpValue, target.VBuffer(), length, fmt.width , *nf );
312
313 target.SetLength( length );
314}
315
316
317
318template<typename TChar>
319void T_Append<typename TFormat<TChar>::Bin, TChar>::operator()( TAString<TChar>& target, const typename TFormat<TChar>::Bin& fmt )
320{
321 TNumberFormat<TChar>* nf= fmt.nf;
322 if( nf == nullptr )
324
325 target.EnsureRemainingCapacity( 80 );
326
327 integer length= target.Length();
328
329 length= detail::WriteBin( fmt.theValue, target.VBuffer(), length, fmt.theWidth, *nf );
330
331 target.SetLength( length );
332}
333
334template<typename TChar>
335void T_Append<typename TFormat<TChar>::Hex, TChar>::operator()( TAString<TChar>& target, const typename TFormat<TChar>::Hex& fmt )
336{
337 TNumberFormat<TChar>* nf= fmt.nf;
338 if( nf == nullptr )
340
341 target.EnsureRemainingCapacity( 25 );
342
343 integer length= target.Length();
344
345 length= detail::WriteHex( fmt.theValue, target.VBuffer(), length, fmt.theWidth, *nf );
346
347 target.SetLength( length );
348}
349
350template<typename TChar>
351void T_Append<typename TFormat<TChar>::Oct, TChar>::operator()( TAString<TChar>& target, const typename TFormat<TChar>::Oct& fmt )
352{
353 TNumberFormat<TChar>* nf= fmt.nf;
354 if( nf == nullptr )
356
357 target.EnsureRemainingCapacity( 30 );
358
359 integer length= target.Length();
360
361 length= detail::WriteOct( fmt.theValue, target.VBuffer(), length, fmt.theWidth, *nf );
362
363 target.SetLength( length );
364}
365
366
367#if defined(ALIB_DOX)
368} // APPENDABLES documentation fake namespace
369#endif
370
371#if !defined(ALIB_DOX)
372// #################################################################################################
373// NAString instantiations
374// #################################################################################################
375template void T_Append<TFormat<nchar> , nchar>::operator()( TAString<nchar>&, const TFormat<nchar>& );
376template void T_Append<TFormat<nchar>::Tab , nchar>::operator()( TAString<nchar>&, const TFormat<nchar>::Tab& );
377template void T_Append<TFormat<nchar>::Field , nchar>::operator()( TAString<nchar>&, const TFormat<nchar>::Field& );
378template void T_Append<TFormat<nchar>::Escape, nchar>::operator()( TAString<nchar>&, const TFormat<nchar>::Escape& );
379template void T_Append<TFormat<nchar>::Bin , nchar>::operator()( TAString<nchar>&, const TFormat<nchar>::Bin& );
380template void T_Append<TFormat<nchar>::Hex , nchar>::operator()( TAString<nchar>&, const TFormat<nchar>::Hex& );
381template void T_Append<TFormat<nchar>::Oct , nchar>::operator()( TAString<nchar>&, const TFormat<nchar>::Oct& );
382
383
384// #################################################################################################
385// WAString instantiations
386// #################################################################################################
387template void T_Append<TFormat<wchar> , wchar>::operator()( TAString<wchar>&, const TFormat<wchar>& );
388template void T_Append<TFormat<wchar>::Tab , wchar>::operator()( TAString<wchar>&, const TFormat<wchar>::Tab& );
389template void T_Append<TFormat<wchar>::Field , wchar>::operator()( TAString<wchar>&, const TFormat<wchar>::Field& );
390template void T_Append<TFormat<wchar>::Escape, wchar>::operator()( TAString<wchar>&, const TFormat<wchar>::Escape& );
391template void T_Append<TFormat<wchar>::Bin , wchar>::operator()( TAString<wchar>&, const TFormat<wchar>::Bin& );
392template void T_Append<TFormat<wchar>::Hex , wchar>::operator()( TAString<wchar>&, const TFormat<wchar>::Hex& );
393template void T_Append<TFormat<wchar>::Oct , wchar>::operator()( TAString<wchar>&, const TFormat<wchar>::Oct& );
394
395// #################################################################################################
396// XAString instantiations
397// #################################################################################################
398template void T_Append<TFormat<xchar> , xchar>::operator()( TAString<xchar>&, const TFormat<xchar>& );
399template void T_Append<TFormat<xchar>::Tab , xchar>::operator()( TAString<xchar>&, const TFormat<xchar>::Tab& );
400template void T_Append<TFormat<xchar>::Field , xchar>::operator()( TAString<xchar>&, const TFormat<xchar>::Field& );
401template void T_Append<TFormat<xchar>::Escape, xchar>::operator()( TAString<xchar>&, const TFormat<xchar>::Escape& );
402template void T_Append<TFormat<xchar>::Bin , xchar>::operator()( TAString<xchar>&, const TFormat<xchar>::Bin& );
403template void T_Append<TFormat<xchar>::Hex , xchar>::operator()( TAString<xchar>&, const TFormat<xchar>::Hex& );
404template void T_Append<TFormat<xchar>::Oct , xchar>::operator()( TAString<xchar>&, const TFormat<xchar>::Oct& );
405
406#endif // !defined(ALIB_DOX)
407
408
409}} // namespace [alib::strings]
void DbgDisableBufferReplacementWarning()
Definition astring.hpp:353
void EnsureRemainingCapacity(integer spaceNeeded)
Definition astring.hpp:680
TChar * VBuffer() const
Definition astring.hpp:780
void SetLength(integer newLength)
Definition astring.hpp:861
constexpr integer Length() const
Definition string.hpp:357
integer WStringLength() const
@ On
Switch it on, switched on, etc.
@ Right
Chooses right alignment.
@ Left
Chooses left alignment.
ALIB_API integer WriteFloat(double value, TChar *buffer, integer idx, int minWidth, const TNumberFormat< TChar > &nf)
ALIB_API integer WriteDecUnsigned(uint64_t value, TChar *buffer, integer idx, int minWidth, const TNumberFormat< TChar > &nf)
ALIB_API integer WriteOct(uint64_t value, TChar *buffer, integer idx, int minWidth, const TNumberFormat< TChar > &nf)
ALIB_API integer WriteDecSigned(int64_t value, TChar *buffer, integer idx, int minWidth, const TNumberFormat< TChar > &nf)
ALIB_API integer WriteHex(uint64_t value, TChar *buffer, integer idx, int minWidth, const TNumberFormat< TChar > &nf)
ALIB_API integer WriteBin(uint64_t value, TChar *buffer, integer idx, int minWidth, const TNumberFormat< TChar > &nf)
Definition alib.cpp:57
characters::wchar wchar
Type alias in namespace alib.
characters::xchar xchar
Type alias in namespace alib.
characters::nchar nchar
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
static TNumberFormat Computational
void operator()(TAString< TChar > &target, const TAppendable &src)