ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
PropertyFormatters< TFormattable, TVariables > Class Template Reference

Description:

template<typename TFormattable, typename TVariables>
class alib::lang::format::PropertyFormatters< TFormattable, TVariables >

Introduction

This template class provides a map of PropertyFormatter objects that use format strings which are defined by variables of a Configuration.

The use case is about having different versions of how an object is formatted and to have these versions configurable to end users through the ALib configuration system.

Sample

The concept is best explained by a code sample. From the documentation of class PropertyFormatter, we are using the sample setup:

enum class Hobbies
{
Hacking,
FineArts,
};
struct Person
{
String Name;
int Age;
Hobbies Hobby;
};
namespace
{
Box getName ( const Box& p, AString& ) { return p.Unbox<Person*>()->Name; }
Box getAge ( const Box& p, AString& ) { return p.Unbox<Person*>()->Age; }
Box getHobby ( const Box& p, AString& ) { return p.Unbox<Person*>()->Hobby == Hobbies::Hacking
? A_CHAR("hacking") : A_CHAR("fine arts") ; }
}
{
{ A_CHAR("name") , 1, getName },
{ A_CHAR("age") , 1, getAge },
{ A_CHAR("hobby") , 1, getHobby },
};

Three different output formats, Short, Default and All should be supported We define an enumeration type for this purpose and use macro ALIB_ENUMS_ASSIGN_RECORD to equip the enumeration with ALib Enum Records of type Declaration. In addition, macro ALIB_RESOURCED is used to announce that the record data is defined using resourced string data.

enum class PersonFormats
{
Short,
All
};
ALIB_RESOURCED( PersonFormats, &alib::BASECAMP.GetResourcePool(),
alib::BASECAMP.ResourceCategory, "PersonFormats" )

The following piece of code is to be performed during bootstrapping. We take the freedom to use the resource pool of module BaseCamp:

// Enum records for enum class "PersonFormats"
"PersonFormats", A_CHAR( "0,FORMATS/SHORT" "," "S" ","
"1,FORMATS/DEFAULT" "," "S" ","
"2,FORMATS/ALL" "," "S" ),
// Built-in default values for the variables
"PersonFormats_D0", A_CHAR( "{@name}") ,
"PersonFormats_D1", A_CHAR( "{@name} ({@age})") ,
"PersonFormats_D2", A_CHAR( "{@name} aged {@age} loves {@hobby}" ),
// Variable comments. These are written for example to an INI-file if the application
// fetches default values at the end of the process. In this sample, all variables share
// the same comment.
"PersonFormats_C0", A_CHAR( "Short output format for lists of \"Persons\"." ),
"PersonFormats_C1", A_CHAR( "Default output format for lists of \"Persons\"." ),
"PersonFormats_C2", A_CHAR( "Verbose output format for lists of \"Persons\"." ),
nullptr // End marker für method BootstrapBulk (must be given!)
);
Note
The default value and variable comment string can be saved when we write back the variables to a configuration file. This hints users to the fact that the output format is changeable, i.e., when they open an INI-file. See chapter 7.3 Built-in Class IniFileFeeder of the Programmer's Manual of camp ALib Configuration for information about how to write built-in default variables like this to an external configuration file.

In the next phase of bootstrapping, our enumeration records have to be initialized from the resource pool:

With this in place, the PropertyFormatters can be created and method Format can be used:

alib::PropertyFormatters<Person, PersonFormats> PersonFormatterMap( PersonCallbacks,
alib::BASECAMP.GetConfig() );

But we're still not fully done yet: The next goal is to have a lightweight object that is "appendable" to objects of class AString. Such object is given with template type PropertyFormatterMapAppendable. It is a simple helper-struct that holds a reference to the formatter map, the format enumeration value and the object to format.
We define a shortcut to the type with the right template arguments in place:

using FMTPerson= alib::lang::format::PropertyFormatterMapAppendable<Person, PersonFormats>;

Now, we are set and can start using the formatter:

// Our data objects
Person sue= { A_CHAR("Sue") , 28, Hobbies::Hacking };
Person john= { A_CHAR("John"), 35, Hobbies::Hacking };
// format the two data objects
AString target;
target << FMTPerson( PersonFormatterMap, PersonFormats::Short, sue ) << NEW_LINE;
target << FMTPerson( PersonFormatterMap, PersonFormats::All, john ) << NEW_LINE;
std::cout << target;

Running the code above produces the following output:

Sue
John aged 35 loves hacking

To make the code even shorter, macros may be used:

// Define custom macros
#define FMT_PERSON(o,p) FMTPerson( PersonFormatterMap, o , p )
#define FMT_PERSON_DEFAULT(p) FMTPerson( PersonFormatterMap, PersonFormats::Default, p )
#define FMT_PERSON_SHORT(p) FMTPerson( PersonFormatterMap, PersonFormats::Short , p )
#define FMT_PERSON_ALL(p) FMTPerson( PersonFormatterMap, PersonFormats::All , p )
// Using the macros
target << FMT_PERSON( PersonFormats::Short, sue ) << NEW_LINE;
target << FMT_PERSON_SHORT( sue ) << NEW_LINE;
target << FMT_PERSON_DEFAULT( sue ) << NEW_LINE;
target << FMT_PERSON_ALL( sue ) << NEW_LINE;
std::cout << target;

