I'm working on eliminating
the macros that are generated by liboctave/operators/mk-ops.awk.
Currently, this script generates a set of header files that
contain things like this
// DO NOT EDIT -- generated by mk-ops.awk
#if ! defined (octave_mx_cm_m_h)
#define octave_mx_cm_m_h 1
#include "octave-config.h"
#include "CMatrix.h"
#include "dMatrix.h"
#include "mx-op-decl.h"
MM_BIN_OP_DECLS (ComplexMatrix, ComplexMatrix, Matrix,
OCTAVE_API)
MM_CMP_OP_DECLS (ComplexMatrix, Matrix, OCTAVE_API)
MM_BOOL_OP_DECLS (ComplexMatrix, Matrix, OCTAVE_API)
#endif
to provide declarations of operators for mixed-type operations
on nd-array/matrix/sparse-matrix/vector/scalar objects of
various types (complex, real, integer). It also generates a
corresponding set of source files that look like this
// DO NOT EDIT -- generated by mk-ops.awk
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include "Array-util.h"
#include "mx-cm-m.h"
#include "mx-op-defs.h"
#include "boolMatrix.h"
#include "boolNDArray.h"
#include "CMatrix.h"
MM_BIN_OPS (ComplexMatrix, ComplexMatrix, Matrix)
MM_CMP_OPS (ComplexMatrix, Matrix)
MM_BOOL_OPS (ComplexMatrix, Matrix)
to provide the actual function definitions. My plan is to
* Use templates instead of macros to define the functions.
* Change the script to generate the declarations directly
instead of using macros.
* Preserve the non-template function signatures using inline
functions in the header files. These can be deprecated and
eventually removed. Octave itself will be fixed to use the
templates directly.
* Wrap all the functions in the octave::numeric namespace.
Questions:
* Should the header file that declares the templates also
provide the template definitions, or should we hide those and
only instantiate these templates for the types we care about?
As a coder, I would find it easier to understand if the template and
its definition were in the same file and located proximate to each
other. However, if the template definitions are going to be large
then the classic C++ pattern of declaring the prototype in a .h file
and the implementation in a .cc file would make more sense.
Will the build be faster if
we use extern templates and explicit instantiation of just the
templates we need?
Unknown, but at least this is testable. One way to gauge
things--without testing--would be to roughly calculate the fraction
of templates that we need compared to the total number of
templates. If we are using greater than 80% of the possible
templates then it sort of makes sense to just do them all.
* If we choose explicit instantiation for only the types we
need, should we continue to use a script to generate these files
or should we just move a copy of the generated sources to the
source tree and eliminate the script, adding new variants by
hand? (If the definitions are all in the header and we don't
use explicit instantiation, then we can just eliminate the
source files and script, but compiling/linking might be slower).
Automation is useful if you are going to repeatedly do something.
If that is not the case, why bother? From the sample code at the
top of this e-mail, it seems like new templates would only need to
be written if we add fundamental new types to liboctave. That
strikes me as a pretty infrequent event, and one for which we would
be doing a lot of other coding anyways. Infrequent, but not
impossible; Examples which might require new templates could be
adding support for Matlab duration arrays, categorical arrays, or
tables.
Comments?
How does this fit in with getting the 4.2.0 release out? Should we
revert the character encoding patches that are causing test failures
and other weirdness between Windows and Linux platforms and then
release. We seem to be moving on to development for 4.4 without
actually having taken care of the existing release.
--Rik
|