@chapsummary
When you want a @code{std::string}, use @code{vcl_string}.
@endchapsummary

The job of vcl is to fix your compiler.  C++ is not just a language; the
standard also includes an extensive library of classes and functions, which
make ISO C++ a powerful and useful tool for building computer programs.
Unfortunately, few C++ compilers available in 2001 have a bug-free
implementation of the standard, so we have to supply our own bug fixes.

To give an example of the type of problems that vcl fixes, here are a few
interpretations from the standard which have been observed in some well
known vendors' libraries.  Many are entirely within the letter of the law,
but remain prone to introduce confusion.

On one compiler, @code{<iostream>} and @code{<iostream.h>} refer to
entirely different stream libraries, which may not be linked together.
Therefore every file in the program must use the same header.  For us, the
@code{<iostream>} version is appropriate, but of course, not all of the
unix compilers support its use.  The solution is for every @vxl{x} program
to include @code{<vcl_iostream.h>}.  In this way, we can maintain
consistency between the many compilers, and if we ever do need to use
another stream library, we can make the switch in one place.
Thus rule one is
@quotation
Wherever you wish to include standard header @code{<foo>}, you should
include @code{<vcl_foo.h>} instead.
@end quotation

Some compilers place STL classes such as @code{vector<>} and @code{string} in
namespace @code{std::}, some don't.  Yet others place them there, but do not
implement namespaces properly.  Therefore, it is very difficult to write
portable code because sometimes one must say @code{std::vector}, sometimes
one must use @code{vector}.  Again, we need a way which works on all
systems.  We could try to insert @code{using namespace std;} or @code{using
std::vector} commands throughout the program, but (a) this is not
considered good C++, and (b) it doesn't work anyway.

The low-tech solution is simply to prefix each standard identifier with
@code{vcl_}, so that @code{vcl_vector} works everywhere.  And this is
what @vxl{x} does, when you include @code{<vcl_vector.h>}.  Thus, safe
programmers prefix @emph{everything} in the standard library with
@code{vcl_}.
@quotation
Wherever you wish to use standard class or function @code{foo}, you should
write @code{vcl_foo} instead.
@end quotation
This may seem excessive, but one gets used to it very quickly, and it
quickly indicates to novice C++ programmers which functions are from the
standard library.  You might think that the designers of @vxl{x} would have
been clever enough to avoid the vcl_ prefix by using fancy compiler flags,
and many #defines.  However, that way lies madness---trying to confuse a
C++ compiler always rebounds on one.

Also, when time comes when all compilers will implement ANSI STL classes
in a consistent way, it's very easy to `perl away' the @code{vcl_} prefixes,
or replace them with @code{std::}; it's much more difficult, if not impossible,
to insert @code{std::} prefixes when there are no @code{vcl_} prefixes.

@section Example
This program is exemplary.  It shows how every identifier in the ISO
library has been prefixed by @code{vcl_}.  It may look like extreme
overkill, but it works, and can be made to work on all compilers we've
seen.
@example
#include <vcl_string.h>    // string
#include <vcl_iostream.h>  // cout
#include <vcl_vector.h>    // vector
#include <vcl_algorithm.h> // copy
#include <vcl_iterator.h>  // ostream_iterator

int main()
@{
  vcl_vector<vcl_string> strings;
  strings.push_back("Hello, ");
  strings.push_back("World.");
  vcl_copy(strings.begin(), strings.end(),
           vcl_ostream_iterator<vcl_string>(vcl_cout));
  return 0;
@}
@end example
The alternative is somewhat scary.  It begins
@smallexample
#if defined(_WIN32) || (defined(__SUNPRO_CC) && (__SUNPRO_CC + 0) >= 0x500)
#include <string>
#else
#include ...
@end smallexample

This document has little more to say about the contents of VCL---a book on
C++ should describe it better than we can.  However, it is important to
note that nothing more can go in there.  If it's not in the standard, it's
not in VCL.  Remember, VCL is full, nothing else can go in there.  It
cannot for example be ``helpfully'' modified, Microsoft-style, to send
standard error to a window (but see also @code{vul_redirector}).


@comment fsm
@section Macros and standard C++

The C++ ISO standard library headers include the functionality of the C ISO standard
library headers.  For example, the declarations found in @code{<stdlib.h>} can be
found in @code{<cstdlib>} but in namespace @code{std::}.  This means that functions
like @code{printf()} should be called using @code{std::printf()} instead; omitting
the @code{std::} is wrong and won't work if the compiler is truly conforming.  The
exception to this (see @code{[C.2.3]} in the standard) is those names from ISO C
which are actually macros.  The following is an incomplete list:

@itemize @bullet
@item assert
@item setjmp
@item NULL
@item errno
@item stdin, stdout, stderr
@item va_arg, va_start, va_end
@end itemize

For example, the following code is the correct way to use C streams in VXL:
@smallexample
#include <vcl_cstdio.h>
#include <vcl_cassert.h>

