Boost logo

Boost :

From: Doug Gregor (gregod_at_[hidden])
Date: 2001-01-13 20:38:11


On Saturday 13 January 2001 03:56, you wrote:
> On Fri, 12 Jan 2001, Doug Gregor wrote:
> gregod>
> gregod> Operators are all mapped to classes, and identity elements
> gregod> will be mapped to integers. To state that integers form an
> gregod> Abelian group over addition, we would have:
> gregod> AbelianGroup<int, plus, 0, negate, minus>. There is a
> gregod> mapping that allows us to take the domain (int) and the
> gregod> IdentityID (0) and get the actual value (0) at run-time
> gregod> when it is needed.
>
> This is what the "literals" tables are for? Could you give an example of
> how this works.

Yes, and yes. The template class "LiteralTable" (parameterized based on the
type of literal it contains) has a static data member "literals". The
literals member is an array containing the literal values - the index of each
value is the integer ID representing that value.

Here is an example literal table for the float type:
template<> float LiteralTable<float>::literals[] = { 0.0f, 1.0f };

This creates the mappings ID(float, 0) <-> 0.0f and ID(float, 1) <-> 1.0f.

This is slightly more interesting for user-defined types. Take for instance a
matrix class parameterized by the number of rows and columns, along with the
element type:

template<typename T, int Rows, int Cols>
class Matrix
{
public:
  enum MatrixType { zero, identity };
  Matrix(MatrixType t)
  // ...
};

The "literals" array for this type could be:

template<typename T, int N>
Matrix<T, N, N> LiteralTable< Matrix<T, N, N> >::literals[] = {
        Matrix<T, N, N>(Matrix<T, N, N>::zero),
        Matrix<T, N, N>(Matrix<T, N, N>::identity)
};

Which lets the ID(Matrix<T, N, N>, 0) <-> the NxN zero matrix and
ID(Matrix<T, N, N>, 1) <-> the NxN identity matrix.

For reference, an "identity" function for an operation Op on type Domain
could be written as:

template<typename Op, typename Domain>
inline Domain identity()
{
  typedef GeneralBinaryOp<Op, Domain, Domain, Domain> OpType;
  return identity(typename GetIdentity<OpType>::id());
}

template<typename Domain, int ID>
inline Domain identity(Expr< Literal<Domain, ID> >)
{
  return LiteralTable<Domain>::literals[ID];
}

So, for instance, identity<plus, float>() would return 0.0f.

        Doug Gregor
        gregod_at_[hidden]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk