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