ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
autosizes.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_strings of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace strings { namespace util {
9
10//==================================================================================================
11/// This class stores and manages tabulator positions and field sizes. The class supports a
12/// simple session handling, by storing each value once for the actual output session and a
13/// second time for a future session. The motivation for writing this class came from the
14/// requirements of logging library \alib_alox. The goals here are:
15///
16/// - During a logging session, log output should be as much tabular as possible.
17/// - On the same time, the log output should be as "narrow" as possible.
18///
19/// If used correctly, this class helps to achieve the following:
20/// - A new log-output session increases tab stops and field widths during execution as needed.
21/// - If values need to be increased, a certain amount of "extra padding" might be
22/// added to avoid too many small increments.
23/// - Once all tab stops or fields have been logged with values of their maximum size, the log output
24/// will not vary in respect to tab stops and auto-sizes anymore.
25/// - If a subsequent session contains the very same log-output (aka the same maximum of requested
26/// tab positions and field width), all extra space is removed and the log output is 100% tabular
27/// beginning with the session start.
28/// - If a subsequent session contains smaller values, then this session is formatted with the
29/// (still larger) width of the previous session. After that, the next session will use the smaller
30/// sizes.
31///
32/// This approach very well guarantees stable log output widths across sessions. Only if the
33/// execution path of software changes (or logging verbosity setting is changed), adjustments
34/// are performed.
35///
36/// To preserve the information across <em>sessions</em>, this class provides methods to transform
37/// its information from and to string representations which can be stored in configuration files.
38///
39/// As the use case of this class is not restricted to log output, but can be used in general when
40/// working with strings, it became a utility class of module \alib_strings_nl.
41///
42/// @see
43/// - The use of this class with field \alib{format;FormatterPythonStyle::Sizes}.
44/// - The use of this class within \alox configuration variable
45/// \alib{lox::textlogger;FormatAutoSizes}.
46//==================================================================================================
48{
49
50 // #############################################################################################
51 // Public fields
52 // #############################################################################################
53 public:
54 /// The entry type, tab stop or field width.
55 enum class Types
56 {
57 Tabstop, ///< denotes a tab stop entry.
58 Field, ///< denotes a field width entry.
59 };
60
61 /// The actual index requested by #Next.
62 /// This field is reset to 0 with every invocation of #Start. The field is public and
63 /// may be read and manipulated, which is considered "expert use".
64 unsigned int ActualIndex;
65
66 // #############################################################################################
67 // Protected fields
68 // #############################################################################################
69 protected:
70 /// Actual and current session entries of tab stop indexes, respectively field widths.
71 struct Entry
72 {
73 Types type; ///< The type of entry.
74 integer actual; ///< The actually used value.
75 integer session; ///< The maximum value requested in the actual session.
76
77 /// Constructor.
78 /// @param t Value for field #type.
79 /// @param v Value for field #actual.
80 /// @param s Value for field #session.
82 : type(t), actual(v), session(s)
83 {}
84 }; // struct Entry
85
86 /// The current and measured sizes.
87 std::vector<Entry> data;
88
89 /// Determines whether any value was changed sincel last #Reset.
90 bool dirty;
91
92 // #############################################################################################
93 // Interface
94 // #############################################################################################
95 public:
96 /// If set, method #Actual will not update the values, but instead return the requested
97 /// value.<br>
98 /// Defaults to \c false.
99 bool WriteProtected = false;
100
101 /// Resets all values, the current ones and the ones of the currently measured session, to
102 /// \c 0 and invokes #Restart().
103 void Reset () { data.clear(); Restart(); dirty= true; }
104
105 /// Determines whether any value was changed since construction, or the last invocation of
106 /// methods #Import, #Export or #SetUnchanged.
107 /// @return \c true if any entry was changed, \c false otherwise.
108 bool IsChanged() const { return dirty; }
109
110 /// Same as #IsChanged(), but clears the internal flag.
111 /// @return \c true if any entry was changed, \c false otherwise.
112 bool SetUnchanged() { bool result= dirty; dirty= false; return result; }
113
114 //==========================================================================================
115 /// Consolidates the values. This method is usually not invoked directly.
116 /// Instead, it is invoked with method #Import.
117 /// The method loops through all values and copies the current session values to the actual
118 /// ones. The difference of both values is summed up during the loop and entries of type
119 /// \alib{strings::util::AutoSizes;Types::Tabstop} are adjusted by that difference.
120 /// As a result, the new values represent the smallest output format that fits all
121 /// rows, if the same output is performed as in the previous "session".
122 //==========================================================================================
124 void Consolidate();
125
126 //==========================================================================================
127 /// Initializes a new query sequence, which is a series of invocations of method #Next.
128 /// @param startIdx The tab stop or field size position to continue with.
129 //==========================================================================================
130 void Restart( unsigned int startIdx= 0 ) { ActualIndex= startIdx; }
131
132 //==========================================================================================
133 /// Returns the actual auto value stored, respectively, if the given requested size is
134 /// higher than what is stored, stores and returns the requested size.
135 ///
136 /// In the latter case, the given extra growth is added to the requested size, but only if
137 /// the value was set at least once before. In other words, the extra size is added only with
138 /// the second growth and each subsequent one.
139 ///
140 /// The requested size in addition replaces the current "session" value if it is higher than
141 /// the currently stored value. To this value, the growth padding is not added.
142 ///
143 /// The whole mechanism can be disabled by setting flag #WriteProtected. If so, this
144 /// method just returns \p{requestedSize}
145 ///
146 /// If any of the values are changed, a call to #IsChanged will return \c true.
147 ///
148 /// @param type The type of entry.
149 /// @param requestedSize The minimum size that is requested.
150 /// @param growthPadding Added to the new size, if the requested size is greater than
151 /// the stored size and if the stored size does not equal \c -1.
152 ///
153 /// @return The (new) size of the auto field.
154 //==========================================================================================
156 integer Actual( Types type, integer requestedSize, integer growthPadding );
157
158 //==========================================================================================
159 /// Invokes #Actual and then increases the internal position counter.
160 ///
161 /// @param type The type of entry.
162 /// @param requestedSize The minimum size that is requested.
163 /// @param growthPadding Added to the new size if the requested size is greater than
164 /// the stored size and if the stored size does not equal \c -1.
165 ///
166 /// @return The (new) size of the auto field.
167 //==========================================================================================
168 integer Next ( Types type, integer requestedSize, integer growthPadding )
169 {
170 auto result= Actual( type, requestedSize, growthPadding );
171 ++ActualIndex;
172 return result;
173 }
174
175 //==========================================================================================
176 /// Imports values from the given \alib{strings;TString;String} by parsing it.
177 /// Usually, string data are used for importing values was previously generated
178 /// with method #Export.
179 ///
180 /// If parameter \p{session} equals \alib{lang::CurrentData;Clear} (which is the default),
181 /// then after the import, method #Consolidate is invoked.
182 ///
183 /// \note
184 /// Parsing is 100% error-tolerant. If the given string does not contain what is expected
185 /// (see method #Export), then only a part or just nothing is imported.
186 /// This is due to the purpose of this class, which is to allow nicer, tabbed output.
187 /// If this is not possible due to import problems, the system should work normally still.
188 /// With debug-builds, a \ref alib_mod_assert "warning is raised" in this case.
189 ///
190 /// This method clears the internal flag that tracks changes, hence after an invocation,
191 /// #IsChanged returns \c false.
192 ///
193 /// @param source The \b %String that is parsed for the exported data.
194 /// @param session Denotes if #Consolidate is to be invoked after import.
195 /// Defaults to \alib{lang::CurrentData;Clear}, which performs
196 /// consolidation.
197 //==========================================================================================
199 void Import( const String& source, lang::CurrentData session= lang::CurrentData::Clear );
200
201 //==========================================================================================
202 /// Exports the current session values by serializing the stored values into to the given
203 /// \alib{strings;TAString;AString} object.
204 ///
205 /// For each current entry in this object, <c>"T|F Actual[,session]</c> is written,
206 /// separated by a forward slash <c>'/'</c>. The session value is written only in case
207 /// it differs from the actual value.
208 /// Furthermore, if field #WriteProtected is set, an exclamation mark <c>'!'</c> will be
209 /// written as a first character. With that, the complete syntax is:
210 ///
211 /// [!] [ T|F Actual[,session] ] [/ T|F Actual[,session] ]
212 ///
213 /// This method clears the internal flag that tracks changes, hence after an invocation,
214 /// #IsChanged returns \c false.
215 ///
216 /// @param target The \b %AString to receive the our values
217 //==========================================================================================
219 void Export( AString& target );
220};
221
222
223}} // namespace alib[::strings::util]
224
225
226/// Type alias in namespace \b alib.
228
229} // namespace [alib]
230
231
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
void Restart(unsigned int startIdx=0)
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
integer Next(Types type, integer requestedSize, integer growthPadding)
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_EXPORT
Definition alib.inl:488
@ Clear
Chooses to clear existing data.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::util::AutoSizes AutoSizes
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
integer actual
The actually used value.
Definition autosizes.inl:74
Entry(Types t, integer v, integer s)
Definition autosizes.inl:81
integer session
The maximum value requested in the actual session.
Definition autosizes.inl:75