ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
formatter.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_format 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 format {
9
10//==================================================================================================
11/// This struct declares the signature of the \ref alib_boxing_functions "box-function"
12/// \b FFormat. It can be implemented to write the contents of a boxed type the given
13/// \b %AString instance, in accordance with a custom format specification.
14///
15/// \see
16/// For more information about this class see chapter
17/// \ref alib_format_custom_types of the Programmer's Manual of module \alib_format_nl.
18//==================================================================================================
19struct FFormat
20{
21 /// Signature of the invokable function.<br>
22 /// Implementations write the content of \p{box} to the given \b %AString object \p{target} in
23 /// accordance to the type-specific format specification \p{formatSpec}.
24 ///
25 /// @param self The box that the function was invoked on.
26 /// @param formatSpec The specification of the format (type specific). If empty, a default
27 /// specification string might have to be chosen.
28 /// @param nf A copy of the number format of the formatter (allowed to be modified).
29 /// @param target The AString object receiving the formatted string.
30 using Signature = void (*) ( const Box& self, const String& formatSpec, NumberFormat& nf,
31 AString& target );
32};
33
34
35// forward declaration
36class Formatter;
37
38} // namespace alib[::format]
39
40/// A shared pointer to instances of \alib{format;Formatter;standard formatters}.
41/// \see Static member \alib{format;Formatter::Default}.
43
44namespace format {
45
46//==================================================================================================
47/// This is an abstract base class to implement an \alib string formatter. A string formatter
48/// uses a "format string" to transform arguments into formatted text. The format string defines
49/// how the arguments are transformed by offering a "placeholder syntax".
50///
51/// With this information, it becomes clear that different formatter types (derived types that offer
52/// a concrete placeholder syntax) all can have the same interface methods.
53/// This class defines this abstract interface.
54///
55/// Built-in formatters derived from this class, are
56/// \alib{format;FormatterPythonStyle;FormatterPythonStyle} and
57/// \alib{format;FormatterJavaStyle;FormatterJavaStyle}.
58//==================================================================================================
62#endif
63{
64
65 //################################################################################################
66 // Internal fields
67 //################################################################################################
68 protected:
69 /// This allocator is (exclusively) used for field #boxes.
71
72 /// A list of boxes. This is reset with every new invocation of variadic template method
73 /// #Format
75
76 /// A buffer used for conversion of the next argument if it is not of a string-type.
78
80
81 //################################################################################################
82 // public fields
83 //################################################################################################
84 public:
85 /// Stores default attributes for formatting numbers.
86 /// Likewise #AlternativeNumberFormat, it usually is not used directly for formatting by
87 /// descendants.
88 /// Instead, at the beginning of parsing a next placeholder field, values are copied to
89 /// a local copy. During the parsing process, values are then modified only in this local
90 /// copy, probably taken from #AlternativeNumberFormat.
91 ///
92 /// This object is to be initialized in the constructor (of descendants) once to meet the
93 /// formatting defaults of the corresponding specification.
94 /// If after construction, attribute values of this object are changed, such changes are
95 /// applied to all number formatting.
97
98 /// This number format is used to store alternative attributes. Likewise #DefaultNumberFormat,
99 /// it is never used directly for formatting.
100 /// Instead, when processing the placeholder syntax, alternatives get copied from either this
101 /// object or from #DefaultNumberFormat.
102 ///
103 /// This object is initialized in the constructor (of descendants) once to meet the
104 /// formatting defaults of the corresponding specification.
105 ///
106 /// With the implementations of this class provided with \alib, not all fields in this object
107 /// are used. The fields used are:
108 /// <p>
109 /// - Locale-specific versions of floating point separators:
110 /// - \alib{strings;TNumberFormat::DecimalPointChar;NumberFormat::DecimalPointChar}
111 /// - \alib{strings;TNumberFormat::ThousandsGroupChar;NumberFormat::ThousandsGroupChar}
112 ///
113 /// These are retrieved according to the current locale once in the constructor. To
114 /// change the locale, these fields can be changed.
115 ///
116 /// - Lower case versions of floating point literals:
117 /// - \alib{strings;TNumberFormat::ExponentSeparator;NumberFormat::ExponentSeparator}
118 /// - \alib{strings;TNumberFormat::INFLiteral;NumberFormat::INFLiteral}
119 /// - \alib{strings;TNumberFormat::NANLiteral;NumberFormat::NANLiteral}
120 ///
121 /// - Lower case versions of prefix literals that indicate the base of integral values:
122 /// - \alib{strings;TNumberFormat::BinLiteralPrefix;BinLiteralPrefix}
123 /// - \alib{strings;TNumberFormat::HexLiteralPrefix;HexLiteralPrefix}
124 /// - \alib{strings;TNumberFormat::OctLiteralPrefix;OctLiteralPrefix}
126
127 /// An optional, next formatter. If set, this formatter will be invoked for a format string
128 /// that does not contain recognized placeholders.
129 /// \attention
130 /// This field is public and not further maintained by this class. Setting the field lies
131 /// completely in the responsibility of the user. E.g., cyclic settings must be avoided.
132 /// Also, object life-cycle management is completely up to the user.
134
135 //################################################################################################
136 // Constructor/destructor
137 //################################################################################################
138 public:
139 /// Default Constructor.
141 :
143 lang::DbgCriticalSections("Formatter")
144 ,
145 #endif
146 allocator(ALIB_DBG("Formatter",) 1)
147 , boxes( allocator ) {}
148
149 /// Destructs an object of this class.
150 /// Note that concatenated formatters are not deleted automatically.
151 virtual ~Formatter() {}
152
153 //################################################################################################
154 // Interface
155 //################################################################################################
156
157 /// Variadic template method that accepts a target \b %AString and a list of arguments.
158 /// This is a convenience method to allow single-line format invocations.
159 ///
160 /// \note
161 /// This method uses <c>static_assert</c> to disallow the invocation with one
162 /// variadic argument of type \alib{boxing;TBoxes} or a derived type.
163 /// This is to ensure that for these box containers, the more efficient method #FormatArgs
164 /// is used.
165 ///
166 /// @tparam TArgs Variadic template type list.
167 /// @param target An AString that takes the result.
168 /// @param args The variadic list of arguments to be used with formatters.
169 /// @return A reference to this formatter to allow concatenated operations.
170 template <typename... TArgs>
171 Formatter& Format( AString& target, TArgs&&... args ) {
172 // assert that this method is not used with Boxes containers.
173 // Those are to be processed with FormatArgs
174 constexpr bool Argument_has_type_Boxes=
175 (sizeof...(TArgs) == 1)
176 && ( std::is_base_of_v< Boxes , std::decay< std::tuple_element<0, std::tuple<TArgs...>>>>
177 || std::is_base_of_v< BoxesMA, std::decay< std::tuple_element<0, std::tuple<TArgs...>>>>
178 || std::is_base_of_v< BoxesPA, std::decay< std::tuple_element<0, std::tuple<TArgs...>>>> );
179 static_assert( !Argument_has_type_Boxes,
180 "To pass a container of type Boxes to a formatter, use method FormatArgs." );
181
182 // create argument objects using implicit constructor invocation
183 boxes.clear();
184 boxes.Add( std::forward<TArgs>( args )... );
185
186 // invoke format
187 formatLoop( target, boxes );
188 return *this;
189 }
190
191 /// Formats the internal list of arguments that is returned by methods #GetArgContainer
192 /// and #Reset.
193 ///
194 /// This method may be more efficient than using inlined variadic method \b Format
195 /// and should be preferred if:
196 /// - Format arguments cannot be collected in a single invocation, for example, if those
197 /// are to be collected in a loop.
198 /// - A sequence of different format operations is to be performed.
199 ///
200 /// @param target An AString that takes the result.
201 /// @return A reference to this formatter to allow concatenated operations.
202 inline
203 Formatter& FormatArgs( AString& target ); // implementation below
204
205
206 /// Same as Format(AString&) but allows specifying an external list of arguments instead of
207 /// the internally allocated object, which is returned by methods #GetArgContainer
208 /// and #Reset.
209 ///
210 /// @param args The arguments to be used with formatters.
211 /// @param target An AString that takes the result.
212 /// @return A reference to this formatter to allow concatenated operations.
213 template<typename TAllocator>
215 {
217 return formatLoop( target, args );
218 }
219
220
221 /// Clones and returns a copy of this formatter.
222 ///
223 /// If a formatter is attached to field \alib{format;Formatter::Next}, it is
224 /// cloned as well (recursively).
225 ///
226 /// @returns An object of the same (derived) type and the same custom settings.
227 virtual SPFormatter Clone() =0;
228
229 /// Clones the settings from the given formatter.
230 /// @param reference The formatter to copy settings from.
232 virtual void CloneSettings( Formatter& reference );
233
234 /// Virtual method used to reset internal states.
235 ///
236 /// It is formatter-depended, which state information is reset. As a sample, derived type
237 /// \alib{format;FormatterPythonStyle;FormatterPythonStyle} clears its auto-tab
238 /// and auto-width positions.
239 ///
240 /// The default implementation does nothing.
241 /// @return An internally allocated container of boxes that may be used to collect
242 /// formatter arguments.
243 virtual BoxesMA& Reset() { ALIB_DCS boxes.clear(); return boxes; }
244
245 /// Returns an empty vector of arguments, which can be passed to the format interface.<br>
246 /// Note: This is nothing more than a recycling strategy.
247 /// @return An internally allocated container of boxes that may be used to collect
248 /// formatter arguments.
249 virtual BoxesMA& GetArgContainer() { ALIB_DCS boxes.clear(); return boxes; }
250
251
252 //################################################################################################
253 // Static Interface methods (default formatter)
254 //################################################################################################
255 /// A publicly accessible static singleton instance which is can be freely used.
256 /// Racing conditions in multithreaded applications have to be avoided by locking mutex
257 /// #DefaultLock.
260
261 #if !ALIB_SINGLE_THREADED
262 /// The lock to be set with multithreaded use of #Default.
263 /// If the compiler-symbol \ref ALIB_DEBUG_CRITICAL_SECTIONS is set, this lock will be
264 /// attached to the \alib{lang;DbgCriticalSections} instance in #Default during
265 /// bootstrap.
266 /// Thus, an assertion will be raised if #Default is used without locking this.
267 ///
268 /// \par Availability
269 /// This object is available only if symbol \ref ALIB_SINGLE_THREADED is not set.
270 ///
271 /// @see Chapter \ref alib_threads_intro_assert_locks of the Programmer's Manual of
272 /// module \alib_threads.
275 #endif
276
277 //################################################################################################
278 // Protected methods
279 //################################################################################################
280 protected:
281 /// Virtual method which is invoked with each invocation of #Format.
282 /// The default implementation does nothing.
283 virtual void initializeFormat() {}
284
285 /// The abstract format method that needs to be implemented by descendants.
286 /// Note that parameter \p{startIdx} and the demanded return value together comprise the
287 /// possibility to use more than one formatter in parallel and to perform multiple format
288 /// operations on suitable argument lists. This demands the implementation of this method to
289 /// \b not copy the format string to the \p{target} in the case that no 'escape sequence'
290 /// was found. For further information, see the general documentation of this class.
291 ///
292 /// @param target The %AString that takes the result.
293 /// @param formatString The format string.
294 /// @param args The objects to be used with formatters.
295 /// @param startArgument The first object in \p{args} to convert.
296 ///
297 /// @return The number of args consumed.
298 virtual int format( AString& target,
299 const String& formatString,
300 const BoxesMA& args,
301 int startArgument ) =0;
302
303 /// The format loop implementation. Searches format strings in \p{args} and tests
304 /// if \c this or #Next is capable of processing it.
305 ///
306 /// @param target An AString that takes the result.
307 /// @param args The objects to be used with formatters.
308 /// @return A reference to this formatter to allow concatenated operations.
309 template<typename TAllocator>
311};
312
313#if !DOXYGEN
317#endif // !DOXYGEN
318
319
320inline
322{
324 return formatLoop( target, boxes );
325}
326
327} // namespace alib[::format]
328
329//##################################################################################################
330// Alias types in namespace #alib.
331//##################################################################################################
332/// Type alias in namespace \b alib.
334
335} // namespace [alib]
virtual void initializeFormat()
NumberFormat DefaultNumberFormat
Definition formatter.inl:96
Formatter & FormatArgs(AString &target)
static ALIB_DLL threads::RecursiveLock DefaultLock
Formatter & Format(AString &target, TArgs &&... args)
MonoAllocator allocator
This allocator is (exclusively) used for field boxes.
Definition formatter.inl:70
virtual ALIB_DLL void CloneSettings(Formatter &reference)
virtual SPFormatter Clone()=0
NumberFormat AlternativeNumberFormat
Formatter & formatLoop(AString &target, const boxing::TBoxes< TAllocator > &args)
static ALIB_DLL SPFormatter Default
SharedPtr< Formatter > Next
virtual BoxesMA & GetArgContainer()
virtual int format(AString &target, const String &formatString, const BoxesMA &args, int startArgument)=0
virtual BoxesMA & Reset()
Formatter()
Default Constructor.
AString formatStringBuffer
A buffer used for conversion of the next argument if it is not of a string-type.
Definition formatter.inl:77
Formatter & FormatArgs(AString &target, const boxing::TBoxes< TAllocator > &args)
#define ALIB_DLL
Definition alib.inl:503
#define ALIB_DCS
Definition alib.inl:1392
#define ALIB_EXPORT
Definition alib.inl:497
#define ALIB_DBG(...)
Definition alib.inl:853
#define ALIB_DBG_PREVENT_RECURSIVE_METHOD_CALLS_MEMBER_DECL
Definition alib.inl:1363
#define ALIB_DEBUG_CRITICAL_SECTIONS
Definition prepro.dox.md:43
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
boxing::TBoxes< lang::HeapAllocator > Boxes
Type alias in namespace alib.
Definition boxes.inl:189
strings::TNumberFormat< character > NumberFormat
Type alias in namespace alib.
boxing::TBoxes< PoolAllocator > BoxesPA
Type alias in namespace alib.
Definition boxes.inl:196
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
format::Formatter Formatter
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
Definition box.inl:1149
boxing::TBoxes< MonoAllocator > BoxesMA
Type alias in namespace alib.
Definition boxes.inl:193
containers::SharedPtr< format::Formatter > SPFormatter
Definition formatter.inl:42
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
containers::SharedPtr< T, TAllocator > SharedPtr
Type alias in namespace alib.
void(*)(const Box &self, const String &formatSpec, NumberFormat &nf, AString &target) Signature
Definition formatter.inl:30