The output is:

Sue
Sue
Sue (28)
Sue aged 28 loves hacking

Using The Appendable With Formatters

The sample above showcased how to append a lightweight object of helper-class PropertyFormatterMapAppendable to objects of class AString. A final step is to define the boxing interface FAppend to make boxed objects of our helper-type applicable. As the type itself is already appendable, we can use a built-in simple macro for that:

As described in the Programmer's Manual of module ALib Boxing, such interface definition should be done only once and be placed in the bootstrap section of a process.

With this, using formatters in combination with our helper-struct works fine:

{ALIB_LOCK_RECURSIVE_WITH(Formatter::DefaultLock)
Formatter::Default->Format( target,
"The person is: {}",
FMT_PERSON_DEFAULT( john ) );
}
std::cout << target << endl;

This code produces the following output.

The person is: John (35)

Module Dependencies

This class is only available if module ALib Configuration is included in the ALib Distribution.

Reference Documentation

Exceptions
alib::lang::format::FMTExceptions::MissingConfigurationVariable
Template Parameters
TFormattableThe type that is formatted.
TVariablesThe enumeration of variables which defines the format strings.

Definition at line 130 of file propertyformatters.hpp.

#include <propertyformatters.hpp>

Collaboration diagram for PropertyFormatters< TFormattable, TVariables >:
[legend]

Public Field Index:

SPFormatter Formatter
 The formatter (as given in the constructor).
 

Public Method Index:

 PropertyFormatters (typename PropertyFormatter::TCallbackTable &callbackTable, config::Configuration &configuration, SPFormatter formatter=nullptr)
 
 ~PropertyFormatters ()
 Destructor. Deletes the PropertyFormatters which got created.
 
void Format (AString &target, TVariables option, TFormattable &formattable)
 

Protected Field Index:

PropertyFormatter::TCallbackTablecallbacks
 The callback table for the property formatters (as given in the constructor).
 
config::Configurationconfig
 The configuration used to load (and store the default) format strings from.
 
std::unordered_map< TVariables, PropertyFormatter * > formatters
 The map of formatters.
 

Field Details:

◆ callbacks

template<typename TFormattable , typename TVariables >
PropertyFormatter::TCallbackTable& callbacks
protected

The callback table for the property formatters (as given in the constructor).

Definition at line 134 of file propertyformatters.hpp.

◆ config

template<typename TFormattable , typename TVariables >
config::Configuration& config
protected

The configuration used to load (and store the default) format strings from.

Definition at line 137 of file propertyformatters.hpp.

◆ Formatter

template<typename TFormattable , typename TVariables >
SPFormatter Formatter

The formatter (as given in the constructor).

Definition at line 144 of file propertyformatters.hpp.

◆ formatters

template<typename TFormattable , typename TVariables >
std::unordered_map<TVariables, PropertyFormatter*> formatters
protected

The map of formatters.

Definition at line 140 of file propertyformatters.hpp.

Constructor(s) / Destructor Details:

◆ PropertyFormatters()

template<typename TFormattable , typename TVariables >
PropertyFormatters ( typename PropertyFormatter::TCallbackTable & callbackTable,
config::Configuration & configuration,
SPFormatter formatter = nullptr )
inline

Constructor storing arguments in fields. All variables are declared within the given configuration and defined with their default values given with their declaration records (associated with TVariables) and thus - if exported to a write-enabled external configuration source like for example IniFileFeeder - can be noted by the end-user to be configurable.

Parameter formatter defaults to nullptr, which causes this constructor to create a clone of the static formatter given with Formatter::Default. Note, that this is in contrast to the similar parameter of class PropertyFormatter, which uses the default formatter itself in the case that nullptr is provided. The rationale behind creating a copy is that it is quite likely that the PropertyFormatter objects created here are used nested within other format operations. This is especially true with the use of helper struct PropertyFormatterMapAppendable. Now, nested formatting must not be done with the same formatter object.

Parameters
callbackTableThe callback table as specified with PropertyFormatter::TCallbackTable.
configurationThe configuration to load the format strings from (and to store the default values defined by the enum record of TVariables).
formatterThe underlying formatter. Used for construction of PropertyFormatters.
Defaults to nullptr which denotes to create a copy of the static formatter given with Formatter::Default.

Definition at line 173 of file propertyformatters.hpp.

Here is the call graph for this function:

◆ ~PropertyFormatters()

template<typename TFormattable , typename TVariables >
~PropertyFormatters ( )
inline

Destructor. Deletes the PropertyFormatters which got created.

Definition at line 191 of file propertyformatters.hpp.

Method Details:

◆ Format()

template<typename TFormattable , typename TVariables >
void Format ( AString & target,
TVariables option,
TFormattable & formattable )
inline

Chooses or - if not yet available - creates the right PropertyFormatter and invokes its method Format.

Parameters
targetThe target string to write into.
optionThe user-defined formatting option.
formattableThe custom object which is passed to the callback methods to collect the formatter arguments.

Definition at line 204 of file propertyformatters.hpp.

Here is the call graph for this function:

The documentation for this class was generated from the following file: