|  | Home | Libraries | People | FAQ | More | 
Learning how to use Spirit.Karma is really simple. We will start from trivial examples, ramping up as we go.
Let's create a generator that will output a floating-point number:
double_
          Easy huh? The above code actually instantiates a Spirit floating point
          generator (a built-in generator). Spirit has many pre-defined generators
          and consistent naming conventions will help you finding your way through
          the maze. Especially important to note is that things related to identical
          entities (as in this case, floating point numbers) are named identically
          in Spirit.Karma and in Spirit.Qi.
          Actually, both libraries are using the very same variable instance to refer
          to a floating point generator or parser: double_.
        
Now, let's create a generator that will output a line consisting of two floating-point numbers.
double_ << double_
          Here you see the familiar floating-point numeric generator double_ used twice, once for each number.
          If you are used to see the '>>'
          operator for concatenating two parsers in Spirit.Qi
          you might wonder, what's that '<<'
          operator doing in there? We decided to distinguish generating and parsing
          of sequences the same way as the std::stream libraries do: we use operator
          '>>' for input (parsing),
          and operator '<<' for output
          (generating). Other than that there is no significant difference. The above
          program creates a generator from two simpler generators, glueing them together
          with the sequence operator. The result is a generator that is a composition
          of smaller generators. Whitespace between numbers can implicitly be inserted
          depending on how the generator is invoked (see below).
        
| ![[Note]](../../../images/note.png) | Note | 
|---|---|
| When we combine generators, we end up with a "bigger" generator, but it's still a generator. Generators can get bigger and bigger, nesting more and more, but whenever you glue two generators together, you end up with one bigger generator. This is an important concept. | 
Now, creating output for two numbers is not too interesting. Let's create a generator that will output zero or more floating-point numbers in a row.
*double_
          This is like a regular-expression Kleene Star. We moved the * to the front for the same reasons we did
          in Spirit.Qi: we must work with the syntax rules of
          C++. But if you know regular expressions (and for sure you remember those
          C++ syntax rules) it will start to look very familiar in a matter of a
          very short time.
        
Any expression that evaluates to a generator may be used with the Kleene Star. Keep in mind, though, that due to C++ operator precedence rules you may need to put the expression in parentheses for complex expressions. As above, whitespace can be inserted implicitly in between the generated numbers, if needed.
We follow the lead of Spirit.Qi's warming up section and will create a generator that produces a comma-delimited list of numbers.
double_ << *(lit(',') << double_)
          Notice lit(','). It is
          a literal character generator that simply generates the comma ','. In this case, the Kleene Star is modifying
          a more complex generator, namely, the one generated by the expression:
        
(lit(',') << double_)
Note that this is a case where the parentheses are necessary. The Kleene Star encloses the complete expression above, repeating the whole pattern in the generated output zero or more times.
          We're done with defining the generator. All that's left is to invoke the
          generator to do its work. For now, we will use the generate_delimited
          function. One overload of this function accepts four arguments:
        
          While comparing this minimal example with an equivalent parser example
          we notice a significant difference. It is possible (and actually, it makes
          a lot of sense) to use a parser without creating any internal representation
          of the parsed input (i.e. without 'producing' any data from the parsed
          input). Using a parser in this mode checks the provided input against the
          given parser expression allowing to verify whether the input is parsable.
          For generators this mode doesn't make any sense. What is output generation
          without generating any output? So we always will have to supply the data
          the output should be generated from. In our example we supply a list of
          double numbers as the last
          parameter to the function generate_delimited
          (see code below).
        
          In this example, we wish to delimit the generated numbers by spaces. Another
          generator named space is
          included in Spirit's repertoire of predefined generators. It is a very
          trivial generator that simply produces spaces. It is the equivalent to
          writing lit(' '), or simply
          ' '. It has been implemented
          for similarity with the corresponding predefined space
          parser. We will use space
          as our delimiter. The delimiter is the one responsible for inserting characters
          in between generator elements such as the double_
          and lit.
        
Ok, so now let's generate (for the complete source code of this example please refer to num_list1.cpp).
template <typename OutputIterator> bool generate_numbers(OutputIterator& sink, std::list<double> const& v) { using karma::double_; using karma::generate_delimited; using ascii::space; bool r = generate_delimited( sink, // destination: output iterator double_ << *(',' << double_), // the generator space, // the delimiter-generator v // the data to output ); return r; }
| ![[Note]](../../../images/note.png) | Note | 
|---|---|
| 
            You might wonder how a  | 
          The generate function returns true
          or false depending on the
          result of the output generation. As outlined in different places of this
          documentation, a generator may fail for different reasons. One of the possible
          reasons is an error in the underlying output iterator (memory exhausted
          or disk full, etc.). Another reason might be that the data doesn't match
          the requirements of a particular generator.
        
| ![[Note]](../../../images/note.png) | Note | 
|---|---|
| 
             
            The careful reader may notice that the generator expression has  
            The problem with omitting the  | 
          Note that we inlined the generator directly in the call to generate_delimited. Upon calling this
          function, the expression evaluates into a temporary, unnamed generator
          which is passed into the generate_delimited
          function, used, and then destroyed.
        
Here, we chose to make the generate function generic by making it a template, parameterized by the output iterator type. By doing so, it can put the generated data into any STL conforming output iterator.