ALib C++ Library
Library Version: 2312 R0
Documentation generated by doxygen
Public Fields | Public Methods | Protected Fields | List of all members
PropertyFormatters< TFormattable, TVariable > Class Template Reference

#include <propertyformatters.hpp>

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

Class Description

template<typename TFormattable, typename TVariable>
class aworx::lib::text::PropertyFormatters< TFormattable, TVariable >


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 VariableDecl. In addition, macro ALIB_RESOURCED is used to announce that the record data is defined using resourced string data.

enum class PersonFormats
{
Short,
Default,
All
};
ALIB_RESOURCED( PersonFormats, &aworx::ALIB.GetResourcePool(),
aworx::ALIB.ResourceCategory, "PersonFormats" )

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

// Enum records for enum class "PersonFormats"
"PersonFormats", A_CHAR( "0,FORMATS," "SHORT" ",,," ","
"1,FORMATS," "DEFAULT" ",,," ","
"2,FORMATS," "ALL" ",,," ),
// 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 would 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 Configuration::FetchFromDefault 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:

aworx::PropertyFormatters<Person, PersonFormats> PersonFormatterMap( PersonCallbacks,
aworx::ALIB.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:

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 ) << NewLine();
target << FMTPerson( PersonFormatterMap, PersonFormats::All, john ) << NewLine();
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 ) << NewLine();
target << FMT_PERSON_SHORT( sue ) << NewLine();
target << FMT_PERSON_DEFAULT( sue ) << NewLine();
target << FMT_PERSON_ALL( sue ) << NewLine();
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 namespace documentation of module ALib Boxing, such interface definition should be done only once and be placed in the bootstrap section of a software.

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

->Format( target, "The person is: {}", FMT_PERSON_DEFAULT( john ) )
.Release();
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
aworx::lib::text::Exceptions::MissingConfigurationVariable
Template Parameters
TFormattableThe type that is formatted.
TVariableThe enumeration of variables which defines the format strings.

Definition at line 141 of file propertyformatters.hpp.

Public Fields

SPFormatter Formatter
 

Public Methods

 PropertyFormatters (typename PropertyFormatter::TCallbackTable &callbackTable, config::Configuration &configuration, SPFormatter formatter=nullptr)
 
 ~PropertyFormatters ()
 
void Format (AString &target, TVariable option, TFormattable &formattable)
 

Protected Fields

PropertyFormatter::TCallbackTablecallbacks
 
config::Configurationconfig
 
std::unordered_map< TVariable, PropertyFormatter * > formatters
 
Variable tempVar
 

Constructor & Destructor Documentation

◆ PropertyFormatters()

PropertyFormatters ( typename PropertyFormatter::TCallbackTable callbackTable,
config::Configuration configuration,
SPFormatter  formatter = nullptr 
)
inline

Constructor storing arguments in fields. All default values of the variables are stored in the configuration and thus - if the configuration is write enabled - 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 formatter returned by Formatter::GetDefault. 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 TVariable).
formatterThe underlying formatter. Used for construction of PropertyFormatters.
Defaults to nullptr which denotes to create a copy of the formatter returned by Formatter::GetDefault.

Definition at line 187 of file propertyformatters.hpp.

◆ ~PropertyFormatters()

~PropertyFormatters ( )
inline

Destructor. Deletes the PropertyFormatters which got created.

Definition at line 205 of file propertyformatters.hpp.

Member Function Documentation

◆ Format()

void Format ( AString target,
TVariable  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 220 of file propertyformatters.hpp.

Member Data Documentation

◆ callbacks

PropertyFormatter::TCallbackTable& callbacks
protected

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

Definition at line 145 of file propertyformatters.hpp.

◆ config

config::Configuration& config
protected

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

Definition at line 148 of file propertyformatters.hpp.

◆ Formatter

The formatter (as given in the constructor).

Definition at line 157 of file propertyformatters.hpp.

◆ formatters

std::unordered_map<TVariable, PropertyFormatter*> formatters
protected

The map of formatters

Definition at line 151 of file propertyformatters.hpp.

◆ tempVar

Variable tempVar
protected

A temporary variable to be reused (allocate once pattern).

Definition at line 154 of file propertyformatters.hpp.


The documentation for this class was generated from the following file:
aworx::lib::text::PropertyFormatterMapAppendable
Definition: propertyformatters.hpp:263
aworx::lib::text::Formatter::AcquireDefault
static SPFormatter AcquireDefault(const NCString &dbgFile, int dbgLine, const NCString &dbgFunc)
Definition: formatter.hpp:356
aworx::String
lib::strings::TString< character > String
Type alias in namespace aworx.
Definition: strings/fwds.hpp:81
aworx::lib::enums::EnumRecords::Bootstrap
static void Bootstrap(TEnum element, TArgs &&... args) noexcept
aworx::Box
lib::boxing::Box Box
Type alias in namespace aworx.
Definition: boxing/fwds.hpp:40
aworx::AString
lib::strings::TAString< character > AString
Type alias in namespace aworx.
Definition: strings/fwds.hpp:135
aworx::lib::text::PropertyFormatters< TFormattable, TOptionEnum >
aworx::ALIB
lib::ALibDistribution ALIB
Definition: distribution.cpp:125
ALIB_BOXING_BOOTSTRAP_REGISTER_FAPPEND_FOR_APPENDABLE_TYPE
#define ALIB_BOXING_BOOTSTRAP_REGISTER_FAPPEND_FOR_APPENDABLE_TYPE(TAppendable)
Definition: functions.inl:502
aworx::lib::resources::ResourcePool::BootstrapBulk
virtual void BootstrapBulk(const nchar *category,...)=0
A_CHAR
#define A_CHAR(STR)
ALIB_CALLER_PRUNED
#define ALIB_CALLER_PRUNED
Definition: tools.hpp:71
ALIB_ENUMS_ASSIGN_RECORD
#define ALIB_ENUMS_ASSIGN_RECORD(TEnum, TRecord)
Definition: records.hpp:769
aworx::lib::boxing::Box::Unbox
const TUnboxable Unbox() const
aworx::NewLine
ALIB_CPP14_CONSTEXPR CString NewLine()
Definition: cstring.hpp:533
aworx::lib::text::PropertyFormatter::TCallbackTable
std::vector< IdentifierEntry > TCallbackTable
Definition: propertyformatter.hpp:229
ALIB_RESOURCED
#define ALIB_RESOURCED(T, ResPool, ResCategory, ResName)
Definition: resources.hpp:638
aworx::lib::config::VariableDecl
Definition: variabledecl.hpp:109
aworx::lib::Module::GetResourcePool
ResourcePool & GetResourcePool()
Definition: module.hpp:435