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