The Callback Interface

A TPT callback must be declared in the form:

	bool mycallback(std::ostream& os, TPT::Object& params);

Note that the first parameter is a reference to an output stream. All communication between the callback and the LibTPT parser are handled with streams. So, to have the callback print a message would look like:

	os << "My Message";

The second parameter is of type TPT::Object, which represents a generic object in LibTPT. The object may hold a type of scalar, array, or hash. The params variable passed to the callback is guaranteed to hold an array, but that array may hold scalars, arrays, hashes, or any combination of those types, depending on how the callback was called from within the TPT template. The enumerated types of object available to a callback function are TPT::Object::type_scalar, TPT::Object::type_array, and TPT::Object::type_hash, with the corresponding access methods TPT::Object::scalar(), TPT::Object::array(), and TPT::Object::hash(). If a call to the incorrect access method is made, an exception will be thrown. The parser does its best to handle these exceptions without interrupting the template translation.

When accessing a member of Object::array() or Object::hash(), be sure to use the get() method to get the member's real address. Member of Object arrays and hashes are stored in a smart pointer to ensure proper memory management. Refer to the example below for how to properly access a member of an Object array.

As mentioned earlier, TPT does not have any built-in functionality for dealing with floating point numbers. Suppose you needed a function to sum a list of floating point numbers populated into variables from a database or user form. See Example 4.1 for an example of what the code might look like for a floating point summation function.

Example 4.1. A callback example: @fsum()

#include <libtpt/tpt>
#include <ostream>

// Define a function for summing floating point numbers
bool fsum(std::ostream& os, TPT::Object& params)
{
	// Make a reference to the array for easier typing.
	TPT::Object::ArrayType& pl = params.array();
	// initialize the work variable
	double work=0;

	// Set up iterators and loop.
	TPT::Object::ArrayType::const_iterator it(pl.begin()), end(pl.end());
	for (; it != end; ++it)
	{
		// Make a reference to the object for easier typing.
		TPT::Object& obj = *(*it).get();
		// Only add the object if it is a scalar.
		if (obj.gettype() == TPT::Object::type_scalar)
			work+= atof(obj.scalar().c_str());
		else
			return true; // expected a scalar!
	}
	os << work;
	return false;
}

This callback is then registered with the TPT::Parser::addfunction() method.

	TPT::Parser p(buf);
	p.addfunction("fsum", &fsum);
		

The above example demonstrates how simple it is to loop through an array of scalar examples. As an exercise, modify fsum to be able to process sub-arrays of floats.