- The
*containers*specify the internal representation.

- They provide methods or functions for accessing, scanning, creating, transforming this representation, often through iterators.

linalg::rep1d<C>; linalg::rep2d<C>; lapack::rep2d<C>; linalg::sparse2d<C>; linalg::toeplitz<C>; bezier::rep1d<C>; ...

- The containers are attached to
*domains*(implemented as namespaces):

linalg; lapack; upol; bezier; ...

- The domains allow to define (by an external user) specialized algorithms for given containers (through the scope name mechanism) or by derivation and redefinition of functions.

- They are open and thus can be extended easily.

namespace lapack { template <class C> void solve(LU,linalg::rep1d<C> & x, const rep2d<C> & A, const linalg::rep1d<C> & b) {...}; }

defines a specialized `solve`

function for the containers of type `lapack::rep2d<C>`

.

- They provide collections of generic implementations which apply to a ``category'' of objects.

- A minimal set of constraints is imposed on the parameters of these generic functions, for containers belonging to a same category.

- They can be combined or extended naturally.

VECTOR, MATRIX, UPOLDAR, MPOLDST ...

These modules are available in files with the suffixe `.m`

.

- They specify how to manipulate or to see the containers as mathematical objects.

- The internal data is available, via the method
`rep()`

.

- They are usualy classes, parameterised by the container type
`R`

and sometimes by trait classes which precise the implementation:

VectDse<double,linalg::rep1d<C> >; //equivalently VectDse<double>;

- The implementations of these views are based on modules.

template<class C, class R> UPolDse<C,R> operator*(const UPolDse<C,R>& a, const UPolDse<C,R>& b) { UPolDse<C,R> r; using UPOLDSE::mul; mul(r.rep(),a.rep(),b.rep()); return r; }