ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
autosizes.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// =========================================== Module ==========================================
17#if ALIB_C20_MODULES
20#else
23#endif
24// ====================================== Implementation =======================================
25namespace alib { namespace strings { namespace util {
26
27integer AutoSizes::Actual( Types type, integer requestedSize, integer growthPadding )
28{
29 // grow arrays as needed
30 while ( data.size() <= ActualIndex )
31 {
32 data.emplace_back( type, -1, -1 );
33 dirty= true;
34 }
35
36 if ( data[ActualIndex].type != type )
37 {
38 data[ActualIndex].type = type;
39 data[ActualIndex].actual= 0;
40 data[ActualIndex].session= -1;
41 dirty= true;
42 }
43
44 if( WriteProtected )
45 return (std::max)( data[ ActualIndex ].actual, requestedSize );
46
47 // set measured size as it would be for the next session
48 integer& session= data[ ActualIndex ].session;
49 if ( session < requestedSize )
50 {
51 session= requestedSize;
52 dirty= true;
53 }
54
55 // get size as it is for actual values (max of imported and session)
56 integer& actual= data[ ActualIndex ].actual;
57 if ( actual < requestedSize )
58 {
59 actual= (requestedSize + ( actual < 0 ? 0 : growthPadding ));
60 dirty= true;
61 }
62
63 return actual;
64}
65
67{
68 if( WriteProtected )
69 target._( "! ");
70
71 auto it= data.begin();
72 while( it!=data.end() )
73 {
74 target << ((*it).type == Types::Tabstop ? 'T' : 'F' )
75 << (*it).actual;
76 if( !WriteProtected && (*it).session != (*it).actual)
77 target << ',' << (*it).session;
78
79 ++it;
80 if( it!=data.end())
81 target << '/';
82 else
83 break;
84 }
85
86 // remove unused entries at the end
87 while( target.EndsWith(A_CHAR("/T0" ))
88 || target.EndsWith(A_CHAR("/F0" ))
89 || target.EndsWith(A_CHAR("/T-1" ))
90 || target.EndsWith(A_CHAR("/F-1" )) )
91 target.DeleteEnd<NC>(target.Length() - target.LastIndexOf('/'));
92
93 dirty= false;
94}
95
96void AutoSizes::Import( const String& src, lang::CurrentData session )
97{
98 Reset();
99 dirty= false;
100
101 #if ALIB_DEBUG
102 # define PARSERROR ALIB_WARNING( "STRINGS", \
103 "Error reading tab stops string \"{}\":\n at position ", \
104 src, src.Length() - parser.Length() )
105 #else
106 # define PARSERROR
107 #endif
108 Substring parser(src);
110 if(parser.Trim().IsEmpty())
111 return;
112
113 Tokenizer tknzr( parser, '/' );
114 while(tknzr.HasNext())
115 {
116 parser= tknzr.Next();
117 Types type;
120 else { PARSERROR break; }
121
122 integer actual;
123 parser.ConsumeInt( actual );
124
125 integer sessionValue;
127 sessionValue= actual;
128 else
129 parser.ConsumeInt( sessionValue );
130
131 data.emplace_back( type, actual, sessionValue );
132 }
133
134 if( session == lang::CurrentData::Clear )
135 Consolidate();
136}
137
139{
140 integer tabDiff = 0;
141 integer lastTabStop = 0;
142 for( auto& entry : data )
143 {
144 integer actDiff= entry.session - entry.actual;
145 if( actDiff > 0 ) // should never happen. Maybe improper data import?
146 actDiff= 0;
147 if( entry.type == Types::Tabstop )
148 {
149 // reset tab difference if (for some strange application-specific reason) this
150 // tab stop is smaller than the previous one. Obviously some multi-line tab stop
151 // is used (does not happen for example with ALox)
152 if( entry.actual > lastTabStop )
153 {
154 lastTabStop= entry.actual;
155 entry.actual= entry.session + tabDiff;
156 }
157 else
158 {
159 lastTabStop= entry.actual;
160 tabDiff= 0;
161 entry.actual= entry.session + tabDiff;
162 }
163 }
164 else
165 {
166 entry.actual = entry.session;
167 }
168 tabDiff+= actDiff;
169 entry.session = -1;
170 }
171}
172
173
174}}} // namespace [alib::strings::util]
175
TAString & DeleteEnd(integer regionLength)
TAString & _(const TAppendable &src)
constexpr integer Length() const
Definition string.inl:318
constexpr bool IsEmpty() const
Definition string.inl:367
bool EndsWith(const TString &needle) const
Definition string.inl:805
integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
Definition string.inl:967
bool ConsumeInt(std::integral auto &result, TNumberFormat< TChar > *numberFormat=nullptr)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
ALIB_DLL integer Actual(Types type, integer requestedSize, integer growthPadding)
Definition autosizes.cpp:27
ALIB_DLL void Export(AString &target)
Definition autosizes.cpp:66
bool dirty
Determines whether any value was changed sincel last Reset.
Definition autosizes.inl:90
ALIB_DLL void Import(const String &source, lang::CurrentData session=lang::CurrentData::Clear)
Definition autosizes.cpp:96
std::vector< Entry > data
The current and measured sizes.
Definition autosizes.inl:87
Types
The entry type, tab stop or field width.
Definition autosizes.inl:56
@ Field
denotes a field width entry.
Definition autosizes.inl:58
@ Tabstop
denotes a tab stop entry.
Definition autosizes.inl:57
ALIB_DLL TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:26
#define A_CHAR(STR)
@ Clear
Chooses to clear existing data.
@ Trim
Trim whitespaces away.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
strings::TSubstring< character > Substring
Type alias in namespace alib.