#ifndef vec_scalar_ATYPE_LTYPE_RTYPE_OPNAME
#define vec_scalar_ATYPE_LTYPE_RTYPE_OPNAME
ATYPE vec_scalar_bo_OPNAME(const IA_VectorDI<LTYPE> *lhs,RTYPE rhs)
{
    const IA_IntPointSet domain = lhs->domain();
    const unsigned sz = domain.card();
    ATYPE *const vec = new ATYPE[sz];

    {
	ATYPE *ds = vec;
	const LTYPE *ls = lhs->vec;
	for (unsigned i=0; i<sz; i++) {
	    if (!( (*(ls++)) SUBOP (rhs) ))
		return 0;
	}
    }
    return 1;
}
#endif // vec_scalar_ATYPE_LTYPE_RTYPE_OPNAME

// scalar-scalar operation is trivial

#ifndef scalar_iter_ATYPE_LTYPE_RTYPE_OPNAME
#define scalar_iter_ATYPE_LTYPE_RTYPE_OPNAME
ATYPE scalar_iter_bo_OPNAME(RTYPE lhs,IA_DiscreteImage<LTYPE> rhs)
{
    const IA_IntPointSet domain = rhs.domain();
    const unsigned sz = domain.card();
    ATYPE *const vec = new ATYPE[sz];

    {
	ATYPE *ds = vec;
	RTYPE rtmp;
	IA_DIVIter<RTYPE>	riter(rhs);
	for (unsigned i=0; i<sz; i++) {
	    riter(rtmp);
	    if (!( (lhs) SUBOP (rtmp) ))
		return 0;
	}
    }
    return 1;
}
#endif // scalar_iter_ATYPE_LTYPE_RTYPE_OPNAME

ATYPE OP ( const IA_DiscreteImage<LTYPE> &lhs, RTYPE rhs)
{
    if (lhs.type() == IA_VectorDI<LTYPE>::s_type()) {
	return vec_scalar_bo_OPNAME((IA_VectorDI<LTYPE> *)lhs.bdip,rhs);
    } else if (lhs.type() == IA_ConstDI<LTYPE>::s_type()) {
	return (((IA_ConstDI<LTYPE> *)lhs.bdip)->value) SUBOP (rhs);
    } else {
	return scalar_iter_bo_OPNAME(rhs,lhs);
    }
}
