Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Click here to view the latest version of this page.
PrevUpHomeNext

Karma Confix Generator

Description

The Spirit.Karma confix generator is a generator directive component allowing to embed any generated ouput inside an opening (a prefix) and a closing (a suffix). A simple example is a C comment: /* This is a C comment */ which can be generated using the confix generator as: confix("/*", "*/")["This is a C comment"]. The general syntax for using the confix is:

confix(prefix, suffix)[subject]

which results in generating a sequence equivalent to

prefix << subject << suffix

Using the confix component instead of the explicit sequence has the advantage of being able to encapsulate the prefix and the suffix into a separate generator construct. The following code snippet illustrates the idea:

// Define a metafunction allowing to compute the type of the confix()
// construct
namespace traits
{
    using namespace boost::spirit;

    template <typename Prefix, typename Suffix = Prefix>
    struct confix_spec
      : spirit::result_of::terminal<repository::tag::confix(Prefix, Suffix)>
    {};
};

// Define a helper function allowing to create a confix() construct from 
// arbitrary prefix and suffix generators
template <typename Prefix, typename Suffix>
typename traits::confix_spec<Prefix, Suffix>::type
confix_spec(Prefix const& prefix, Suffix const& suffix)
{
    using namespace boost::spirit;
    return repository::confix(prefix, suffix);
}

// Define a helper function to  construct a HTML tag from the tag name
inline typename traits::confix_spec<std::string>::type
tag (std::string const& tagname)
{
    return confix_spec("<" + tagname + ">", "</" + tagname + ">");
}

// Define generators for different HTML tags the HTML tag
typedef traits::confix_spec<std::string>::type ol = tag("ol");      // <ol>...</ol> 
typedef traits::confix_spec<std::string>::type li = tag("li");      // <li>...</li> 

Now, for instance, the above definitions allow to generate the HTML 'ol' tag using a simple: ol["Some text"] (which results in <ol>Some text</ol>).

Header
// forwards to <boost/spirit/repository/home/karma/directive/confix.hpp>
#include <boost/spirit/repository/include/karma_confix.hpp>
Synopsis
confix(prefix, suffix)[subject]
Parameters

Parameter

Description

prefix

The generator construct to use to format the opening (the prefix). The prefix is the part generated before any output as generated by the subject.

suffix

The generator construct to use to format the ending (the suffix). The suffix is the part generated after any output as generated by the subject.

subject

The generator construct to use to format the actual output in between the prefix and suffix parts.

All three parameters can be arbitrary complex generators themselves.

Attribute

The confix component exposes the attribute type of its subject as its own attribute type. If the subject does not expose any attribute (the type is unused_type), then the confix does not expose any attribute either.

a: A --> confix(p, s)[a]: A
[Note] Note

This notation is used all over the Spirit documentation and reads as: Given, a is generator, and A is the type of the attribute of generator a, then the type of the attribute exposed by confix(p, s)[a] will be A as well.

Example

The following example shows simple use cases of the confix generator. We will illustrate its usage by generating different comment styles and a function prototype (for the full example code see here: confix.cpp)

Prerequisites

In addition to the main header file needed to include the core components implemented in Spirit.Karma we add the header file needed for the new confix generator.

#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/repository/include/karma_confix.hpp>

To make all the code below more readable we introduce the following namespaces.

using namespace boost::spirit;
using namespace boost::spirit::ascii;
using boost::spirit::repository::confix;

Generating Different Comment Styles

We will show how to generate different comment styles. First we will generate a C++ comment:

// C++ comment
std::cout <<
    karma::format_delimited(
        confix("//", eol)[string],            // format description
        space,                                // delimiter
        "This is a comment"                   // data
    ) << std::endl;

This code snippet will obviouly generate // This is a comment \n . Similarily generating a 'C'-style comment proves to be straightforward:

// C comment
std::cout <<
    karma::format_delimited(
        confix("/*", "*/")[string],           // format description
        space,                                // delimiter
        "This is a comment"                   // data
    ) << std::endl;

which again will generate /* This is a comment */ .

Generating a Function Prototype

Generating a function prototype given a function name a vector or parameter names is simple as well:

// Generate a function call with an arbitrary parameter list
std::vector<std::string> parameters;
parameters.push_back("par1");
parameters.push_back("par2");
parameters.push_back("par3");

std::cout <<
    karma::format(
        string << confix('(', ')')[string % ','],   // format description
        "func",                                     // function name
        parameters                                  // parameter names
    ) << std::endl;

which generates the expected output: func(par1,par2,par3).


PrevUpHomeNext