void f(char const *file_name)
@{
  assert(file_name);
  vcl_FILE *fp = vcl_fopen(file_name, "r");
  if (! fp) @{
    vcl_fprintf(stderr, "failed to open %s for reading.\n", file_name);
    vcl_abort();
  @}
  ... other stuff ...
@}
@end smallexample
Note that it uses @code{assert}, @code{stderr} and not @code{vcl_assert}, @code{vcl_stderr}
even though it uses @code{vcl_fprintf}, @code{vcl_abort}.  This may seem complicated and
hard to remember, but it isn't the fault of VCL.  If your compiler were strictly conformant
you would still have to use @code{std::fprintf} and you couldn't use @code{std::stderr}.


@comment fsm
@anchor{VCL_Requirements}
@section Which parts of standard C++ may be used in VXL?


Eventually the answer to this will be "all parts" but until compilers
catch up with the language standard, the answer is "all but the following":

@itemize @bullet
@item run-time type information (RTTI) in core libraries.
@item exceptions in core libraries.
@item nested classes (not supported very well by MSVC)
@item wide characters (not supported by FreeBSD).
@item member templates (not supported by SGI CC 7.2.x).
@item partial template specializations (not supported by SGI CC 7.2.x).
@item non-type parameters in function templates (not supported by SunPro 5.0).
@item default template parameters which depend on previous template parameters.
@end itemize

Of course, if you are just using VXL for your own purposes you may use whatever
C++ constructs you like, you just can't put them in the core VXL libraries.

The justification for banning certain things in core libraries is to encourage
the adoption of the core by reducing the possibility of porting problems.
The justification for allowing it for Level 2 and greater libraries is that
they are really pretty useful and hard to do without in more complex libraries
than those in the core (e.g. RTTI for doing things like strategy patterns, or
managing polymorphic class trees).


@comment fsm
@section Template instantiation

In C++, template instantiation is done by the compiler.  In real life, it
doesn't work as the standard says.  In brief here is how template instantiation
is supposed to work:

@itemize @bullet

@item The compiler must instantiate every needed template before its first use.

@item The definition of a template must be in scope at the point of instantiation
      unless the template is declared as exported.

@end itemize

To understand the implications of this (and the meaning of "exported") let's
consider the following program, composed of two "translation units"
(i.e. files):

@smallexample
// matrix.h
template <typename T>
struct matrix
@{
  matrix(int, int);
  ...
@};
@end smallexample

The class template @code{matrix<>} just declared is defined in

@smallexample
// matrix.txx
#include "matrix.h"
template <typename T>
matrix<T>::matrix(int m, int n) @{ ... @}
@end smallexample

Finally we refer to the matrix class in a little program:

@smallexample
// program.cxx
#include "matrix.h"
int main()
@{
  matrix<double> P(3, 4);
  ...
  return 0;
@}
@end smallexample

The program is ill-formed because the @code{matrix<double>} must be
instantiated before its use in @code{program.cxx}, but the definition
isn't in scope at that point.
One way to fix this is to explicitly instantiate the required template in
some source file and make sure to compile that source file first.
Another is to include the definition of the template in the header file.
A third solution is to put the keyword @code{export} in front of the declaration
of @code{matrix<T>}, which makes it possible to implicitly instantiate
@code{matrix<double>} even when the definition is not in scope.

Unfortunately, there are at the time of writing (April 2001) no compilers
which understand and implement @code{export} so we are currently limited to
using two kinds of templates:
@itemize @bullet
@item "Inline" templates whose definitions are in scope at the point of use.
      This includes (in most implementations) the containers and algorithms
      from the STL.  An example is @code{vcl_vector<vcl_pair<int, vcl_string> >}.
@item "Export" templates which are explicitly instantiated in the program (despite
      being exported).  In VXL, these instantiations all live in the @code{Templates/}
      directories in the source tree and include things like @code{vnl_svd<T>}
      which only need to be instantiated for a handful of types anyway.
@end itemize

Now, it gets worse.  For various reasons it is sometimes advantageous to turn
off automatic instantiation of the first kind of template.  This is only really
the case for some architectures but if you are unlucky enough to be using one
of them, you also have to explicitly instantiate your STL container classes
and algorithms in the @code{Templates/} directories. [You should consider skipping
the rest of this section until you actually have a template problem.  Don't read it
just for pleasure.]  To make it easier to do
this, and to make sure it works on all platforms, explicit instantiation is
done using preprocessor macros.  The macro used to instantiate a class or function
is obtained by capitalizing the name (of that class or function) and appending
@code{_INSTANTIATE}.  For example, here is how to instantiate a
@code{vcl_map<int, X>} where @code{X} is the name of some class:

@smallexample
// Templates/vcl_map+int.X-.cxx
#include "X.h"         // declaration of class X.
#include <vcl_map.txx> // the instantiation macro lives here.
VCL_MAP_INSTANTIATE(int, X, vcl_less<int>);
@end smallexample

