// Emacs -*- C++ -*-

#ifndef restrict_h_
#define restrict_h_

#include "BaseI.h"
#include "VectorI.h"
#include <complex.h>

template <class T>
IA_BaseImage<IA_Point<int>,T> *restrictD_toD
(
 const IA_BaseImage<IA_Point<int>,T> *im ,
 const IA_Set<IA_Point<int> > &ips
 );

// The actual definition of these functions is placed in the
// derivation module (i.e. UcharDI.c).  The function body looks like
// this:  return restrictD_toD(im, ps);

#if 1
template <class T, class P>
IA_BaseImage<IA_Point<int>, T> *
restrict_toD(const IA_BaseImage<P, T> *, const IA_Set<IA_Point<int> > &)
#else

// Defining them as inline here leaves a LOT of undefined symbols in
// the instantiation object and causes otherwise unneeded .o files to
// be linked in to satisfy the undefined symbols.

IA_BaseImage<IA_Point<int>,u_char> *restrict_toD(const IA_BaseImage<IA_Point<int>, u_char> *im, const IA_Set<IA_Point<int> > &ips);

IA_BaseImage<IA_Point<int>,int> *restrict_toD(const IA_BaseImage<IA_Point<int>, int> *im, const IA_Set<IA_Point<int> > &ips);

IA_BaseImage<IA_Point<int>,float> *restrict_toD(const IA_BaseImage<IA_Point<int>, float> *im, const IA_Set<IA_Point<int> > &ips);

// IA_BaseImage<IA_Point<int>,double> *restrict_toD(const IA_BaseImage<IA_Point<int>, double> *im, const IA_Set<IA_Point<int> > &ips);

IA_BaseImage<IA_Point<int>,complex> *restrict_toD(const IA_BaseImage<IA_Point<int>, complex> *im, const IA_Set<IA_Point<int> > &ips);

#endif

//
template <class T>
IA_BaseImage<IA_Point<int>,T> *restrictC_toD
  (
   const IA_BaseImage<IA_Point<double>,T> *im,
   const IA_Set<IA_Point<int> > &ips
   );

//  The body of these functions should look like this:
// return restrictC_toD(im, ips);

#if 1

   // see above

#else
// IA_BaseImage<IA_Point<int>,u_char> *restrict_toD(const IA_BaseImage<IA_Point<double>, u_char> *im, const IA_Set<IA_Point<int> > &ips);

// IA_BaseImage<IA_Point<int>,int> *restrict_toD(const IA_BaseImage<IA_Point<double>, int> *im, const IA_Set<IA_Point<int> > &ips);

IA_BaseImage<IA_Point<int>,float> *restrict_toD(const IA_BaseImage<IA_Point<double>, float> *im, const IA_Set<IA_Point<int> > &ips);

// IA_BaseImage<IA_Point<int>,double> *restrict_toD(const IA_BaseImage<IA_Point<double>, double> *im, const IA_Set<IA_Point<int> > &ips);

// IA_BaseImage<IA_Point<int>,complex> *restrict_toD(const IA_BaseImage<IA_Point<double>, complex> *im, const IA_Set<IA_Point<int> > &ips);
#endif

#endif