and here is how to instantiate @code{vcl_vector<X *>}:

@smallexample
// Templates/vcl_vector+X~-.cxx
struct X; // forward declare the class.
#include <vcl_vector.txx>
VCL_VECTOR_INSTANTIATE(X *);
@end smallexample

The naming convention for such files is as follows:
@itemize @bullet
@item Take the full template instantiation, e.g. 
@code{VSL_VECTOR_IO_INSTANTIATE( vcl_vector< vcl_pair< unsigned int, vxl_int_64 > > )}
@item Strip the @code{_INSTANTIATE} and convert the Macro name to lowercase, e.g. 
@code{vsl_vector_io( vcl_vector< vcl_pair< unsigned int, vxl_int_64 > >)}
@item Convert the macro's brackets @code{()} to angle brackets @code{<>} e.g.
@code{vsl_vector_io< vcl_vector< vcl_pair< unsigned int, vxl_int_64 > > >}
@item Replace '@code{unsigned *}' with '@code{u*}', i.e. '@code{unsigned int}' 
with '@code{uint}', etc. e.g.
@code{vsl_vector_io< vcl_vector< vcl_pair< uint, vxl_int_64 > > >}
@item Strip '@code{vcl_}' prefixes from fixed width types. e.g.
@code{vsl_vector_io< vcl_vector< vcl_pair< uint, int_64 > > >}
@item Strip spaces and replace '@code{<}' with '@code{+}', '@code{>}' with
'@code{-}', and '@code{,}' with '@code{.}' e.g.
@code{vsl_vector_io+vcl_vector+vcl_pair+uint.uint---}
@item 
@end itemize

If you are using the build system that comes with VXL and you aren't using
implicit instantiation you should put such instantiations in the
@code{Templates/} directory or you @emph{will} be stuffed.

@comment IMS (with input from fsm)
@section Use of Assertions (Developer Topic)
@cindex assert
@cindex assertion
@cindex vcl_abort
@cindex error


First of all a definition: Assertions include anything that acts
like an assert().  They check for some error condition
that should not occur if the code is working
correctly@footnote{Strictly, computing science defines
assertions in association with a code section's pre- and
post-conditions.}.  They are there to
detect broken code.  The fact that they abort rather than do
something more graceful is irrelevant because the program is
already broken.  Typical things to check for include array bounds
violations, container size mismatches, invalid function
parameters.  The following things should not be considered as
assertions; invalid user input, file input failure; users are too
good at messing these things up, and should be treated
sympathetically.

When putting an assertion in one of the @vxl{x} libraries, you
should make sure that it can be turned off using @code{NDEBUG}.
This is the intention of the NDEBUG macro, and is very useful for
time-critical code.
The easiest way to do this is using the @code{assert()} macro.  If
you want to print out a more useful error message you could try
@smallexample
#include <vcl_iostream.h>
#include <vcl_cstdlib.h>
int f()
@{ ...
#ifndef NDEBUG
  if (vcl_sqrt(4.0) < 1.0)
  @{
    vcl_cerr << "There is something very wrong with your"
             << "vcl_sqrt() function" << vcl_endl;
    vcl_abort();
  @}
  ...
  return 0;
@}
@end smallexample
However you should bear in mind the extra compilation overhead compared
to just @code{#include <vcl_cassert.h>}.

If you want finer control you can add extra control macros.
Indeed in the case of time-critical code, you are encouraged to provide
this extra control.  You can have the default (i.e. when the control macro
is undefined) either include, or not include, the assertion.
In any case, you @emph{should} ensure that defining @code{NDEBUG} will
override your specialist macros, and turn off @emph{all} assertions.
For example,
@smallexample
#include <vcl_iostream.h>
#include <vcl_cstdlib.h>
int f()
@{ ...
#if (!defined NDEBUG) && (defined I_AM_PARANOID_ABOUT_VCL_SQRT)
  if (vcl_sqrt(4.0) < 1.0)
  @{
    vcl_cerr << "There is something very wrong with your"
             << "vcl_sqrt() function" << vcl_endl;
    vcl_abort();
  @}
  ...
  return 0;
@}
@end smallexample

Of course, you should also document the effect of your macro in
the function Doxygen markup (or class level if appropriate.)

@section Notes
@subsection Forward Declaration of vcl Classes

Do not forward declare classes in vcl.  For example,
@example
class vcl_string;   // This is not allowed. std::string is a typedef.
class my_class @{
..
@end example

In this case you should just include <vcl_string.h>.  In the case of stream
stuff, there is an include file of forward declarations that will work.
@example
#include <vcl_iosfwd.h>
@end example

General rule: never forward declare vcl_something with "class
vcl_something;" but either @samp{#include <vcl_something_fwd.h>} or
@samp{#include <vcl_something.h>}
